summaryrefslogtreecommitdiffstats
path: root/test/Transforms/InstCombine
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstCombine')
-rw-r--r--test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll2
-rw-r--r--test/Transforms/InstCombine/2007-09-11-Trampoline.ll24
-rw-r--r--test/Transforms/InstCombine/2007-10-28-stacksave.ll2
-rw-r--r--test/Transforms/InstCombine/2008-01-14-DoubleNest.ll24
-rw-r--r--test/Transforms/InstCombine/2008-04-28-VolatileStore.ll2
-rw-r--r--test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll6
-rw-r--r--test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll4
-rw-r--r--test/Transforms/InstCombine/2008-06-24-StackRestore.ll4
-rw-r--r--test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll6
-rw-r--r--test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll12
-rw-r--r--test/Transforms/InstCombine/2012-02-13-FCmp.ll35
-rw-r--r--test/Transforms/InstCombine/2012-02-28-ICmp.ll19
-rw-r--r--test/Transforms/InstCombine/2012-03-10-InstCombine.ll35
-rw-r--r--test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll12
-rw-r--r--test/Transforms/InstCombine/LandingPadClauses.ll52
-rw-r--r--test/Transforms/InstCombine/align-external.ll13
-rw-r--r--test/Transforms/InstCombine/alloca.ll44
-rw-r--r--test/Transforms/InstCombine/apint-shl-trunc.ll15
-rw-r--r--test/Transforms/InstCombine/bitcount.ll8
-rw-r--r--test/Transforms/InstCombine/constant-fold-gep.ll6
-rw-r--r--test/Transforms/InstCombine/crash.ll15
-rw-r--r--test/Transforms/InstCombine/dg.exp3
-rw-r--r--test/Transforms/InstCombine/extractvalue.ll6
-rw-r--r--test/Transforms/InstCombine/fold-sqrt-sqrtf.ll17
-rw-r--r--test/Transforms/InstCombine/icmp.ll84
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll46
-rw-r--r--test/Transforms/InstCombine/lit.local.cfg1
-rw-r--r--test/Transforms/InstCombine/mul.ll80
-rw-r--r--test/Transforms/InstCombine/overflow.ll22
-rw-r--r--test/Transforms/InstCombine/pr12251.ll15
-rw-r--r--test/Transforms/InstCombine/select.ll20
-rw-r--r--test/Transforms/InstCombine/sext.ll8
-rw-r--r--test/Transforms/InstCombine/shift.ll72
-rw-r--r--test/Transforms/InstCombine/sign-test-and-or.ll100
-rw-r--r--test/Transforms/InstCombine/sub-xor.ll37
-rw-r--r--test/Transforms/InstCombine/sub.ll26
-rw-r--r--test/Transforms/InstCombine/vec_shuffle.ll46
-rw-r--r--test/Transforms/InstCombine/vector_gep1.ll37
-rw-r--r--test/Transforms/InstCombine/volatile_store.ll4
39 files changed, 840 insertions, 124 deletions
diff --git a/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll b/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll
index 3297919..7f73908 100644
--- a/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll
+++ b/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll
@@ -2,6 +2,6 @@
define void @test(i32* %P) {
; Dead but not deletable!
- %X = volatile load i32* %P ; <i32> [#uses=0]
+ %X = load volatile i32* %P ; <i32> [#uses=0]
ret void
}
diff --git a/test/Transforms/InstCombine/2007-09-11-Trampoline.ll b/test/Transforms/InstCombine/2007-09-11-Trampoline.ll
deleted file mode 100644
index 6190aa9..0000000
--- a/test/Transforms/InstCombine/2007-09-11-Trampoline.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; RUN: opt < %s -instcombine -S | grep {call i32 @f}
-
- %struct.FRAME.nest = type { i32, i32 (i32)* }
- %struct.__builtin_trampoline = type { [10 x i8] }
-
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
-
-declare i32 @f(%struct.FRAME.nest* nest , i32 )
-
-define i32 @nest(i32 %n) {
-entry:
- %FRAME.0 = alloca %struct.FRAME.nest, align 8 ; <%struct.FRAME.nest*> [#uses=3]
- %TRAMP.216 = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1]
- %TRAMP.216.sub = getelementptr [10 x i8]* %TRAMP.216, i32 0, i32 0 ; <i8*> [#uses=1]
- %tmp3 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %n, i32* %tmp3, align 8
- %FRAME.06 = bitcast %struct.FRAME.nest* %FRAME.0 to i8* ; <i8*> [#uses=1]
- %tramp = call i8* @llvm.init.trampoline( i8* %TRAMP.216.sub, i8* bitcast (i32 (%struct.FRAME.nest* , i32)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
- %tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (i32)**> [#uses=1]
- %tmp89 = bitcast i8* %tramp to i32 (i32)* ; <i32 (i32)*> [#uses=2]
- store i32 (i32)* %tmp89, i32 (i32)** %tmp7, align 8
- %tmp2.i = call i32 %tmp89( i32 1 ) ; <i32> [#uses=1]
- ret i32 %tmp2.i
-}
diff --git a/test/Transforms/InstCombine/2007-10-28-stacksave.ll b/test/Transforms/InstCombine/2007-10-28-stacksave.ll
index 76bceb6..4c5c367 100644
--- a/test/Transforms/InstCombine/2007-10-28-stacksave.ll
+++ b/test/Transforms/InstCombine/2007-10-28-stacksave.ll
@@ -26,7 +26,7 @@ lab: ; preds = %cleanup31, %entry
%tmp21 = getelementptr i32* %tmp1819, i32 0 ; <i32*> [#uses=1]
store i32 1, i32* %tmp21, align 4
%tmp2223 = bitcast i32* %tmp1819 to i8* ; <i8*> [#uses=1]
- volatile store i8* %tmp2223, i8** @p, align 4
+ store volatile i8* %tmp2223, i8** @p, align 4
%tmp25 = add i32 %n.0, 1 ; <i32> [#uses=2]
%tmp27 = icmp sle i32 %tmp25, 999999 ; <i1> [#uses=1]
%tmp2728 = zext i1 %tmp27 to i8 ; <i8> [#uses=1]
diff --git a/test/Transforms/InstCombine/2008-01-14-DoubleNest.ll b/test/Transforms/InstCombine/2008-01-14-DoubleNest.ll
deleted file mode 100644
index 6401dfd..0000000
--- a/test/Transforms/InstCombine/2008-01-14-DoubleNest.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; RUN: opt < %s -instcombine -disable-output
-
- %struct.FRAME.nest = type { i32, i32 (i32*)* }
- %struct.__builtin_trampoline = type { [10 x i8] }
-
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind
-
-declare i32 @f(%struct.FRAME.nest* nest , i32*)
-
-define i32 @nest(i32 %n) {
-entry:
- %FRAME.0 = alloca %struct.FRAME.nest, align 8 ; <%struct.FRAME.nest*> [#uses=3]
- %TRAMP.216 = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1]
- %TRAMP.216.sub = getelementptr [10 x i8]* %TRAMP.216, i32 0, i32 0 ; <i8*> [#uses=1]
- %tmp3 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 %n, i32* %tmp3, align 8
- %FRAME.06 = bitcast %struct.FRAME.nest* %FRAME.0 to i8* ; <i8*> [#uses=1]
- %tramp = call i8* @llvm.init.trampoline( i8* %TRAMP.216.sub, i8* bitcast (i32 (%struct.FRAME.nest*, i32*)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
- %tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (i32*)**> [#uses=1]
- %tmp89 = bitcast i8* %tramp to i32 (i32*)* ; <i32 (i32*)*> [#uses=2]
- store i32 (i32*)* %tmp89, i32 (i32*)** %tmp7, align 8
- %tmp2.i = call i32 %tmp89( i32* nest null ) ; <i32> [#uses=1]
- ret i32 %tmp2.i
-}
diff --git a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
index 6847f5e..de08c32 100644
--- a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
+++ b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
@@ -2,7 +2,7 @@
define void @test() {
%votf = alloca <4 x float> ; <<4 x float>*> [#uses=1]
- volatile store <4 x float> zeroinitializer, <4 x float>* %votf, align 16
+ store volatile <4 x float> zeroinitializer, <4 x float>* %votf, align 16
ret void
}
diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
index a24f307..1286e3d 100644
--- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
+++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
@@ -6,17 +6,17 @@ target triple = "i386-apple-darwin8"
define i32 @main() nounwind {
entry:
%tmp93 = icmp slt i32 0, 10 ; <i1> [#uses=0]
- %tmp34 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp34 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br label %bb
bb: ; preds = %bb, %entry
%b.0.reg2mem.0 = phi i32 [ 0, %entry ], [ %tmp6, %bb ] ; <i32> [#uses=1]
%tmp3.reg2mem.0 = phi i32 [ %tmp34, %entry ], [ %tmp3, %bb ] ; <i32> [#uses=1]
%tmp4 = add i32 %tmp3.reg2mem.0, 5 ; <i32> [#uses=1]
- volatile store i32 %tmp4, i32* @g_1, align 4
+ store volatile i32 %tmp4, i32* @g_1, align 4
%tmp6 = add i32 %b.0.reg2mem.0, 1 ; <i32> [#uses=2]
%tmp9 = icmp slt i32 %tmp6, 10 ; <i1> [#uses=1]
- %tmp3 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp3 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br i1 %tmp9, label %bb, label %bb11
bb11: ; preds = %bb
diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
index 5fb11ff..ebbd3a7 100644
--- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
+++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
@@ -7,11 +7,11 @@ target triple = "i386-apple-darwin8"
define i32 @main(i32 %i) nounwind {
entry:
%tmp93 = icmp slt i32 %i, 10 ; <i1> [#uses=0]
- %tmp34 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp34 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br i1 %tmp93, label %bb11, label %bb
bb: ; preds = %bb, %entry
- %tmp3 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp3 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br label %bb11
bb11: ; preds = %bb
diff --git a/test/Transforms/InstCombine/2008-06-24-StackRestore.ll b/test/Transforms/InstCombine/2008-06-24-StackRestore.ll
index 8307834..4f4709b 100644
--- a/test/Transforms/InstCombine/2008-06-24-StackRestore.ll
+++ b/test/Transforms/InstCombine/2008-06-24-StackRestore.ll
@@ -10,7 +10,7 @@ entry:
%tmp2752 = alloca i32 ; <i32*> [#uses=2]
%tmpcast53 = bitcast i32* %tmp2752 to i8* ; <i8*> [#uses=1]
store i32 2, i32* %tmp2752, align 4
- volatile store i8* %tmpcast53, i8** @p, align 4
+ store volatile i8* %tmpcast53, i8** @p, align 4
br label %bb44
bb: ; preds = %bb44
@@ -29,7 +29,7 @@ bb44: ; preds = %bb44, %entry
store i32 1, i32* %tmp27, align 4
%tmp34 = getelementptr i32* %tmp27, i32 %tmp4 ; <i32*> [#uses=1]
store i32 2, i32* %tmp34, align 4
- volatile store i8* %tmpcast, i8** @p, align 4
+ store volatile i8* %tmpcast, i8** @p, align 4
%exitcond = icmp eq i32 %tmp3857, 999999 ; <i1> [#uses=1]
br i1 %exitcond, label %bb, label %bb44
}
diff --git a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
index 8104408..1ed5323 100644
--- a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
+++ b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
@@ -7,17 +7,17 @@ target triple = "i386-apple-darwin8"
define i32 @main() nounwind {
entry:
%tmp93 = icmp slt i32 0, 10 ; <i1> [#uses=0]
- %tmp34 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp34 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br label %bb
bb: ; preds = %bb, %entry
%b.0.reg2mem.0 = phi i32 [ 0, %entry ], [ %tmp6, %bb ] ; <i32> [#uses=1]
%tmp3.reg2mem.0 = phi i32 [ %tmp3, %bb ], [ %tmp34, %entry ]
%tmp4 = add i32 %tmp3.reg2mem.0, 5 ; <i32> [#uses=1]
- volatile store i32 %tmp4, i32* @g_1, align 4
+ store volatile i32 %tmp4, i32* @g_1, align 4
%tmp6 = add i32 %b.0.reg2mem.0, 1 ; <i32> [#uses=2]
%tmp9 = icmp slt i32 %tmp6, 10 ; <i1> [#uses=1]
- %tmp3 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp3 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br i1 %tmp9, label %bb, label %bb11
bb11: ; preds = %bb
diff --git a/test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll b/test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll
new file mode 100644
index 0000000..abab9dc
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine -disable-output
+
+%opaque_struct = type opaque
+
+@G = external global [0 x %opaque_struct]
+
+declare void @foo(%opaque_struct*)
+
+define void @bar() {
+ call void @foo(%opaque_struct* bitcast ([0 x %opaque_struct]* @G to %opaque_struct*))
+ ret void
+}
diff --git a/test/Transforms/InstCombine/2012-02-13-FCmp.ll b/test/Transforms/InstCombine/2012-02-13-FCmp.ll
new file mode 100644
index 0000000..39b0594
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-02-13-FCmp.ll
@@ -0,0 +1,35 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+; Radar 10803727
+@.str = private unnamed_addr constant [35 x i8] c"\0Ain_range input (should be 0): %f\0A\00", align 1
+@.str1 = external hidden unnamed_addr constant [35 x i8], align 1
+
+declare i32 @printf(i8*, ...)
+define i64 @_Z8tempCastj(i32 %val) uwtable ssp {
+entry:
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([35 x i8]* @.str1, i64 0, i64 0), i32 %val)
+ %conv = uitofp i32 %val to double
+ %call.i = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([35 x i8]* @.str, i64 0, i64 0), double %conv)
+ %cmp.i = fcmp oge double %conv, -1.000000e+00
+ br i1 %cmp.i, label %land.rhs.i, label %if.end.critedge
+; CHECK: br i1 true, label %land.rhs.i, label %if.end.critedge
+
+land.rhs.i: ; preds = %entry
+ %cmp1.i = fcmp olt double %conv, 1.000000e+00
+ br i1 %cmp1.i, label %if.then, label %if.end
+
+if.then: ; preds = %land.rhs.i
+ %add = fadd double %conv, 5.000000e-01
+ %conv3 = fptosi double %add to i64
+ br label %return
+
+if.end.critedge: ; preds = %entry
+ br label %if.end
+
+if.end: ; preds = %if.end.critedge, %land.rhs.i
+ br label %return
+
+return: ; preds = %if.end, %if.then
+ %retval.0 = phi i64 [ %conv3, %if.then ], [ -1, %if.end ]
+ ret i64 %retval.0
+}
+
diff --git a/test/Transforms/InstCombine/2012-02-28-ICmp.ll b/test/Transforms/InstCombine/2012-02-28-ICmp.ll
new file mode 100644
index 0000000..82cf85f
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-02-28-ICmp.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; <rdar://problem/10803154>
+
+; There should be no transformation.
+; CHECK: %a = trunc i32 %x to i8
+; CHECK: %b = icmp ne i8 %a, 0
+; CHECK: %c = and i32 %x, 16711680
+; CHECK: %d = icmp ne i32 %c, 0
+; CHECK: %e = and i1 %b, %d
+; CHECK: ret i1 %e
+
+define i1 @f1(i32 %x) {
+ %a = trunc i32 %x to i8
+ %b = icmp ne i8 %a, 0
+ %c = and i32 %x, 16711680
+ %d = icmp ne i32 %c, 0
+ %e = and i1 %b, %d
+ ret i1 %e
+}
diff --git a/test/Transforms/InstCombine/2012-03-10-InstCombine.ll b/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
new file mode 100644
index 0000000..58ccf12
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -S -instcombine | FileCheck %s
+
+; Derived from gcc.c-torture/execute/frame-address.c
+
+; CHECK: @func
+; CHECK: return:
+; CHECK-NOT: ret i32 0
+; CHECK: ret i32 %retval
+
+define i32 @func(i8* %c, i8* %f) nounwind uwtable readnone noinline ssp {
+entry:
+ %d = alloca i8, align 1
+ store i8 0, i8* %d, align 1
+ %cmp = icmp ugt i8* %d, %c
+ br i1 %cmp, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ %cmp2 = icmp ule i8* %d, %f
+ %not.cmp1 = icmp uge i8* %c, %f
+ %.cmp2 = and i1 %cmp2, %not.cmp1
+ %land.ext = zext i1 %.cmp2 to i32
+ br label %return
+
+if.else: ; preds = %entry
+ %cmp5 = icmp uge i8* %d, %f
+ %not.cmp3 = icmp ule i8* %c, %f
+ %.cmp5 = and i1 %cmp5, %not.cmp3
+ %land.ext7 = zext i1 %.cmp5 to i32
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ %land.ext, %if.then ], [ %land.ext7, %if.else ]
+ ret i32 %retval.0
+}
+
diff --git a/test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll b/test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll
new file mode 100644
index 0000000..c1602da
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; PR12234
+
+@g = extern_weak global i32
+define i32 @function(i32 %x) nounwind {
+entry:
+ %xor = xor i32 %x, 1
+ store volatile i32 %xor, i32* inttoptr (i64 1 to i32*), align 4
+ %or4 = or i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 1), %xor
+ ret i32 %or4
+}
+; CHECK: define i32 @function
diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll
index 055bdcc..de3b2d3 100644
--- a/test/Transforms/InstCombine/LandingPadClauses.ll
+++ b/test/Transforms/InstCombine/LandingPadClauses.ll
@@ -6,6 +6,7 @@
declare i32 @generic_personality(i32, i64, i8*, i8*)
declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+declare i32 @__objc_personality_v0(i32, i64, i8*, i8*)
declare void @bar()
@@ -179,3 +180,54 @@ lpad.d:
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
}
+
+define void @foo_objc() {
+; CHECK: @foo_objc
+ invoke void @bar()
+ to label %cont.a unwind label %lpad.a
+cont.a:
+ invoke void @bar()
+ to label %cont.b unwind label %lpad.b
+cont.b:
+ invoke void @bar()
+ to label %cont.c unwind label %lpad.c
+cont.c:
+ invoke void @bar()
+ to label %cont.d unwind label %lpad.d
+cont.d:
+ ret void
+
+lpad.a:
+ %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__objc_personality_v0
+ catch i32* null
+ catch i32* @T1
+ unreachable
+; CHECK: %a = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+
+lpad.b:
+ %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__objc_personality_v0
+ filter [1 x i32*] zeroinitializer
+ unreachable
+; CHECK: %b = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+
+lpad.c:
+ %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__objc_personality_v0
+ filter [2 x i32*] [i32* @T1, i32* null]
+ unreachable
+; CHECK: %c = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+
+lpad.d:
+ %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__objc_personality_v0
+ cleanup
+ catch i32* null
+ unreachable
+; CHECK: %d = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+}
diff --git a/test/Transforms/InstCombine/align-external.ll b/test/Transforms/InstCombine/align-external.ll
index 6e8ad87..d4a5d42 100644
--- a/test/Transforms/InstCombine/align-external.ll
+++ b/test/Transforms/InstCombine/align-external.ll
@@ -1,7 +1,7 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-; Don't assume that external global variables have their preferred
-; alignment. They may only have the ABI minimum alignment.
+; Don't assume that external global variables or those with weak linkage have
+; their preferred alignment. They may only have the ABI minimum alignment.
; CHECK: %s = shl i64 %a, 3
; CHECK: %r = or i64 %s, ptrtoint (i32* @A to i64)
@@ -11,7 +11,7 @@
target datalayout = "-i32:8:32"
@A = external global i32
-@B = external global i32
+@B = weak_odr global i32 0
define i64 @foo(i64 %a) {
%t = ptrtoint i32* @A to i64
@@ -20,3 +20,10 @@ define i64 @foo(i64 %a) {
%q = add i64 %r, 1
ret i64 %q
}
+
+define i32 @bar() {
+; CHECK: @bar
+ %r = load i32* @B, align 1
+; CHECK: align 1
+ ret i32 %r
+}
diff --git a/test/Transforms/InstCombine/alloca.ll b/test/Transforms/InstCombine/alloca.ll
index e4d1367..ef7185c 100644
--- a/test/Transforms/InstCombine/alloca.ll
+++ b/test/Transforms/InstCombine/alloca.ll
@@ -44,3 +44,47 @@ define i32* @test4(i32 %n) {
%A = alloca i32, i32 %n
ret i32* %A
}
+
+; Allocas which are only used by GEPs, bitcasts, and stores (transitively)
+; should be deleted.
+define void @test5() {
+; CHECK: @test5
+; CHECK-NOT: alloca
+; CHECK-NOT: store
+; CHECK: ret
+
+entry:
+ %a = alloca { i32 }
+ %b = alloca i32*
+ %a.1 = getelementptr { i32 }* %a, i32 0, i32 0
+ store i32 123, i32* %a.1
+ store i32* %a.1, i32** %b
+ %b.1 = bitcast i32** %b to i32*
+ store i32 123, i32* %b.1
+ %a.2 = getelementptr { i32 }* %a, i32 0, i32 0
+ store atomic i32 2, i32* %a.2 unordered, align 4
+ %a.3 = getelementptr { i32 }* %a, i32 0, i32 0
+ store atomic i32 3, i32* %a.3 release, align 4
+ %a.4 = getelementptr { i32 }* %a, i32 0, i32 0
+ store atomic i32 4, i32* %a.4 seq_cst, align 4
+ ret void
+}
+
+declare void @f(i32* %p)
+
+; Check that we don't delete allocas in some erroneous cases.
+define void @test6() {
+; CHECK: @test6
+; CHECK-NOT: ret
+; CHECK: alloca
+; CHECK-NEXT: alloca
+; CHECK: ret
+
+entry:
+ %a = alloca { i32 }
+ %b = alloca i32
+ %a.1 = getelementptr { i32 }* %a, i32 0, i32 0
+ store volatile i32 123, i32* %a.1
+ tail call void @f(i32* %b)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/apint-shl-trunc.ll b/test/Transforms/InstCombine/apint-shl-trunc.ll
index 8163e6d..f2dc7d5 100644
--- a/test/Transforms/InstCombine/apint-shl-trunc.ll
+++ b/test/Transforms/InstCombine/apint-shl-trunc.ll
@@ -1,13 +1,24 @@
-; RUN: opt < %s -instcombine -S | grep shl
-; END.
+; RUN: opt < %s -instcombine -S | FileCheck %s
define i1 @test0(i39 %X, i39 %A) {
+; CHECK: @test0
+; CHECK: %[[V1:.*]] = shl i39 1, %A
+; CHECK: %[[V2:.*]] = and i39 %[[V1]], %X
+; CHECK: %[[V3:.*]] = icmp ne i39 %[[V2]], 0
+; CHECK: ret i1 %[[V3]]
+
%B = lshr i39 %X, %A
%D = trunc i39 %B to i1
ret i1 %D
}
define i1 @test1(i799 %X, i799 %A) {
+; CHECK: @test1
+; CHECK: %[[V1:.*]] = shl i799 1, %A
+; CHECK: %[[V2:.*]] = and i799 %[[V1]], %X
+; CHECK: %[[V3:.*]] = icmp ne i799 %[[V2]], 0
+; CHECK: ret i1 %[[V3]]
+
%B = lshr i799 %X, %A
%D = trunc i799 %B to i1
ret i1 %D
diff --git a/test/Transforms/InstCombine/bitcount.ll b/test/Transforms/InstCombine/bitcount.ll
index f75ca2d..a6fd837 100644
--- a/test/Transforms/InstCombine/bitcount.ll
+++ b/test/Transforms/InstCombine/bitcount.ll
@@ -4,13 +4,13 @@
; RUN: grep -v declare | not grep llvm.ct
declare i31 @llvm.ctpop.i31(i31 %val)
-declare i32 @llvm.cttz.i32(i32 %val)
-declare i33 @llvm.ctlz.i33(i33 %val)
+declare i32 @llvm.cttz.i32(i32 %val, i1)
+declare i33 @llvm.ctlz.i33(i33 %val, i1)
define i32 @test(i32 %A) {
%c1 = call i31 @llvm.ctpop.i31(i31 12415124)
- %c2 = call i32 @llvm.cttz.i32(i32 87359874)
- %c3 = call i33 @llvm.ctlz.i33(i33 87359874)
+ %c2 = call i32 @llvm.cttz.i32(i32 87359874, i1 true)
+ %c3 = call i33 @llvm.ctlz.i33(i33 87359874, i1 true)
%t1 = zext i31 %c1 to i32
%t3 = trunc i33 %c3 to i32
%r1 = add i32 %t1, %c2
diff --git a/test/Transforms/InstCombine/constant-fold-gep.ll b/test/Transforms/InstCombine/constant-fold-gep.ll
index c679226..e5b16ea 100644
--- a/test/Transforms/InstCombine/constant-fold-gep.ll
+++ b/test/Transforms/InstCombine/constant-fold-gep.ll
@@ -9,7 +9,7 @@ target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
@Y = internal global [3 x %struct.X] zeroinitializer
define void @frob() {
-; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0), align 8
+; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0), align 16
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0), align 4
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 1), align 4
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 1), align 4
@@ -33,7 +33,7 @@ define void @frob() {
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 10), align 4
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 1, i32 1, i64 2), align 4
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 11), align 4
-; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 0), align 8
+; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 0), align 16
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 12), align 4
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 1), align 4
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 13), align 4
@@ -47,7 +47,7 @@ define void @frob() {
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 17), align 8
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 1, i64 0, i32 0, i64 0), align 8
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 18), align 8
-; CHECK: store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 2, i64 0, i32 0, i64 0), align 8
+; CHECK: store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 2, i64 0, i32 0, i64 0), align 16
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 36), align 8
; CHECK: store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 1, i64 0, i32 0, i64 1), align 8
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 19), align 8
diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll
index 54a77aa..d5af532 100644
--- a/test/Transforms/InstCombine/crash.ll
+++ b/test/Transforms/InstCombine/crash.ll
@@ -165,20 +165,19 @@ entry:
br i1 %tobool, label %cond.end, label %cond.false
terminate.handler: ; preds = %ehcleanup
- %exc = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %0 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
+ %exc = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
call void @_ZSt9terminatev() noreturn nounwind
unreachable
ehcleanup: ; preds = %cond.false
- %exc1 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %1 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc1, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
+ %exc1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
invoke void @_ZN6UStackD1Ev(%class.UStack* %breaks)
to label %cont unwind label %terminate.handler
cont: ; preds = %ehcleanup
- call void @_Unwind_Resume_or_Rethrow(i8* %exc1)
- unreachable
+ resume { i8*, i32 } %exc1
cond.false: ; preds = %entry
%tmp4 = getelementptr inbounds %class.RuleBasedBreakIterator* %this, i32 0, i32 0 ; <i64 ()**> [#uses=1]
@@ -199,10 +198,6 @@ declare void @_ZN6UStackD1Ev(%class.UStack*)
declare i32 @__gxx_personality_v0(...)
-declare i8* @llvm.eh.exception() nounwind readonly
-
-declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
-
declare void @_ZSt9terminatev()
declare void @_Unwind_Resume_or_Rethrow(i8*)
diff --git a/test/Transforms/InstCombine/dg.exp b/test/Transforms/InstCombine/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/InstCombine/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/test/Transforms/InstCombine/extractvalue.ll b/test/Transforms/InstCombine/extractvalue.ll
index cf36b8f..5e4c677 100644
--- a/test/Transforms/InstCombine/extractvalue.ll
+++ b/test/Transforms/InstCombine/extractvalue.ll
@@ -88,7 +88,7 @@ define i32 @doubleextract2gep({i32, {i32, i32}}* %arg) {
; CHECK-NEXT: ret
define i32 @nogep-multiuse({i32, i32}* %pair) {
; The load should be left unchanged since both parts are needed.
- %L = volatile load {i32, i32}* %pair
+ %L = load volatile {i32, i32}* %pair
%LHS = extractvalue {i32, i32} %L, 0
%RHS = extractvalue {i32, i32} %L, 1
%R = add i32 %LHS, %RHS
@@ -100,8 +100,8 @@ define i32 @nogep-multiuse({i32, i32}* %pair) {
; CHECK-NEXT: extractvalue
; CHECK-NEXT: ret
define i32 @nogep-volatile({i32, i32}* %pair) {
- ; The volatile load should be left unchanged.
- %L = volatile load {i32, i32}* %pair
+ ; The load volatile should be left unchanged.
+ %L = load volatile {i32, i32}* %pair
%E = extractvalue {i32, i32} %L, 1
ret i32 %E
}
diff --git a/test/Transforms/InstCombine/fold-sqrt-sqrtf.ll b/test/Transforms/InstCombine/fold-sqrt-sqrtf.ll
new file mode 100644
index 0000000..bd92b4a
--- /dev/null
+++ b/test/Transforms/InstCombine/fold-sqrt-sqrtf.ll
@@ -0,0 +1,17 @@
+; RUN: opt -instcombine -S -disable-simplify-libcalls < %s | FileCheck %s
+; rdar://10466410
+
+; Instcombine tries to fold (fptrunc (sqrt (fpext x))) -> (sqrtf x), but this
+; shouldn't fold when sqrtf isn't available.
+define float @foo(float %f) uwtable ssp {
+entry:
+; CHECK: %conv = fpext float %f to double
+; CHECK: %call = tail call double @sqrt(double %conv)
+; CHECK: %conv1 = fptrunc double %call to float
+ %conv = fpext float %f to double
+ %call = tail call double @sqrt(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
+}
+
+declare double @sqrt(double)
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 77ca62c..a9ae221 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -121,8 +121,8 @@ define i1 @test12(i1 %A) {
%B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
ret i1 %B
; CHECK: @test12
-; CHECK-NEXT: %B = select i1
-; CHECK-NEXT: ret i1 %B
+; CHECK-NEXT: = xor i1 %A, true
+; CHECK-NEXT: ret i1
}
; PR6481
@@ -524,7 +524,7 @@ define i1 @test53(i32 %a, i32 %b) nounwind {
; CHECK: @test54
; CHECK-NEXT: %and = and i8 %a, -64
-; CHECK-NEXT icmp eq i8 %and, -128
+; CHECK-NEXT: icmp eq i8 %and, -128
define i1 @test54(i8 %a) nounwind {
%ext = zext i8 %a to i32
%and = and i32 %ext, 192
@@ -559,3 +559,81 @@ define i1 @test57(i32 %a) {
call void @foo(i32 %and)
ret i1 %cmp
}
+
+; rdar://problem/10482509
+; CHECK: @cmpabs1
+; CHECK-NEXT: icmp ne
+define zeroext i1 @cmpabs1(i64 %val) {
+ %sub = sub nsw i64 0, %val
+ %cmp = icmp slt i64 %val, 0
+ %sub.val = select i1 %cmp, i64 %sub, i64 %val
+ %tobool = icmp ne i64 %sub.val, 0
+ ret i1 %tobool
+}
+
+; CHECK: @cmpabs2
+; CHECK-NEXT: icmp ne
+define zeroext i1 @cmpabs2(i64 %val) {
+ %sub = sub nsw i64 0, %val
+ %cmp = icmp slt i64 %val, 0
+ %sub.val = select i1 %cmp, i64 %val, i64 %sub
+ %tobool = icmp ne i64 %sub.val, 0
+ ret i1 %tobool
+}
+
+; CHECK: @test58
+; CHECK-NEXT: call i32 @test58_d(i64 36029346783166592)
+define void @test58() nounwind {
+ %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
+ %call = call i32 @test58_d( i64 %cast) nounwind
+ ret void
+}
+declare i32 @test58_d(i64)
+
+define i1 @test59(i8* %foo) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr inbounds i32* %bit, i64 2
+ %gep2 = getelementptr inbounds i8* %foo, i64 10
+ %cast1 = bitcast i32* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ %use = ptrtoint i8* %cast1 to i64
+ %call = call i32 @test58_d(i64 %use) nounwind
+ ret i1 %cmp
+; CHECK: @test59
+; CHECK: ret i1 true
+}
+
+define i1 @test60(i8* %foo, i64 %i, i64 %j) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr inbounds i32* %bit, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = bitcast i32* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ ret i1 %cmp
+; CHECK: @test60
+; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
+; CHECK-NEXT: icmp slt i64 %gep1.idx, %j
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test61(i8* %foo, i64 %i, i64 %j) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr i32* %bit, i64 %i
+ %gep2 = getelementptr i8* %foo, i64 %j
+ %cast1 = bitcast i32* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ ret i1 %cmp
+; Don't transform non-inbounds GEPs.
+; CHECK: @test61
+; CHECK: icmp ult i8* %cast1, %gep2
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test62(i8* %a) {
+ %arrayidx1 = getelementptr inbounds i8* %a, i64 1
+ %arrayidx2 = getelementptr inbounds i8* %a, i64 10
+ %cmp = icmp slt i8* %arrayidx1, %arrayidx2
+ ret i1 %cmp
+; CHECK: @test62
+; CHECK-NEXT: ret i1 true
+}
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index f033e51..382e6b3 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -5,10 +5,10 @@
declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
declare double @llvm.powi.f64(double, i32) nounwind readonly
-declare i32 @llvm.cttz.i32(i32) nounwind readnone
-declare i32 @llvm.ctlz.i32(i32) nounwind readnone
+declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
+declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
declare i32 @llvm.ctpop.i32(i32) nounwind readnone
-declare i8 @llvm.ctlz.i8(i8) nounwind readnone
+declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone
define i8 @uaddtest1(i8 %A, i8 %B) {
%x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B)
@@ -142,13 +142,13 @@ define i32 @umultest4(i32 %n) nounwind {
define void @powi(double %V, double *%P) {
entry:
%A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind
- volatile store double %A, double* %P
+ store volatile double %A, double* %P
%B = tail call double @llvm.powi.f64(double %V, i32 0) nounwind
- volatile store double %B, double* %P
+ store volatile double %B, double* %P
%C = tail call double @llvm.powi.f64(double %V, i32 1) nounwind
- volatile store double %C, double* %P
+ store volatile double %C, double* %P
ret void
; CHECK: @powi
; CHECK: %A = fdiv double 1.0{{.*}}, %V
@@ -161,7 +161,7 @@ define i32 @cttz(i32 %a) {
entry:
%or = or i32 %a, 8
%and = and i32 %or, -8
- %count = tail call i32 @llvm.cttz.i32(i32 %and) nounwind readnone
+ %count = tail call i32 @llvm.cttz.i32(i32 %and, i1 true) nounwind readnone
ret i32 %count
; CHECK: @cttz
; CHECK-NEXT: entry:
@@ -172,7 +172,7 @@ define i8 @ctlz(i8 %a) {
entry:
%or = or i8 %a, 32
%and = and i8 %or, 63
- %count = tail call i8 @llvm.ctlz.i8(i8 %and) nounwind readnone
+ %count = tail call i8 @llvm.ctlz.i8(i8 %and, i1 true) nounwind readnone
ret i8 %count
; CHECK: @ctlz
; CHECK-NEXT: entry:
@@ -181,15 +181,15 @@ entry:
define void @cmp.simplify(i32 %a, i32 %b, i1* %c) {
entry:
- %lz = tail call i32 @llvm.ctlz.i32(i32 %a) nounwind readnone
+ %lz = tail call i32 @llvm.ctlz.i32(i32 %a, i1 false) nounwind readnone
%lz.cmp = icmp eq i32 %lz, 32
- volatile store i1 %lz.cmp, i1* %c
- %tz = tail call i32 @llvm.cttz.i32(i32 %a) nounwind readnone
+ store volatile i1 %lz.cmp, i1* %c
+ %tz = tail call i32 @llvm.cttz.i32(i32 %a, i1 false) nounwind readnone
%tz.cmp = icmp ne i32 %tz, 32
- volatile store i1 %tz.cmp, i1* %c
+ store volatile i1 %tz.cmp, i1* %c
%pop = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone
%pop.cmp = icmp eq i32 %pop, 0
- volatile store i1 %pop.cmp, i1* %c
+ store volatile i1 %pop.cmp, i1* %c
ret void
; CHECK: @cmp.simplify
; CHECK-NEXT: entry:
@@ -201,16 +201,22 @@ entry:
; CHECK-NEXT: store volatile i1 %pop.cmp, i1* %c
}
-
-define i32 @cttz_simplify1(i32 %x) nounwind readnone ssp {
- %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x) ; <i32> [#uses=1]
- %shr3 = lshr i32 %tmp1, 5 ; <i32> [#uses=1]
+define i32 @cttz_simplify1a(i32 %x) nounwind readnone ssp {
+ %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+ %shr3 = lshr i32 %tmp1, 5
ret i32 %shr3
-
-; CHECK: @cttz_simplify1
+
+; CHECK: @cttz_simplify1a
; CHECK: icmp eq i32 %x, 0
-; CHECK-NEXT: zext i1
+; CHECK-NEXT: zext i1
; CHECK-NEXT: ret i32
}
+define i32 @cttz_simplify1b(i32 %x) nounwind readnone ssp {
+ %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %shr3 = lshr i32 %tmp1, 5
+ ret i32 %shr3
+; CHECK: @cttz_simplify1b
+; CHECK-NEXT: ret i32 0
+}
diff --git a/test/Transforms/InstCombine/lit.local.cfg b/test/Transforms/InstCombine/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/InstCombine/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index 53a5643..edb5305 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -1,116 +1,184 @@
; This test makes sure that mul instructions are properly eliminated.
-; RUN: opt < %s -instcombine -S | not grep mul
+; RUN: opt < %s -instcombine -S | FileCheck %s
define i32 @test1(i32 %A) {
+; CHECK: @test1
%B = mul i32 %A, 1 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: ret i32 %A
}
define i32 @test2(i32 %A) {
+; CHECK: @test2
; Should convert to an add instruction
%B = mul i32 %A, 2 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: shl i32 %A, 1
}
define i32 @test3(i32 %A) {
+; CHECK: @test3
; This should disappear entirely
%B = mul i32 %A, 0 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: ret i32 0
}
define double @test4(double %A) {
+; CHECK: @test4
; This is safe for FP
%B = fmul double 1.000000e+00, %A ; <double> [#uses=1]
ret double %B
+; CHECK: ret double %A
}
define i32 @test5(i32 %A) {
+; CHECK: @test5
%B = mul i32 %A, 8 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: shl i32 %A, 3
}
define i8 @test6(i8 %A) {
+; CHECK: @test6
%B = mul i8 %A, 8 ; <i8> [#uses=1]
%C = mul i8 %B, 8 ; <i8> [#uses=1]
ret i8 %C
+; CHECK: shl i8 %A, 6
}
define i32 @test7(i32 %i) {
+; CHECK: @test7
%tmp = mul i32 %i, -1 ; <i32> [#uses=1]
ret i32 %tmp
+; CHECK: sub i32 0, %i
}
define i64 @test8(i64 %i) {
- ; tmp = sub 0, %i
+; CHECK: @test8
%j = mul i64 %i, -1 ; <i64> [#uses=1]
ret i64 %j
+; CHECK: sub i64 0, %i
}
define i32 @test9(i32 %i) {
- ; %j = sub 0, %i
+; CHECK: @test9
%j = mul i32 %i, -1 ; <i32> [#uses=1]
ret i32 %j
+; CHECJ: sub i32 0, %i
}
define i32 @test10(i32 %a, i32 %b) {
+; CHECK: @test10
%c = icmp slt i32 %a, 0 ; <i1> [#uses=1]
%d = zext i1 %c to i32 ; <i32> [#uses=1]
; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST10:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST10]], %b
+; CHECK-NEXT: ret i32 %e
}
define i32 @test11(i32 %a, i32 %b) {
+; CHECK: @test11
%c = icmp sle i32 %a, -1 ; <i1> [#uses=1]
%d = zext i1 %c to i32 ; <i32> [#uses=1]
; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST11:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST11]], %b
+; CHECK-NEXT: ret i32 %e
}
-define i32 @test12(i8 %a, i32 %b) {
- %c = icmp ugt i8 %a, 127 ; <i1> [#uses=1]
+define i32 @test12(i32 %a, i32 %b) {
+; CHECK: @test12
+ %c = icmp ugt i32 %a, 2147483647 ; <i1> [#uses=1]
%d = zext i1 %c to i32 ; <i32> [#uses=1]
- ; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST12:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST12]], %b
+; CHECK-NEXT: ret i32 %e
+
}
; PR2642
define internal void @test13(<4 x float>*) {
+; CHECK: @test13
load <4 x float>* %0, align 1
fmul <4 x float> %2, < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >
store <4 x float> %3, <4 x float>* %0, align 1
ret void
+; CHECK-NEXT: ret void
}
define <16 x i8> @test14(<16 x i8> %a) {
+; CHECK: @test14
%b = mul <16 x i8> %a, zeroinitializer
ret <16 x i8> %b
+; CHECK-NEXT: ret <16 x i8> zeroinitializer
}
; rdar://7293527
define i32 @test15(i32 %A, i32 %B) {
+; CHECK: @test15
entry:
%shl = shl i32 1, %B
%m = mul i32 %shl, %A
ret i32 %m
+; CHECK: shl i32 %A, %B
}
; X * Y (when Y is 0 or 1) --> x & (0-Y)
define i32 @test16(i32 %b, i1 %c) {
+; CHECK: @test16
%d = zext i1 %c to i32 ; <i32> [#uses=1]
; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST16:%.*]] = sext i1 %c to i32
+; CHECK-NEXT: %e = and i32 [[TEST16]], %b
+; CHECK-NEXT: ret i32 %e
}
; X * Y (when Y is 0 or 1) --> x & (0-Y)
define i32 @test17(i32 %a, i32 %b) {
+; CHECK: @test17
%a.lobit = lshr i32 %a, 31
%e = mul i32 %a.lobit, %b
ret i32 %e
+; CHECK: [[TEST17:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST17]], %b
+; CHECK-NEXT: ret i32 %e
+}
+
+define i32 @test18(i32 %A, i32 %B) {
+; CHECK: @test18
+ %C = and i32 %A, 1
+ %D = and i32 %B, 1
+
+ %E = mul i32 %C, %D
+ %F = and i32 %E, 16
+ ret i32 %F
+; CHECK-NEXT: ret i32 0
}
+declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
+declare void @use(i1)
+define i32 @test19(i32 %A, i32 %B) {
+; CHECK: @test19
+ %C = and i32 %A, 1
+ %D = and i32 %B, 1
+; It would be nice if we also started proving that this doesn't overflow.
+ %E = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %C, i32 %D)
+ %F = extractvalue {i32, i1} %E, 0
+ %G = extractvalue {i32, i1} %E, 1
+ call void @use(i1 %G)
+ %H = and i32 %F, 16
+ ret i32 %H
+; CHECK: ret i32 0
+}
diff --git a/test/Transforms/InstCombine/overflow.ll b/test/Transforms/InstCombine/overflow.ll
index 9123283..81ceef8 100644
--- a/test/Transforms/InstCombine/overflow.ll
+++ b/test/Transforms/InstCombine/overflow.ll
@@ -130,4 +130,26 @@ entry:
ret i64 %Q
}
+; CHECK: @test8
+; PR11438
+; This is @test1, but the operands are not sign-extended. Make sure
+; we don't transform this case.
+define i32 @test8(i64 %a, i64 %b) nounwind ssp {
+entry:
+; CHECK-NOT: llvm.sadd
+; CHECK: add i64 %a, %b
+; CHECK-NOT: llvm.sadd
+; CHECK: ret
+ %add = add i64 %a, %b
+ %add.off = add i64 %add, 2147483648
+ %0 = icmp ugt i64 %add.off, 4294967295
+ br i1 %0, label %if.then, label %if.end
+
+if.then:
+ tail call void @throwAnExceptionOrWhatever() nounwind
+ br label %if.end
+if.end:
+ %conv9 = trunc i64 %add to i32
+ ret i32 %conv9
+}
diff --git a/test/Transforms/InstCombine/pr12251.ll b/test/Transforms/InstCombine/pr12251.ll
new file mode 100644
index 0000000..74a41eb
--- /dev/null
+++ b/test/Transforms/InstCombine/pr12251.ll
@@ -0,0 +1,15 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define zeroext i1 @_Z3fooPb(i8* nocapture %x) {
+entry:
+ %a = load i8* %x, align 1, !range !0
+ %b = and i8 %a, 1
+ %tobool = icmp ne i8 %b, 0
+ ret i1 %tobool
+}
+
+; CHECK: %a = load i8* %x, align 1, !range !0
+; CHECK-NEXT: %tobool = icmp ne i8 %a, 0
+; CHECK-NEXT: ret i1 %tobool
+
+!0 = metadata !{i8 0, i8 2}
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 4661561..4baae26 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -809,3 +809,23 @@ define i32 @test61(i32* %ptr) {
; CHECK: @test61
; CHECK: ret i32 10
}
+
+define i1 @test62(i1 %A, i1 %B) {
+ %not = xor i1 %A, true
+ %C = select i1 %A, i1 %not, i1 %B
+ ret i1 %C
+; CHECK: @test62
+; CHECK: %not = xor i1 %A, true
+; CHECK: %C = and i1 %not, %B
+; CHECK: ret i1 %C
+}
+
+define i1 @test63(i1 %A, i1 %B) {
+ %not = xor i1 %A, true
+ %C = select i1 %A, i1 %B, i1 %not
+ ret i1 %C
+; CHECK: @test63
+; CHECK: %not = xor i1 %A, true
+; CHECK: %C = or i1 %B, %not
+; CHECK: ret i1 %C
+}
diff --git a/test/Transforms/InstCombine/sext.ll b/test/Transforms/InstCombine/sext.ll
index f49a2ef..f198797 100644
--- a/test/Transforms/InstCombine/sext.ll
+++ b/test/Transforms/InstCombine/sext.ll
@@ -3,8 +3,8 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
declare i32 @llvm.ctpop.i32(i32)
-declare i32 @llvm.ctlz.i32(i32)
-declare i32 @llvm.cttz.i32(i32)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
define i64 @test1(i32 %x) {
%t = call i32 @llvm.ctpop.i32(i32 %x)
@@ -16,7 +16,7 @@ define i64 @test1(i32 %x) {
}
define i64 @test2(i32 %x) {
- %t = call i32 @llvm.ctlz.i32(i32 %x)
+ %t = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
%s = sext i32 %t to i64
ret i64 %s
@@ -25,7 +25,7 @@ define i64 @test2(i32 %x) {
}
define i64 @test3(i32 %x) {
- %t = call i32 @llvm.cttz.i32(i32 %x)
+ %t = call i32 @llvm.cttz.i32(i32 %x, i1 true)
%s = sext i32 %t to i64
ret i64 %s
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll
index 132d51a..52310e3 100644
--- a/test/Transforms/InstCombine/shift.ll
+++ b/test/Transforms/InstCombine/shift.ll
@@ -542,3 +542,75 @@ define i32 @test45(i32 %a) nounwind {
; CHECK-NEXT: %y = lshr i32 %a, 5
; CHECK-NEXT: ret i32 %y
}
+
+define i32 @test46(i32 %a) {
+ %y = ashr exact i32 %a, 3
+ %z = shl i32 %y, 1
+ ret i32 %z
+; CHECK: @test46
+; CHECK-NEXT: %z = ashr exact i32 %a, 2
+; CHECK-NEXT: ret i32 %z
+}
+
+define i32 @test47(i32 %a) {
+ %y = lshr exact i32 %a, 3
+ %z = shl i32 %y, 1
+ ret i32 %z
+; CHECK: @test47
+; CHECK-NEXT: %z = lshr exact i32 %a, 2
+; CHECK-NEXT: ret i32 %z
+}
+
+define i32 @test48(i32 %x) {
+ %A = lshr exact i32 %x, 1
+ %B = shl i32 %A, 3
+ ret i32 %B
+; CHECK: @test48
+; CHECK-NEXT: %B = shl i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test49(i32 %x) {
+ %A = ashr exact i32 %x, 1
+ %B = shl i32 %A, 3
+ ret i32 %B
+; CHECK: @test49
+; CHECK-NEXT: %B = shl i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test50(i32 %x) {
+ %A = shl nsw i32 %x, 1
+ %B = ashr i32 %A, 3
+ ret i32 %B
+; CHECK: @test50
+; CHECK-NEXT: %B = ashr i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test51(i32 %x) {
+ %A = shl nuw i32 %x, 1
+ %B = lshr i32 %A, 3
+ ret i32 %B
+; CHECK: @test51
+; CHECK-NEXT: %B = lshr i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test52(i32 %x) {
+ %A = shl nsw i32 %x, 3
+ %B = ashr i32 %A, 1
+ ret i32 %B
+; CHECK: @test52
+; CHECK-NEXT: %B = shl nsw i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test53(i32 %x) {
+ %A = shl nuw i32 %x, 3
+ %B = lshr i32 %A, 1
+ ret i32 %B
+; CHECK: @test53
+; CHECK-NEXT: %B = shl nuw i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
diff --git a/test/Transforms/InstCombine/sign-test-and-or.ll b/test/Transforms/InstCombine/sign-test-and-or.ll
index 47f5f30..a6066d8 100644
--- a/test/Transforms/InstCombine/sign-test-and-or.ll
+++ b/test/Transforms/InstCombine/sign-test-and-or.ll
@@ -77,3 +77,103 @@ if.then:
if.end:
ret void
}
+
+define void @test5(i32 %a) nounwind {
+ %and = and i32 %a, 134217728
+ %1 = icmp eq i32 %and, 0
+ %2 = icmp sgt i32 %a, -1
+ %or.cond = and i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test5
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test6(i32 %a) nounwind {
+ %1 = icmp sgt i32 %a, -1
+ %and = and i32 %a, 134217728
+ %2 = icmp eq i32 %and, 0
+ %or.cond = and i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test6
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test7(i32 %a) nounwind {
+ %and = and i32 %a, 134217728
+ %1 = icmp ne i32 %and, 0
+ %2 = icmp slt i32 %a, 0
+ %or.cond = or i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test7
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test8(i32 %a) nounwind {
+ %1 = icmp slt i32 %a, 0
+ %and = and i32 %a, 134217728
+ %2 = icmp ne i32 %and, 0
+ %or.cond = or i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test8
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test9(i32 %a) nounwind {
+ %1 = and i32 %a, 1073741824
+ %2 = icmp ne i32 %1, 0
+ %3 = icmp sgt i32 %a, -1
+ %or.cond = and i1 %2, %3
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test9
+; CHECK-NEXT: %1 = and i32 %a, -1073741824
+; CHECK-NEXT: %2 = icmp eq i32 %1, 1073741824
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
diff --git a/test/Transforms/InstCombine/sub-xor.ll b/test/Transforms/InstCombine/sub-xor.ll
new file mode 100644
index 0000000..279e4ac
--- /dev/null
+++ b/test/Transforms/InstCombine/sub-xor.ll
@@ -0,0 +1,37 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+define i32 @test1(i32 %x) nounwind {
+ %and = and i32 %x, 31
+ %sub = sub i32 63, %and
+ ret i32 %sub
+
+; CHECK: @test1
+; CHECK-NEXT: and i32 %x, 31
+; CHECK-NEXT: xor i32 %and, 63
+; CHECK-NEXT: ret
+}
+
+declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
+
+define i32 @test2(i32 %x) nounwind {
+ %count = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) nounwind readnone
+ %sub = sub i32 31, %count
+ ret i32 %sub
+
+; CHECK: @test2
+; CHECK-NEXT: ctlz
+; CHECK-NEXT: xor i32 %count, 31
+; CHECK-NEXT: ret
+}
+
+define i32 @test3(i32 %x) nounwind {
+ %and = and i32 %x, 31
+ %sub = xor i32 31, %and
+ %add = add i32 %sub, 42
+ ret i32 %add
+
+; CHECK: @test3
+; CHECK-NEXT: and i32 %x, 31
+; CHECK-NEXT: sub i32 73, %and
+; CHECK-NEXT: ret
+}
diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll
index 37de328..b71ec8c 100644
--- a/test/Transforms/InstCombine/sub.ll
+++ b/test/Transforms/InstCombine/sub.ll
@@ -301,3 +301,29 @@ define i32 @test28(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: add i32
; CHECK-NEXT: ret i32
}
+
+define i64 @test29(i8* %foo, i64 %i, i64 %j) {
+ %gep1 = getelementptr inbounds i8* %foo, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = ptrtoint i8* %gep1 to i64
+ %cast2 = ptrtoint i8* %gep2 to i64
+ %sub = sub i64 %cast1, %cast2
+ ret i64 %sub
+; CHECK: @test29
+; CHECK-NEXT: sub i64 %i, %j
+; CHECK-NEXT: ret i64
+}
+
+define i64 @test30(i8* %foo, i64 %i, i64 %j) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr inbounds i32* %bit, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = ptrtoint i32* %gep1 to i64
+ %cast2 = ptrtoint i8* %gep2 to i64
+ %sub = sub i64 %cast1, %cast2
+ ret i64 %sub
+; CHECK: @test30
+; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
+; CHECK-NEXT: sub i64 %gep1.idx, %j
+; CHECK-NEXT: ret i64
+}
diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll
index 896cb88..8f78c2e 100644
--- a/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/test/Transforms/InstCombine/vec_shuffle.ll
@@ -98,6 +98,17 @@ define <4 x i8> @test9a(<16 x i8> %tmp6) nounwind {
ret <4 x i8> %tmp9
}
+; Test fold of two shuffles where the first shuffle vectors inputs are a
+; different length then the second.
+define <4 x i8> @test9b(<4 x i8> %tmp6, <4 x i8> %tmp7) nounwind {
+; CHECK: @test9
+; CHECK-NEXT: shufflevector
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <4 x i8> %tmp6, <4 x i8> %tmp7, <8 x i32> <i32 0, i32 1, i32 4, i32 5, i32 4, i32 5, i32 2, i32 3> ; <<4 x i8>> [#uses=1]
+ %tmp9 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5> ; <<4 x i8>> [#uses=1]
+ ret <4 x i8> %tmp9
+}
+
; Redundant vector splats should be removed. Radar 8597790.
define <4 x i32> @test10(<4 x i32> %tmp5) nounwind {
; CHECK: @test10
@@ -107,3 +118,38 @@ define <4 x i32> @test10(<4 x i32> %tmp5) nounwind {
%tmp7 = shufflevector <4 x i32> %tmp6, <4 x i32> undef, <4 x i32> zeroinitializer
ret <4 x i32> %tmp7
}
+
+; Test fold of two shuffles where the two shufflevector inputs's op1 are
+; the same
+define <8 x i8> @test11(<16 x i8> %tmp6) nounwind {
+; CHECK: @test11
+; CHECK-NEXT: shufflevector <16 x i8> %tmp6, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x i8>> [#uses=1]
+ %tmp2 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> ; <<4 x i8>> [#uses=1]
+ %tmp3 = shufflevector <4 x i8> %tmp1, <4 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> ; <<8 x i8>> [#uses=1]
+ ret <8 x i8> %tmp3
+}
+
+; Test fold of two shuffles where the first shufflevector's inputs are
+; the same as the second
+define <8 x i8> @test12(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind {
+; CHECK: @test12
+; CHECK-NEXT: shufflevector <8 x i8> %tmp6, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12>
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7> ; <<8 x i8>> [#uses=1]
+ %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12> ; <<8 x i8>> [#uses=1]
+ ret <8 x i8> %tmp3
+}
+
+; Test fold of two shuffles where the first shufflevector's inputs are
+; the same as the second
+define <8 x i8> @test12a(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind {
+; CHECK: @test12a
+; CHECK-NEXT: shufflevector <8 x i8> %tmp2, <8 x i8> %tmp6, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11>
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7> ; <<8 x i8>> [#uses=1]
+ %tmp3 = shufflevector <8 x i8> %tmp2, <8 x i8> %tmp1, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11> ; <<8 x i8>> [#uses=1]
+ ret <8 x i8> %tmp3
+}
+
diff --git a/test/Transforms/InstCombine/vector_gep1.ll b/test/Transforms/InstCombine/vector_gep1.ll
new file mode 100644
index 0000000..6523622
--- /dev/null
+++ b/test/Transforms/InstCombine/vector_gep1.ll
@@ -0,0 +1,37 @@
+; RUN: opt -instcombine %s -disable-output
+; RUN: opt -instsimplify %s -disable-output
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@G1 = global i8 zeroinitializer
+
+define <2 x i1> @test(<2 x i8*> %a, <2 x i8*> %b) {
+ %A = icmp eq <2 x i8*> %a, %b
+ ret <2 x i1> %A
+}
+
+define <2 x i1> @test2(<2 x i8*> %a) {
+ %A = inttoptr <2 x i32> <i32 1, i32 2> to <2 x i8*>
+ %B = icmp ult <2 x i8*> %A, zeroinitializer
+ ret <2 x i1> %B
+}
+
+define <2 x i1> @test3(<2 x i8*> %a) {
+ %g = getelementptr <2 x i8*> %a, <2 x i32> <i32 1, i32 0>
+ %B = icmp ult <2 x i8*> %g, zeroinitializer
+ ret <2 x i1> %B
+}
+
+define <1 x i1> @test4(<1 x i8*> %a) {
+ %g = getelementptr <1 x i8*> %a, <1 x i32> <i32 1>
+ %B = icmp ult <1 x i8*> %g, zeroinitializer
+ ret <1 x i1> %B
+}
+
+define <2 x i1> @test5(<2 x i8*> %a) {
+ %w = getelementptr <2 x i8*> %a, <2 x i32> zeroinitializer
+ %e = getelementptr <2 x i8*> %w, <2 x i32> <i32 5, i32 9>
+ %g = getelementptr <2 x i8*> %e, <2 x i32> <i32 1, i32 0>
+ %B = icmp ult <2 x i8*> %g, zeroinitializer
+ ret <2 x i1> %B
+}
diff --git a/test/Transforms/InstCombine/volatile_store.ll b/test/Transforms/InstCombine/volatile_store.ll
index 0518e5a..2256678 100644
--- a/test/Transforms/InstCombine/volatile_store.ll
+++ b/test/Transforms/InstCombine/volatile_store.ll
@@ -5,8 +5,8 @@
define void @self_assign_1() {
entry:
- %tmp = volatile load i32* @x ; <i32> [#uses=1]
- volatile store i32 %tmp, i32* @x
+ %tmp = load volatile i32* @x ; <i32> [#uses=1]
+ store volatile i32 %tmp, i32* @x
br label %return
return: ; preds = %entry
OpenPOWER on IntegriCloud