diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-01 10:31:22 +0000 |
commit | 1e7804dbd25b8dbf534c850355d70ad215206f4b (patch) | |
tree | dba00119388b84f9f44e6ec5e9129f807fd79ca3 /test/Transforms | |
parent | 571945e6affd20b19264ec22495da418d0fbdbb4 (diff) |
Notes
Diffstat (limited to 'test/Transforms')
25 files changed, 970 insertions, 218 deletions
diff --git a/test/Transforms/GVN/rle-phi-translate.ll b/test/Transforms/GVN/rle-phi-translate.ll index 912f58064a26a..6731f43c0d2b0 100644 --- a/test/Transforms/GVN/rle-phi-translate.ll +++ b/test/Transforms/GVN/rle-phi-translate.ll @@ -38,77 +38,109 @@ bb2: ; preds = %bb1, %bb define i8 @test2(i1 %cond, i32* %b, i32* %c) nounwind { ; CHECK: @test2 entry: - br i1 %cond, label %bb, label %bb1 + br i1 %cond, label %bb, label %bb1 bb: %b1 = bitcast i32* %b to i8* store i8 4, i8* %b1 - br label %bb2 + br label %bb2 bb1: %c1 = bitcast i32* %c to i8* store i8 92, i8* %c1 - br label %bb2 + br label %bb2 bb2: - %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] + %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] %d1 = bitcast i32* %d to i8* - %dv = load i8* %d1 + %dv = load i8* %d1 ; CHECK: %dv = phi i8 [ 92, %bb1 ], [ 4, %bb ] ; CHECK-NOT: load ; CHECK: ret i8 %dv - ret i8 %dv + ret i8 %dv } define i32 @test3(i1 %cond, i32* %b, i32* %c) nounwind { ; CHECK: @test3 entry: - br i1 %cond, label %bb, label %bb1 + br i1 %cond, label %bb, label %bb1 bb: %b1 = getelementptr i32* %b, i32 17 store i32 4, i32* %b1 - br label %bb2 + br label %bb2 bb1: %c1 = getelementptr i32* %c, i32 7 store i32 82, i32* %c1 - br label %bb2 + br label %bb2 bb2: - %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] - %i = phi i32 [ 7, %bb1 ], [ 17, %bb ] + %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] + %i = phi i32 [ 7, %bb1 ], [ 17, %bb ] %d1 = getelementptr i32* %d, i32 %i - %dv = load i32* %d1 + %dv = load i32* %d1 ; CHECK: %dv = phi i32 [ 82, %bb1 ], [ 4, %bb ] ; CHECK-NOT: load ; CHECK: ret i32 %dv - ret i32 %dv + ret i32 %dv } ; PR5313 define i32 @test4(i1 %cond, i32* %b, i32* %c) nounwind { ; CHECK: @test4 entry: - br i1 %cond, label %bb, label %bb1 + br i1 %cond, label %bb, label %bb1 bb: store i32 4, i32* %b - br label %bb2 + br label %bb2 bb1: %c1 = getelementptr i32* %c, i32 7 store i32 82, i32* %c1 - br label %bb2 + br label %bb2 bb2: - %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] - %i = phi i32 [ 7, %bb1 ], [ 0, %bb ] + %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] + %i = phi i32 [ 7, %bb1 ], [ 0, %bb ] %d1 = getelementptr i32* %d, i32 %i - %dv = load i32* %d1 + %dv = load i32* %d1 ; CHECK: %dv = phi i32 [ 82, %bb1 ], [ 4, %bb ] ; CHECK-NOT: load ; CHECK: ret i32 %dv - ret i32 %dv + ret i32 %dv } + + +; void test5(int N, double* G) { +; for (long j = 1; j < 1000; j++) +; G[j] = G[j] + G[j-1]; +; } +; +; Should compile into one load in the loop. +define void @test5(i32 %N, double* nocapture %G) nounwind ssp { +; CHECK: @test5 +bb.nph: + br label %for.body + +for.body: + %indvar = phi i64 [ 0, %bb.nph ], [ %tmp, %for.body ] + %arrayidx6 = getelementptr double* %G, i64 %indvar + %tmp = add i64 %indvar, 1 + %arrayidx = getelementptr double* %G, i64 %tmp + %tmp3 = load double* %arrayidx + %tmp7 = load double* %arrayidx6 + %add = fadd double %tmp3, %tmp7 + store double %add, double* %arrayidx + %exitcond = icmp eq i64 %tmp, 999 + br i1 %exitcond, label %for.end, label %for.body +; CHECK: for.body: +; CHECK: phi double +; CHECK: load double +; CHECK-NOT: load double +; CHECK: br i1 +for.end: + ret void +} diff --git a/test/Transforms/GlobalOpt/heap-sra-3.ll b/test/Transforms/GlobalOpt/heap-sra-3.ll index cbbcdfcaf7755..e7a877cda446a 100644 --- a/test/Transforms/GlobalOpt/heap-sra-3.ll +++ b/test/Transforms/GlobalOpt/heap-sra-3.ll @@ -8,7 +8,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1 define void @bar(i64 %Size) nounwind noinline { entry: - %mallocsize = mul i64 8, %Size, ; <i64> [#uses=1] + %mallocsize = mul i64 8, %Size ; <i64> [#uses=1] ; CHECK: mul i64 %Size, 4 %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1] %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1] diff --git a/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll b/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll index 187e2f594d69b..6672b6c6d4e5f 100644 --- a/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll +++ b/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll @@ -33,6 +33,14 @@ define i1 @lt_signed_to_large_negative(i8 %SB) { ; CHECK: ret i1 false } +define i1 @lt_signed_to_small_unsigned(i8 %SB) { + %Y = sext i8 %SB to i32 + %C = icmp ult i32 %Y, 17 + ret i1 %C +; CHECK: %C = icmp ult i8 %SB, 17 +; CHECK: ret i1 %C +} + define i1 @lt_signed_to_small_signed(i8 %SB) { %Y = sext i8 %SB to i32 ; <i32> [#uses=1] %C = icmp slt i32 %Y, 17 ; <i1> [#uses=1] @@ -77,6 +85,14 @@ define i1 @lt_unsigned_to_small_unsigned(i8 %SB) { ; CHECK: ret i1 %C } +define i1 @lt_unsigned_to_small_signed(i8 %SB) { + %Y = zext i8 %SB to i32 + %C = icmp slt i32 %Y, 17 + ret i1 %C +; CHECK: %C = icmp ult i8 %SB, 17 +; CHECK: ret i1 %C +} + define i1 @lt_unsigned_to_small_negative(i8 %SB) { %Y = zext i8 %SB to i32 ; <i32> [#uses=1] %C = icmp slt i32 %Y, -17 ; <i1> [#uses=1] @@ -106,6 +122,14 @@ define i1 @gt_signed_to_large_negative(i8 %SB) { ; CHECK: ret i1 true } +define i1 @gt_signed_to_small_unsigned(i8 %SB) { + %Y = sext i8 %SB to i32 + %C = icmp ugt i32 %Y, 17 + ret i1 %C +; CHECK: %C = icmp ugt i8 %SB, 17 +; CHECK: ret i1 %C +} + define i1 @gt_signed_to_small_signed(i8 %SB) { %Y = sext i8 %SB to i32 ; <i32> [#uses=1] %C = icmp sgt i32 %Y, 17 ; <i1> [#uses=1] @@ -151,6 +175,14 @@ define i1 @gt_unsigned_to_small_unsigned(i8 %SB) { ; CHECK: ret i1 %C } +define i1 @gt_unsigned_to_small_signed(i8 %SB) { + %Y = zext i8 %SB to i32 + %C = icmp sgt i32 %Y, 17 + ret i1 %C +; CHECK: %C = icmp ugt i8 %SB, 17 +; CHECK: ret i1 %C +} + define i1 @gt_unsigned_to_small_negative(i8 %SB) { %Y = zext i8 %SB to i32 ; <i32> [#uses=1] %C = icmp sgt i32 %Y, -17 ; <i1> [#uses=1] diff --git a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll deleted file mode 100644 index 4d1a9ef21655b..0000000000000 --- a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll +++ /dev/null @@ -1,12 +0,0 @@ -; This test case is reduced from llvmAsmParser.cpp -; The optimizer should not remove the cast here. -; RUN: opt < %s -instcombine -S | \ -; RUN: grep sext.*i32 - - -define i1 @test(i16 %X) { - %A = sext i16 %X to i32 ; <i32> [#uses=1] - %B = icmp ugt i32 %A, 1330 ; <i1> [#uses=1] - ret i1 %B -} - diff --git a/test/Transforms/InstCombine/2009-12-17-CmpSelectNull.ll b/test/Transforms/InstCombine/2009-12-17-CmpSelectNull.ll new file mode 100644 index 0000000000000..fb7497b395d4f --- /dev/null +++ b/test/Transforms/InstCombine/2009-12-17-CmpSelectNull.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +@.str254 = internal constant [2 x i8] c".\00" +@.str557 = internal constant [3 x i8] c"::\00" + +define i8* @demangle_qualified(i32 %isfuncname) nounwind { +entry: + %tobool272 = icmp ne i32 %isfuncname, 0 + %cond276 = select i1 %tobool272, i8* getelementptr inbounds ([2 x i8]* @.str254, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8]* @.str557, i32 0, i32 0) ; <i8*> [#uses=4] + %cmp.i504 = icmp eq i8* %cond276, null + %rval = getelementptr i8* %cond276, i1 %cmp.i504 + ret i8* %rval +} + +; CHECK: %cond276 = select i1 +; CHECK: ret i8* %cond276 diff --git a/test/Transforms/InstCombine/cast_ptr.ll b/test/Transforms/InstCombine/cast_ptr.ll index 6544e7d735a44..6a00e83978482 100644 --- a/test/Transforms/InstCombine/cast_ptr.ll +++ b/test/Transforms/InstCombine/cast_ptr.ll @@ -27,3 +27,12 @@ define i1 @test2(i8* %a, i8* %b) { ret i1 %r } +; These casts should also be folded away. +; CHECK: @test3 +; CHECK: icmp eq i8* %a, @global +@global = global i8 0 +define i1 @test3(i8* %a) { + %tmpa = ptrtoint i8* %a to i32 + %r = icmp eq i32 %tmpa, ptrtoint (i8* @global to i32) + ret i1 %r +} diff --git a/test/Transforms/InstCombine/constant-fold-compare.ll b/test/Transforms/InstCombine/constant-fold-compare.ll new file mode 100644 index 0000000000000..6e41e2f680264 --- /dev/null +++ b/test/Transforms/InstCombine/constant-fold-compare.ll @@ -0,0 +1,8 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" + +define i32 @a() nounwind readnone { +entry: + ret i32 zext (i1 icmp eq (i32 0, i32 ptrtoint (i32 ()* @a to i32)) to i32) +} +; CHECK: ret i32 0 diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll index 82ac575717814..732a88262178d 100644 --- a/test/Transforms/InstCombine/crash.ll +++ b/test/Transforms/InstCombine/crash.ll @@ -1,5 +1,5 @@ ; RUN: opt < %s -instcombine -S -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128:n8:16:32" target triple = "i386-apple-darwin10.0" define i32 @test0(i8 %tmp2) ssp { @@ -148,3 +148,59 @@ entry: store i32* getelementptr (i32* bitcast (i32 (i32, i8**)* @test6 to i32*), i32 -2048), i32** @test6g, align 4 unreachable } + + +; PR5827 + +%class.RuleBasedBreakIterator = type { i64 ()* } +%class.UStack = type { i8** } + +define i32 @_ZN22RuleBasedBreakIterator15checkDictionaryEi(%class.RuleBasedBreakIterator* %this, i32 %x) align 2 { +entry: + %breaks = alloca %class.UStack, align 4 ; <%class.UStack*> [#uses=3] + call void @_ZN6UStackC1Ei(%class.UStack* %breaks, i32 0) + %tobool = icmp ne i32 %x, 0 ; <i1> [#uses=1] + 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] + 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] + 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 + +cond.false: ; preds = %entry + %tmp4 = getelementptr inbounds %class.RuleBasedBreakIterator* %this, i32 0, i32 0 ; <i64 ()**> [#uses=1] + %tmp5 = load i64 ()** %tmp4 ; <i64 ()*> [#uses=1] + %call = invoke i64 %tmp5() + to label %cond.end unwind label %ehcleanup ; <i64> [#uses=1] + +cond.end: ; preds = %cond.false, %entry + %cond = phi i64 [ 0, %entry ], [ %call, %cond.false ] ; <i64> [#uses=1] + %conv = trunc i64 %cond to i32 ; <i32> [#uses=1] + call void @_ZN6UStackD1Ev(%class.UStack* %breaks) + ret i32 %conv +} + +declare void @_ZN6UStackC1Ei(%class.UStack*, i32) + +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/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 64e88c9ae86d7..79fa220752b55 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -1,10 +1,13 @@ -; RUN: opt < %s -instcombine -S | not grep icmp +; RUN: opt < %s -instcombine -S | FileCheck %s define i32 @test1(i32 %X) { entry: icmp slt i32 %X, 0 ; <i1>:0 [#uses=1] zext i1 %0 to i32 ; <i32>:1 [#uses=1] ret i32 %1 +; CHECK: @test1 +; CHECK: lshr i32 %X, 31 +; CHECK-NEXT: ret i32 } define i32 @test2(i32 %X) { @@ -12,6 +15,10 @@ entry: icmp ult i32 %X, -2147483648 ; <i1>:0 [#uses=1] zext i1 %0 to i32 ; <i32>:1 [#uses=1] ret i32 %1 +; CHECK: @test2 +; CHECK: lshr i32 %X, 31 +; CHECK-NEXT: xor i32 +; CHECK-NEXT: ret i32 } define i32 @test3(i32 %X) { @@ -19,6 +26,9 @@ entry: icmp slt i32 %X, 0 ; <i1>:0 [#uses=1] sext i1 %0 to i32 ; <i32>:1 [#uses=1] ret i32 %1 +; CHECK: @test3 +; CHECK: ashr i32 %X, 31 +; CHECK-NEXT: ret i32 } define i32 @test4(i32 %X) { @@ -26,6 +36,10 @@ entry: icmp ult i32 %X, -2147483648 ; <i1>:0 [#uses=1] sext i1 %0 to i32 ; <i32>:1 [#uses=1] ret i32 %1 +; CHECK: @test4 +; CHECK: ashr i32 %X, 31 +; CHECK-NEXT: xor i32 +; CHECK-NEXT: ret i32 } ; PR4837 @@ -33,6 +47,8 @@ define <2 x i1> @test5(<2 x i64> %x) { entry: %V = icmp eq <2 x i64> %x, undef ret <2 x i1> %V +; CHECK: @test5 +; CHECK: ret <2 x i1> undef } define i32 @test6(i32 %a, i32 %b) { @@ -41,4 +57,58 @@ define i32 @test6(i32 %a, i32 %b) { %e = sub i32 0, %d %f = and i32 %e, %b ret i32 %f +; CHECK: @test6 +; CHECK-NEXT: ashr i32 %a, 31 +; CHECK-NEXT: %f = and i32 %e, %b +; CHECK-NEXT: ret i32 %f } + + +define i1 @test7(i32 %x) { +entry: + %a = add i32 %x, -1 + %b = icmp ult i32 %a, %x + ret i1 %b +; CHECK: @test7 +; CHECK: %b = icmp ne i32 %x, 0 +; CHECK: ret i1 %b +} + +define i1 @test8(i32 %x){ +entry: + %a = add i32 %x, -1 + %b = icmp eq i32 %a, %x + ret i1 %b +; CHECK: @test8 +; CHECK: ret i1 false +} + +define i1 @test9(i32 %x) { +entry: + %a = add i32 %x, -2 + %b = icmp ugt i32 %x, %a + ret i1 %b +; CHECK: @test9 +; CHECK: icmp ugt i32 %x, 1 +; CHECK: ret i1 %b +} + +define i1 @test10(i32 %x){ +entry: + %a = add i32 %x, -1 + %b = icmp slt i32 %a, %x + ret i1 %b + +; CHECK: @test10 +; CHECK: %b = icmp ne i32 %x, -2147483648 +; CHECK: ret i1 %b +} + +define i1 @test11(i32 %x) { + %a = add nsw i32 %x, 8 + %b = icmp slt i32 %x, %a + ret i1 %b +; CHECK: @test11 +; CHECK: ret i1 true +} + diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index fda4386e9439e..135e7772eea90 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -4,6 +4,7 @@ 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 define i8 @test1(i8 %A, i8 %B) { %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B) @@ -77,3 +78,24 @@ define i8 @test6(i8 %A, i1* %overflowPtr) { ; CHECK-NEXT: store i1 false, i1* %overflowPtr ; CHECK-NEXT: ret i8 %A } + + +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 + + %B = tail call double @llvm.powi.f64(double %V, i32 0) nounwind + volatile store double %B, double* %P + + %C = tail call double @llvm.powi.f64(double %V, i32 1) nounwind + volatile store double %C, double* %P + ret void +; CHECK: @powi +; CHECK: %A = fdiv double 1.0{{.*}}, %V +; CHECK: volatile store double %A, +; CHECK: volatile store double 1.0 +; CHECK: volatile store double %V +} + + diff --git a/test/Transforms/InstCombine/memcpy.ll b/test/Transforms/InstCombine/memcpy.ll new file mode 100644 index 0000000000000..2e7b2c0bb41d5 --- /dev/null +++ b/test/Transforms/InstCombine/memcpy.ll @@ -0,0 +1,10 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) + +define void @test4(i8* %a) { + tail call void @llvm.memcpy.i32( i8* %a, i8* %a, i32 100, i32 1 ) + ret void +} +; CHECK: define void @test4 +; CHECK-NEXT: ret void diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index b04382e8b1132..06d5338884ec8 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -1,205 +1,309 @@ ; This test makes sure that these instructions are properly eliminated. ; PR1822 -; RUN: opt < %s -instcombine -S | not grep select +; RUN: opt < %s -instcombine -S | FileCheck %s define i32 @test1(i32 %A, i32 %B) { - %C = select i1 false, i32 %A, i32 %B ; <i32> [#uses=1] + %C = select i1 false, i32 %A, i32 %B ret i32 %C +; CHECK: @test1 +; CHECK: ret i32 %B } define i32 @test2(i32 %A, i32 %B) { - %C = select i1 true, i32 %A, i32 %B ; <i32> [#uses=1] + %C = select i1 true, i32 %A, i32 %B ret i32 %C +; CHECK: @test2 +; CHECK: ret i32 %A } define i32 @test3(i1 %C, i32 %I) { ; V = I - %V = select i1 %C, i32 %I, i32 %I ; <i32> [#uses=1] + %V = select i1 %C, i32 %I, i32 %I ret i32 %V +; CHECK: @test3 +; CHECK: ret i32 %I } define i1 @test4(i1 %C) { ; V = C - %V = select i1 %C, i1 true, i1 false ; <i1> [#uses=1] + %V = select i1 %C, i1 true, i1 false ret i1 %V +; CHECK: @test4 +; CHECK: ret i1 %C } define i1 @test5(i1 %C) { ; V = !C - %V = select i1 %C, i1 false, i1 true ; <i1> [#uses=1] + %V = select i1 %C, i1 false, i1 true ret i1 %V +; CHECK: @test5 +; CHECK: xor i1 %C, true +; CHECK: ret i1 } define i32 @test6(i1 %C) { ; V = cast C to int - %V = select i1 %C, i32 1, i32 0 ; <i32> [#uses=1] + %V = select i1 %C, i32 1, i32 0 ret i32 %V +; CHECK: @test6 +; CHECK: %V = zext i1 %C to i32 +; CHECK: ret i32 %V } define i1 @test7(i1 %C, i1 %X) { ; R = or C, X - %R = select i1 %C, i1 true, i1 %X ; <i1> [#uses=1] + %R = select i1 %C, i1 true, i1 %X ret i1 %R +; CHECK: @test7 +; CHECK: %R = or i1 %C, %X +; CHECK: ret i1 %R } define i1 @test8(i1 %C, i1 %X) { ; R = and C, X - %R = select i1 %C, i1 %X, i1 false ; <i1> [#uses=1] + %R = select i1 %C, i1 %X, i1 false ret i1 %R +; CHECK: @test8 +; CHECK: %R = and i1 %C, %X +; CHECK: ret i1 %R } define i1 @test9(i1 %C, i1 %X) { ; R = and !C, X - %R = select i1 %C, i1 false, i1 %X ; <i1> [#uses=1] + %R = select i1 %C, i1 false, i1 %X ret i1 %R +; CHECK: @test9 +; CHECK: xor i1 %C, true +; CHECK: %R = and i1 +; CHECK: ret i1 %R } define i1 @test10(i1 %C, i1 %X) { ; R = or !C, X - %R = select i1 %C, i1 %X, i1 true ; <i1> [#uses=1] + %R = select i1 %C, i1 %X, i1 true ret i1 %R +; CHECK: @test10 +; CHECK: xor i1 %C, true +; CHECK: %R = or i1 +; CHECK: ret i1 %R } define i32 @test11(i32 %a) { - %C = icmp eq i32 %a, 0 ; <i1> [#uses=1] - %R = select i1 %C, i32 0, i32 1 ; <i32> [#uses=1] + %C = icmp eq i32 %a, 0 + %R = select i1 %C, i32 0, i32 1 ret i32 %R +; CHECK: @test11 +; CHECK: icmp ne i32 %a, 0 +; CHECK: %R = zext i1 +; CHECK: ret i32 %R } define i32 @test12(i1 %cond, i32 %a) { - %b = or i32 %a, 1 ; <i32> [#uses=1] - %c = select i1 %cond, i32 %b, i32 %a ; <i32> [#uses=1] + %b = or i32 %a, 1 + %c = select i1 %cond, i32 %b, i32 %a ret i32 %c +; CHECK: @test12 +; CHECK: %b = zext i1 %cond to i32 +; CHECK: %c = or i32 %b, %a +; CHECK: ret i32 %c } define i32 @test12a(i1 %cond, i32 %a) { - %b = ashr i32 %a, 1 ; <i32> [#uses=1] - %c = select i1 %cond, i32 %b, i32 %a ; <i32> [#uses=1] + %b = ashr i32 %a, 1 + %c = select i1 %cond, i32 %b, i32 %a ret i32 %c +; CHECK: @test12a +; CHECK: %b = zext i1 %cond to i32 +; CHECK: %c = ashr i32 %a, %b +; CHECK: ret i32 %c } define i32 @test12b(i1 %cond, i32 %a) { - %b = ashr i32 %a, 1 ; <i32> [#uses=1] - %c = select i1 %cond, i32 %a, i32 %b ; <i32> [#uses=1] + %b = ashr i32 %a, 1 + %c = select i1 %cond, i32 %a, i32 %b ret i32 %c +; CHECK: @test12b +; CHECK: zext i1 %cond to i32 +; CHECK: %b = xor i32 +; CHECK: %c = ashr i32 %a, %b +; CHECK: ret i32 %c } define i32 @test13(i32 %a, i32 %b) { - %C = icmp eq i32 %a, %b ; <i1> [#uses=1] - %V = select i1 %C, i32 %a, i32 %b ; <i32> [#uses=1] + %C = icmp eq i32 %a, %b + %V = select i1 %C, i32 %a, i32 %b ret i32 %V +; CHECK: @test13 +; CHECK: ret i32 %b } define i32 @test13a(i32 %a, i32 %b) { - %C = icmp ne i32 %a, %b ; <i1> [#uses=1] - %V = select i1 %C, i32 %a, i32 %b ; <i32> [#uses=1] + %C = icmp ne i32 %a, %b + %V = select i1 %C, i32 %a, i32 %b ret i32 %V +; CHECK: @test13a +; CHECK: ret i32 %a } define i32 @test13b(i32 %a, i32 %b) { - %C = icmp eq i32 %a, %b ; <i1> [#uses=1] - %V = select i1 %C, i32 %b, i32 %a ; <i32> [#uses=1] + %C = icmp eq i32 %a, %b + %V = select i1 %C, i32 %b, i32 %a ret i32 %V +; CHECK: @test13b +; CHECK: ret i32 %a } define i1 @test14a(i1 %C, i32 %X) { - %V = select i1 %C, i32 %X, i32 0 ; <i32> [#uses=1] + %V = select i1 %C, i32 %X, i32 0 ; (X < 1) | !C - %R = icmp slt i32 %V, 1 ; <i1> [#uses=1] + %R = icmp slt i32 %V, 1 ret i1 %R +; CHECK: @test14a +; CHECK: icmp slt i32 %X, 1 +; CHECK: xor i1 %C, true +; CHECK: or i1 +; CHECK: ret i1 %R } define i1 @test14b(i1 %C, i32 %X) { - %V = select i1 %C, i32 0, i32 %X ; <i32> [#uses=1] + %V = select i1 %C, i32 0, i32 %X ; (X < 1) | C - %R = icmp slt i32 %V, 1 ; <i1> [#uses=1] + %R = icmp slt i32 %V, 1 ret i1 %R +; CHECK: @test14b +; CHECK: icmp slt i32 %X, 1 +; CHECK: or i1 +; CHECK: ret i1 %R } ;; Code sequence for (X & 16) ? 16 : 0 define i32 @test15a(i32 %X) { - %t1 = and i32 %X, 16 ; <i32> [#uses=1] - %t2 = icmp eq i32 %t1, 0 ; <i1> [#uses=1] - %t3 = select i1 %t2, i32 0, i32 16 ; <i32> [#uses=1] + %t1 = and i32 %X, 16 + %t2 = icmp eq i32 %t1, 0 + %t3 = select i1 %t2, i32 0, i32 16 ret i32 %t3 +; CHECK: @test15a +; CHECK: %t1 = and i32 %X, 16 +; CHECK: ret i32 %t1 } ;; Code sequence for (X & 32) ? 0 : 24 define i32 @test15b(i32 %X) { - %t1 = and i32 %X, 32 ; <i32> [#uses=1] - %t2 = icmp eq i32 %t1, 0 ; <i1> [#uses=1] - %t3 = select i1 %t2, i32 32, i32 0 ; <i32> [#uses=1] + %t1 = and i32 %X, 32 + %t2 = icmp eq i32 %t1, 0 + %t3 = select i1 %t2, i32 32, i32 0 ret i32 %t3 +; CHECK: @test15b +; CHECK: %t1 = and i32 %X, 32 +; CHECK: xor i32 %t1, 32 +; CHECK: ret i32 } ;; Alternate code sequence for (X & 16) ? 16 : 0 define i32 @test15c(i32 %X) { - %t1 = and i32 %X, 16 ; <i32> [#uses=1] - %t2 = icmp eq i32 %t1, 16 ; <i1> [#uses=1] - %t3 = select i1 %t2, i32 16, i32 0 ; <i32> [#uses=1] + %t1 = and i32 %X, 16 + %t2 = icmp eq i32 %t1, 16 + %t3 = select i1 %t2, i32 16, i32 0 ret i32 %t3 +; CHECK: @test15c +; CHECK: %t1 = and i32 %X, 16 +; CHECK: ret i32 %t1 } ;; Alternate code sequence for (X & 16) ? 16 : 0 define i32 @test15d(i32 %X) { - %t1 = and i32 %X, 16 ; <i32> [#uses=1] - %t2 = icmp ne i32 %t1, 0 ; <i1> [#uses=1] - %t3 = select i1 %t2, i32 16, i32 0 ; <i32> [#uses=1] + %t1 = and i32 %X, 16 + %t2 = icmp ne i32 %t1, 0 + %t3 = select i1 %t2, i32 16, i32 0 ret i32 %t3 +; CHECK: @test15d +; CHECK: %t1 = and i32 %X, 16 +; CHECK: ret i32 %t1 } define i32 @test16(i1 %C, i32* %P) { - %P2 = select i1 %C, i32* %P, i32* null ; <i32*> [#uses=1] - %V = load i32* %P2 ; <i32> [#uses=1] + %P2 = select i1 %C, i32* %P, i32* null + %V = load i32* %P2 ret i32 %V +; CHECK: @test16 +; CHECK-NEXT: %V = load i32* %P +; CHECK: ret i32 %V } define i1 @test17(i32* %X, i1 %C) { - %R = select i1 %C, i32* %X, i32* null ; <i32*> [#uses=1] - %RV = icmp eq i32* %R, null ; <i1> [#uses=1] + %R = select i1 %C, i32* %X, i32* null + %RV = icmp eq i32* %R, null ret i1 %RV +; CHECK: @test17 +; CHECK: icmp eq i32* %X, null +; CHECK: xor i1 %C, true +; CHECK: %RV = or i1 +; CHECK: ret i1 %RV } define i32 @test18(i32 %X, i32 %Y, i1 %C) { - %R = select i1 %C, i32 %X, i32 0 ; <i32> [#uses=1] - %V = sdiv i32 %Y, %R ; <i32> [#uses=1] + %R = select i1 %C, i32 %X, i32 0 + %V = sdiv i32 %Y, %R ret i32 %V +; CHECK: @test18 +; CHECK: %V = sdiv i32 %Y, %X +; CHECK: ret i32 %V } define i32 @test19(i32 %x) { - %tmp = icmp ugt i32 %x, 2147483647 ; <i1> [#uses=1] - %retval = select i1 %tmp, i32 -1, i32 0 ; <i32> [#uses=1] + %tmp = icmp ugt i32 %x, 2147483647 + %retval = select i1 %tmp, i32 -1, i32 0 ret i32 %retval +; CHECK: @test19 +; CHECK-NEXT: ashr i32 %x, 31 +; CHECK-NEXT: ret i32 } define i32 @test20(i32 %x) { - %tmp = icmp slt i32 %x, 0 ; <i1> [#uses=1] - %retval = select i1 %tmp, i32 -1, i32 0 ; <i32> [#uses=1] + %tmp = icmp slt i32 %x, 0 + %retval = select i1 %tmp, i32 -1, i32 0 ret i32 %retval +; CHECK: @test20 +; CHECK-NEXT: ashr i32 %x, 31 +; CHECK-NEXT: ret i32 } define i64 @test21(i32 %x) { - %tmp = icmp slt i32 %x, 0 ; <i1> [#uses=1] - %retval = select i1 %tmp, i64 -1, i64 0 ; <i64> [#uses=1] + %tmp = icmp slt i32 %x, 0 + %retval = select i1 %tmp, i64 -1, i64 0 ret i64 %retval +; CHECK: @test21 +; CHECK-NEXT: ashr i32 %x, 31 +; CHECK-NEXT: sext i32 +; CHECK-NEXT: ret i64 } define i16 @test22(i32 %x) { - %tmp = icmp slt i32 %x, 0 ; <i1> [#uses=1] - %retval = select i1 %tmp, i16 -1, i16 0 ; <i16> [#uses=1] + %tmp = icmp slt i32 %x, 0 + %retval = select i1 %tmp, i16 -1, i16 0 ret i16 %retval +; CHECK: @test22 +; CHECK-NEXT: ashr i32 %x, 31 +; CHECK-NEXT: trunc i32 +; CHECK-NEXT: ret i16 } define i1 @test23(i1 %a, i1 %b) { - %c = select i1 %a, i1 %b, i1 %a ; <i1> [#uses=1] + %c = select i1 %a, i1 %b, i1 %a ret i1 %c +; CHECK: @test23 +; CHECK-NEXT: %c = and i1 %a, %b +; CHECK-NEXT: ret i1 %c } define i1 @test24(i1 %a, i1 %b) { - %c = select i1 %a, i1 %a, i1 %b ; <i1> [#uses=1] + %c = select i1 %a, i1 %a, i1 %b ret i1 %c +; CHECK: @test24 +; CHECK-NEXT: %c = or i1 %a, %b +; CHECK-NEXT: ret i1 %c } define i32 @test25(i1 %c) { @@ -211,6 +315,9 @@ ret: %a = phi i1 [true, %jump], [false, %entry] %b = select i1 %a, i32 10, i32 20 ret i32 %b +; CHECK: @test25 +; CHECK: %a = phi i32 [ 10, %jump ], [ 20, %entry ] +; CHECK-NEXT: ret i32 %a } define i32 @test26(i1 %cond) { @@ -223,6 +330,9 @@ ret: %a = phi i1 [true, %jump], [%c, %entry] %b = select i1 %a, i32 10, i32 20 ret i32 %b +; CHECK: @test26 +; CHECK: %a = phi i32 [ 10, %jump ], [ 20, %entry ] +; CHECK-NEXT: ret i32 %a } define i32 @test27(i1 %c, i32 %A, i32 %B) { @@ -234,6 +344,9 @@ ret: %a = phi i1 [true, %jump], [false, %entry] %b = select i1 %a, i32 %A, i32 %B ret i32 %b +; CHECK: @test27 +; CHECK: %a = phi i32 [ %A, %jump ], [ %B, %entry ] +; CHECK-NEXT: ret i32 %a } define i32 @test28(i1 %cond, i32 %A, i32 %B) { @@ -246,6 +359,9 @@ ret: %a = phi i1 [true, %jump], [false, %entry] %b = select i1 %a, i32 %A, i32 %c ret i32 %b +; CHECK: @test28 +; CHECK: %a = phi i32 [ %A, %jump ], [ %B, %entry ] +; CHECK-NEXT: ret i32 %a } define i32 @test29(i1 %cond, i32 %A, i32 %B) { @@ -261,5 +377,64 @@ ret: next: %b = select i1 %a, i32 %A, i32 %c ret i32 %b +; CHECK: @test29 +; CHECK: %a = phi i32 [ %A, %jump ], [ %B, %entry ] +; CHECK: ret i32 %a } + +; SMAX(SMAX(x, y), x) -> SMAX(x, y) +define i32 @test30(i32 %x, i32 %y) { + %cmp = icmp sgt i32 %x, %y + %cond = select i1 %cmp, i32 %x, i32 %y + + %cmp5 = icmp sgt i32 %cond, %x + %retval = select i1 %cmp5, i32 %cond, i32 %x + ret i32 %retval +; CHECK: @test30 +; CHECK: ret i32 %cond +} + +; UMAX(UMAX(x, y), x) -> UMAX(x, y) +define i32 @test31(i32 %x, i32 %y) { + %cmp = icmp ugt i32 %x, %y + %cond = select i1 %cmp, i32 %x, i32 %y + %cmp5 = icmp ugt i32 %cond, %x + %retval = select i1 %cmp5, i32 %cond, i32 %x + ret i32 %retval +; CHECK: @test31 +; CHECK: ret i32 %cond +} + +; SMIN(SMIN(x, y), x) -> SMIN(x, y) +define i32 @test32(i32 %x, i32 %y) { + %cmp = icmp sgt i32 %x, %y + %cond = select i1 %cmp, i32 %y, i32 %x + %cmp5 = icmp sgt i32 %cond, %x + %retval = select i1 %cmp5, i32 %x, i32 %cond + ret i32 %retval +; CHECK: @test32 +; CHECK: ret i32 %cond +} + +; MAX(MIN(x, y), x) -> x +define i32 @test33(i32 %x, i32 %y) { + %cmp = icmp sgt i32 %x, %y + %cond = select i1 %cmp, i32 %y, i32 %x + %cmp5 = icmp sgt i32 %cond, %x + %retval = select i1 %cmp5, i32 %cond, i32 %x + ret i32 %retval +; CHECK: @test33 +; CHECK: ret i32 %x +} + +; MIN(MAX(x, y), x) -> x +define i32 @test34(i32 %x, i32 %y) { + %cmp = icmp sgt i32 %x, %y + %cond = select i1 %cmp, i32 %x, i32 %y + %cmp5 = icmp sgt i32 %cond, %x + %retval = select i1 %cmp5, i32 %x, i32 %cond + ret i32 %retval +; CHECK: @test34 +; CHECK: ret i32 %x +} diff --git a/test/Transforms/LoopRotate/phi-duplicate.ll b/test/Transforms/LoopRotate/phi-duplicate.ll new file mode 100644 index 0000000000000..cac00f826bd2e --- /dev/null +++ b/test/Transforms/LoopRotate/phi-duplicate.ll @@ -0,0 +1,35 @@ +; RUN: opt -S %s -loop-rotate | FileCheck %s +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" +target triple = "x86_64-apple-darwin10.0" + +; PR5837 +define void @test(i32 %N, double* %G) nounwind ssp { +entry: + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %j.0 = phi i64 [ 1, %entry ], [ %inc, %for.body ] ; <i64> [#uses=5] + %cmp = icmp slt i64 %j.0, 1000 ; <i1> [#uses=1] + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %arrayidx = getelementptr inbounds double* %G, i64 %j.0 ; <double*> [#uses=1] + %tmp3 = load double* %arrayidx ; <double> [#uses=1] + %sub = sub i64 %j.0, 1 ; <i64> [#uses=1] + %arrayidx6 = getelementptr inbounds double* %G, i64 %sub ; <double*> [#uses=1] + %tmp7 = load double* %arrayidx6 ; <double> [#uses=1] + %add = fadd double %tmp3, %tmp7 ; <double> [#uses=1] + %arrayidx10 = getelementptr inbounds double* %G, i64 %j.0 ; <double*> [#uses=1] + store double %add, double* %arrayidx10 + %inc = add nsw i64 %j.0, 1 ; <i64> [#uses=1] + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} +; Should only end up with one phi. +; CHECK: for.body: +; CHECK-NEXT: %j.02 = phi i64 +; CHECK-NOT phi +; CHECK: ret void + diff --git a/test/Transforms/Reassociate/basictest.ll b/test/Transforms/Reassociate/basictest.ll index eca2d6310d34c..e77d83d160e40 100644 --- a/test/Transforms/Reassociate/basictest.ll +++ b/test/Transforms/Reassociate/basictest.ll @@ -1,10 +1,206 @@ ; With reassociation, constant folding can eliminate the 12 and -12 constants. ; -; RUN: opt < %s -reassociate -constprop -instcombine -die -S | not grep add +; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s -define i32 @test(i32 %arg) { - %tmp1 = sub i32 -12, %arg ; <i32> [#uses=1] - %tmp2 = add i32 %tmp1, 12 ; <i32> [#uses=1] +define i32 @test1(i32 %arg) { + %tmp1 = sub i32 -12, %arg + %tmp2 = add i32 %tmp1, 12 ret i32 %tmp2 +; CHECK: @test1 +; CHECK-NEXT: sub i32 0, %arg +; CHECK-NEXT: ret i32 } +define i32 @test2(i32 %reg109, i32 %reg1111) { + %reg115 = add i32 %reg109, -30 ; <i32> [#uses=1] + %reg116 = add i32 %reg115, %reg1111 ; <i32> [#uses=1] + %reg117 = add i32 %reg116, 30 ; <i32> [#uses=1] + ret i32 %reg117 +; CHECK: @test2 +; CHECK-NEXT: add i32 %reg1111, %reg109 +; CHECK-NEXT: ret i32 +} + +@e = external global i32 ; <i32*> [#uses=3] +@a = external global i32 ; <i32*> [#uses=3] +@b = external global i32 ; <i32*> [#uses=3] +@c = external global i32 ; <i32*> [#uses=3] +@f = external global i32 ; <i32*> [#uses=3] + +define void @test3() { + %A = load i32* @a ; <i32> [#uses=2] + %B = load i32* @b ; <i32> [#uses=2] + %C = load i32* @c ; <i32> [#uses=2] + %t1 = add i32 %A, %B ; <i32> [#uses=1] + %t2 = add i32 %t1, %C ; <i32> [#uses=1] + %t3 = add i32 %C, %A ; <i32> [#uses=1] + %t4 = add i32 %t3, %B ; <i32> [#uses=1] + ; e = (a+b)+c; + store i32 %t2, i32* @e + ; f = (a+c)+b + store i32 %t4, i32* @f + ret void +; CHECK: @test3 +; CHECK: add i32 +; CHECK: add i32 +; CHECK-NOT: add i32 +; CHECK: ret void +} + +define void @test4() { + %A = load i32* @a ; <i32> [#uses=2] + %B = load i32* @b ; <i32> [#uses=2] + %C = load i32* @c ; <i32> [#uses=2] + %t1 = add i32 %A, %B ; <i32> [#uses=1] + %t2 = add i32 %t1, %C ; <i32> [#uses=1] + %t3 = add i32 %C, %A ; <i32> [#uses=1] + %t4 = add i32 %t3, %B ; <i32> [#uses=1] + ; e = c+(a+b) + store i32 %t2, i32* @e + ; f = (c+a)+b + store i32 %t4, i32* @f + ret void +; CHECK: @test4 +; CHECK: add i32 +; CHECK: add i32 +; CHECK-NOT: add i32 +; CHECK: ret void +} + +define void @test5() { + %A = load i32* @a ; <i32> [#uses=2] + %B = load i32* @b ; <i32> [#uses=2] + %C = load i32* @c ; <i32> [#uses=2] + %t1 = add i32 %B, %A ; <i32> [#uses=1] + %t2 = add i32 %t1, %C ; <i32> [#uses=1] + %t3 = add i32 %C, %A ; <i32> [#uses=1] + %t4 = add i32 %t3, %B ; <i32> [#uses=1] + ; e = c+(b+a) + store i32 %t2, i32* @e + ; f = (c+a)+b + store i32 %t4, i32* @f + ret void +; CHECK: @test5 +; CHECK: add i32 +; CHECK: add i32 +; CHECK-NOT: add i32 +; CHECK: ret void +} + +define i32 @test6() { + %tmp.0 = load i32* @a + %tmp.1 = load i32* @b + ; (a+b) + %tmp.2 = add i32 %tmp.0, %tmp.1 + %tmp.4 = load i32* @c + ; (a+b)+c + %tmp.5 = add i32 %tmp.2, %tmp.4 + ; (a+c) + %tmp.8 = add i32 %tmp.0, %tmp.4 + ; (a+c)+b + %tmp.11 = add i32 %tmp.8, %tmp.1 + ; X ^ X = 0 + %RV = xor i32 %tmp.5, %tmp.11 + ret i32 %RV +; CHECK: @test6 +; CHECK: ret i32 0 +} + +; This should be one add and two multiplies. +define i32 @test7(i32 %A, i32 %B, i32 %C) { + ; A*A*B + A*C*A + %aa = mul i32 %A, %A + %aab = mul i32 %aa, %B + %ac = mul i32 %A, %C + %aac = mul i32 %ac, %A + %r = add i32 %aab, %aac + ret i32 %r +; CHECK: @test7 +; CHECK-NEXT: add i32 %C, %B +; CHECK-NEXT: mul i32 +; CHECK-NEXT: mul i32 +; CHECK-NEXT: ret i32 +} + + +define i32 @test8(i32 %X, i32 %Y, i32 %Z) { + %A = sub i32 0, %X + %B = mul i32 %A, %Y + ; (-X)*Y + Z -> Z-X*Y + %C = add i32 %B, %Z + ret i32 %C +; CHECK: @test8 +; CHECK-NEXT: %A = mul i32 %Y, %X +; CHECK-NEXT: %C = sub i32 %Z, %A +; CHECK-NEXT: ret i32 %C +} + + +; PR5458 +define i32 @test9(i32 %X) { + %Y = mul i32 %X, 47 + %Z = add i32 %Y, %Y + ret i32 %Z +; CHECK: @test9 +; CHECK-NEXT: mul i32 %X, 94 +; CHECK-NEXT: ret i32 +} + +define i32 @test10(i32 %X) { + %Y = add i32 %X ,%X + %Z = add i32 %Y, %X + ret i32 %Z +; CHECK: @test10 +; CHECK-NEXT: mul i32 %X, 3 +; CHECK-NEXT: ret i32 +} + +define i32 @test11(i32 %W) { + %X = mul i32 %W, 127 + %Y = add i32 %X ,%X + %Z = add i32 %Y, %X + ret i32 %Z +; CHECK: @test11 +; CHECK-NEXT: mul i32 %W, 381 +; CHECK-NEXT: ret i32 +} + +define i32 @test12(i32 %X) { + %A = sub i32 1, %X + %B = sub i32 2, %X + %C = sub i32 3, %X + + %Y = add i32 %A ,%B + %Z = add i32 %Y, %C + ret i32 %Z +; CHECK: @test12 +; CHECK-NEXT: mul i32 %X, -3 +; CHECK-NEXT: add i32{{.*}}, 6 +; CHECK-NEXT: ret i32 +} + +define i32 @test13(i32 %X1, i32 %X2, i32 %X3) { + %A = sub i32 0, %X1 + %B = mul i32 %A, %X2 ; -X1*X2 + %C = mul i32 %X1, %X3 ; X1*X3 + %D = add i32 %B, %C ; -X1*X2 + X1*X3 -> X1*(X3-X2) + ret i32 %D +; CHECK: @test13 +; CHECK-NEXT: sub i32 %X3, %X2 +; CHECK-NEXT: mul i32 {{.*}}, %X1 +; CHECK-NEXT: ret i32 +} + +; PR5359 +define i32 @test14(i32 %X1, i32 %X2) { + %B = mul i32 %X1, 47 ; X1*47 + %C = mul i32 %X2, -47 ; X2*-47 + %D = add i32 %B, %C ; X1*47 + X2*-47 -> 47*(X1-X2) + ret i32 %D +; CHECK: @test14 +; CHECK-NEXT: sub i32 %X1, %X2 +; CHECK-NEXT: mul i32 {{.*}}, 47 +; CHECK-NEXT: ret i32 +} + + diff --git a/test/Transforms/Reassociate/basictest2.ll b/test/Transforms/Reassociate/basictest2.ll deleted file mode 100644 index ba1ff9ec73fd2..0000000000000 --- a/test/Transforms/Reassociate/basictest2.ll +++ /dev/null @@ -1,11 +0,0 @@ -; With reassociation, constant folding can eliminate the +/- 30 constants. -; -; RUN: opt < %s -reassociate -constprop -instcombine -die -S | not grep 30 - -define i32 @test(i32 %reg109, i32 %reg1111) { - %reg115 = add i32 %reg109, -30 ; <i32> [#uses=1] - %reg116 = add i32 %reg115, %reg1111 ; <i32> [#uses=1] - %reg117 = add i32 %reg116, 30 ; <i32> [#uses=1] - ret i32 %reg117 -} - diff --git a/test/Transforms/Reassociate/basictest3.ll b/test/Transforms/Reassociate/basictest3.ll deleted file mode 100644 index 92285fbbb63e3..0000000000000 --- a/test/Transforms/Reassociate/basictest3.ll +++ /dev/null @@ -1,54 +0,0 @@ -; RUN: opt < %s -reassociate -gvn -S | grep add | count 6 -; Each of these functions should turn into two adds each. - -@e = external global i32 ; <i32*> [#uses=3] -@a = external global i32 ; <i32*> [#uses=3] -@b = external global i32 ; <i32*> [#uses=3] -@c = external global i32 ; <i32*> [#uses=3] -@f = external global i32 ; <i32*> [#uses=3] - -define void @test1() { - %A = load i32* @a ; <i32> [#uses=2] - %B = load i32* @b ; <i32> [#uses=2] - %C = load i32* @c ; <i32> [#uses=2] - %t1 = add i32 %A, %B ; <i32> [#uses=1] - %t2 = add i32 %t1, %C ; <i32> [#uses=1] - %t3 = add i32 %C, %A ; <i32> [#uses=1] - %t4 = add i32 %t3, %B ; <i32> [#uses=1] - ; e = (a+b)+c; - store i32 %t2, i32* @e - ; f = (a+c)+b - store i32 %t4, i32* @f - ret void -} - -define void @test2() { - %A = load i32* @a ; <i32> [#uses=2] - %B = load i32* @b ; <i32> [#uses=2] - %C = load i32* @c ; <i32> [#uses=2] - %t1 = add i32 %A, %B ; <i32> [#uses=1] - %t2 = add i32 %t1, %C ; <i32> [#uses=1] - %t3 = add i32 %C, %A ; <i32> [#uses=1] - %t4 = add i32 %t3, %B ; <i32> [#uses=1] - ; e = c+(a+b) - store i32 %t2, i32* @e - ; f = (c+a)+b - store i32 %t4, i32* @f - ret void -} - -define void @test3() { - %A = load i32* @a ; <i32> [#uses=2] - %B = load i32* @b ; <i32> [#uses=2] - %C = load i32* @c ; <i32> [#uses=2] - %t1 = add i32 %B, %A ; <i32> [#uses=1] - %t2 = add i32 %t1, %C ; <i32> [#uses=1] - %t3 = add i32 %C, %A ; <i32> [#uses=1] - %t4 = add i32 %t3, %B ; <i32> [#uses=1] - ; e = c+(b+a) - store i32 %t2, i32* @e - ; f = (c+a)+b - store i32 %t4, i32* @f - ret void -} - diff --git a/test/Transforms/Reassociate/basictest4.ll b/test/Transforms/Reassociate/basictest4.ll deleted file mode 100644 index 88dbdf781504e..0000000000000 --- a/test/Transforms/Reassociate/basictest4.ll +++ /dev/null @@ -1,23 +0,0 @@ -; RUN: opt < %s -reassociate -gvn -instcombine -S | not grep add - -@a = weak global i32 0 ; <i32*> [#uses=1] -@b = weak global i32 0 ; <i32*> [#uses=1] -@c = weak global i32 0 ; <i32*> [#uses=1] -@d = weak global i32 0 ; <i32*> [#uses=0] - -define i32 @foo() { - %tmp.0 = load i32* @a ; <i32> [#uses=2] - %tmp.1 = load i32* @b ; <i32> [#uses=2] - ; (a+b) - %tmp.2 = add i32 %tmp.0, %tmp.1 ; <i32> [#uses=1] - %tmp.4 = load i32* @c ; <i32> [#uses=2] - ; (a+b)+c - %tmp.5 = add i32 %tmp.2, %tmp.4 ; <i32> [#uses=1] - ; (a+c) - %tmp.8 = add i32 %tmp.0, %tmp.4 ; <i32> [#uses=1] - ; (a+c)+b - %tmp.11 = add i32 %tmp.8, %tmp.1 ; <i32> [#uses=1] - ; X ^ X = 0 - %RV = xor i32 %tmp.5, %tmp.11 ; <i32> [#uses=1] - ret i32 %RV -} diff --git a/test/Transforms/Reassociate/mul-factor3.ll b/test/Transforms/Reassociate/mul-factor3.ll deleted file mode 100644 index 4d0517618e00e..0000000000000 --- a/test/Transforms/Reassociate/mul-factor3.ll +++ /dev/null @@ -1,15 +0,0 @@ -; This should be one add and two multiplies. - -; RUN: opt < %s -reassociate -instcombine -S > %t -; RUN: grep mul %t | count 2 -; RUN: grep add %t | count 1 - -define i32 @test(i32 %A, i32 %B, i32 %C) { - %aa = mul i32 %A, %A ; <i32> [#uses=1] - %aab = mul i32 %aa, %B ; <i32> [#uses=1] - %ac = mul i32 %A, %C ; <i32> [#uses=1] - %aac = mul i32 %ac, %A ; <i32> [#uses=1] - %r = add i32 %aab, %aac ; <i32> [#uses=1] - ret i32 %r -} - diff --git a/test/Transforms/Reassociate/mul-neg-add.ll b/test/Transforms/Reassociate/mul-neg-add.ll deleted file mode 100644 index dd6ddd9b62ec3..0000000000000 --- a/test/Transforms/Reassociate/mul-neg-add.ll +++ /dev/null @@ -1,10 +0,0 @@ -; RUN: opt < %s -reassociate -instcombine -S |\ -; RUN: not grep {sub i32 0} - -define i32 @test(i32 %X, i32 %Y, i32 %Z) { - %A = sub i32 0, %X ; <i32> [#uses=1] - %B = mul i32 %A, %Y ; <i32> [#uses=1] - ; (-X)*Y + Z -> Z-X*Y - %C = add i32 %B, %Z ; <i32> [#uses=1] - ret i32 %C -} diff --git a/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll b/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll new file mode 100644 index 0000000000000..71f66d67b94db --- /dev/null +++ b/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll @@ -0,0 +1,89 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +; Radar 7441282 + +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10" + +%struct.__neon_int16x8x2_t = type { <8 x i16>, <8 x i16> } +%struct.int16x8_t = type { <8 x i16> } +%struct.int16x8x2_t = type { [2 x %struct.int16x8_t] } +%union..0anon = type { %struct.int16x8x2_t } + +define arm_apcscc void @test(<8 x i16> %tmp.0, %struct.int16x8x2_t* %dst) nounwind { +; CHECK: @test +; CHECK-NOT: alloca +; CHECK: "alloca point" +entry: + %tmp_addr = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=3] + %dst_addr = alloca %struct.int16x8x2_t* ; <%struct.int16x8x2_t**> [#uses=2] + %__rv = alloca %union..0anon ; <%union..0anon*> [#uses=2] + %__bx = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=2] + %__ax = alloca %struct.int16x8_t ; <%struct.int16x8_t*> [#uses=2] + %tmp2 = alloca %struct.int16x8x2_t ; <%struct.int16x8x2_t*> [#uses=2] + %0 = alloca %struct.int16x8x2_t ; <%struct.int16x8x2_t*> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + %1 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + store <8 x i16> %tmp.0, <8 x i16>* %1 + store %struct.int16x8x2_t* %dst, %struct.int16x8x2_t** %dst_addr + %2 = getelementptr inbounds %struct.int16x8_t* %__ax, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %3 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %4 = load <8 x i16>* %3, align 16 ; <<8 x i16>> [#uses=1] + store <8 x i16> %4, <8 x i16>* %2, align 16 + %5 = getelementptr inbounds %struct.int16x8_t* %__bx, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %6 = getelementptr inbounds %struct.int16x8_t* %tmp_addr, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %7 = load <8 x i16>* %6, align 16 ; <<8 x i16>> [#uses=1] + store <8 x i16> %7, <8 x i16>* %5, align 16 + %8 = getelementptr inbounds %struct.int16x8_t* %__ax, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %9 = load <8 x i16>* %8, align 16 ; <<8 x i16>> [#uses=2] + %10 = getelementptr inbounds %struct.int16x8_t* %__bx, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + %11 = load <8 x i16>* %10, align 16 ; <<8 x i16>> [#uses=2] + %12 = getelementptr inbounds %union..0anon* %__rv, i32 0, i32 0 ; <%struct.int16x8x2_t*> [#uses=1] + %13 = bitcast %struct.int16x8x2_t* %12 to %struct.__neon_int16x8x2_t* ; <%struct.__neon_int16x8x2_t*> [#uses=2] + %14 = shufflevector <8 x i16> %9, <8 x i16> %11, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14> ; <<8 x i16>> [#uses=1] + %15 = getelementptr inbounds %struct.__neon_int16x8x2_t* %13, i32 0, i32 0 ; <<8 x i16>*> [#uses=1] + store <8 x i16> %14, <8 x i16>* %15 + %16 = shufflevector <8 x i16> %9, <8 x i16> %11, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15> ; <<8 x i16>> [#uses=1] + %17 = getelementptr inbounds %struct.__neon_int16x8x2_t* %13, i32 0, i32 1 ; <<8 x i16>*> [#uses=1] + store <8 x i16> %16, <8 x i16>* %17 + %18 = getelementptr inbounds %union..0anon* %__rv, i32 0, i32 0 ; <%struct.int16x8x2_t*> [#uses=1] + %19 = bitcast %struct.int16x8x2_t* %0 to i8* ; <i8*> [#uses=1] + %20 = bitcast %struct.int16x8x2_t* %18 to i8* ; <i8*> [#uses=1] + call void @llvm.memcpy.i32(i8* %19, i8* %20, i32 32, i32 16) + %tmp21 = bitcast %struct.int16x8x2_t* %tmp2 to i8* ; <i8*> [#uses=1] + %21 = bitcast %struct.int16x8x2_t* %0 to i8* ; <i8*> [#uses=1] + call void @llvm.memcpy.i32(i8* %tmp21, i8* %21, i32 32, i32 16) + %22 = load %struct.int16x8x2_t** %dst_addr, align 4 ; <%struct.int16x8x2_t*> [#uses=1] + %23 = bitcast %struct.int16x8x2_t* %22 to i8* ; <i8*> [#uses=1] + %tmp22 = bitcast %struct.int16x8x2_t* %tmp2 to i8* ; <i8*> [#uses=1] + call void @llvm.memcpy.i32(i8* %23, i8* %tmp22, i32 32, i32 16) + br label %return + +; CHECK: store <8 x i16> +; CHECK: store <8 x i16> + +return: ; preds = %entry + ret void +} + +; Radar 7466574 +%struct._NSRange = type { i64 } + +define arm_apcscc void @test_memcpy_self() nounwind { +; CHECK: @test_memcpy_self +; CHECK-NOT: alloca +; CHECK: br i1 +entry: + %range = alloca %struct._NSRange ; <%struct._NSRange*> [#uses=2] + br i1 undef, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %tmp3 = bitcast %struct._NSRange* %range to i8* ; <i8*> [#uses=1] + %tmp4 = bitcast %struct._NSRange* %range to i8* ; <i8*> [#uses=1] + call void @llvm.memcpy.i32(i8* %tmp3, i8* %tmp4, i32 8, i32 8) + ret void + +cond.false: ; preds = %entry + ret void +} + +declare void @llvm.memcpy.i32(i8* nocapture, i8* nocapture, i32, i32) nounwind diff --git a/test/Transforms/ScalarRepl/nonzero-first-index.ll b/test/Transforms/ScalarRepl/nonzero-first-index.ll new file mode 100644 index 0000000000000..60f414b717578 --- /dev/null +++ b/test/Transforms/ScalarRepl/nonzero-first-index.ll @@ -0,0 +1,53 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i386-pc-linux-gnu" + +%nested = type { i32, [4 x i32] } + +; Check that a GEP with a non-zero first index does not prevent SROA as long +; as the resulting offset corresponds to an element in the alloca. +define i32 @test1() { +; CHECK: @test1 +; CHECK-NOT: = i160 +; CHECK: ret i32 undef + %A = alloca %nested + %B = getelementptr %nested* %A, i32 0, i32 1, i32 0 + %C = getelementptr i32* %B, i32 2 + %D = load i32* %C + ret i32 %D +} + +; But, if the offset is out of range, then it should not be transformed. +define i32 @test2() { +; CHECK: @test2 +; CHECK: i160 + %A = alloca %nested + %B = getelementptr %nested* %A, i32 0, i32 1, i32 0 + %C = getelementptr i32* %B, i32 4 + %D = load i32* %C + ret i32 %D +} + +; Try it with a bitcast and single GEP.... +define i32 @test3() { +; CHECK: @test3 +; CHECK-NOT: = i160 +; CHECK: ret i32 undef + %A = alloca %nested + %B = bitcast %nested* %A to i32* + %C = getelementptr i32* %B, i32 2 + %D = load i32* %C + ret i32 %D +} + +; ...and again make sure that out-of-range accesses are not transformed. +define i32 @test4() { +; CHECK: @test4 +; CHECK: i160 + %A = alloca %nested + %B = bitcast %nested* %A to i32* + %C = getelementptr i32* %B, i32 -1 + %D = load i32* %C + ret i32 %D +} diff --git a/test/Transforms/SimplifyCFG/basictest.ll b/test/Transforms/SimplifyCFG/basictest.ll index a829e030e21d0..83a9fa7ad1b8d 100644 --- a/test/Transforms/SimplifyCFG/basictest.ll +++ b/test/Transforms/SimplifyCFG/basictest.ll @@ -1,30 +1,59 @@ -; Test CFG simplify removal of branch instructions... +; Test CFG simplify removal of branch instructions. ; -; RUN: opt < %s -simplifycfg -S | not grep br +; RUN: opt < %s -simplifycfg -S | FileCheck %s define void @test1() { br label %BB1 BB1: ; preds = %0 ret void +; CHECK: @test1 +; CHECK-NEXT: ret void } define void @test2() { ret void BB1: ; No predecessors! ret void +; CHECK: @test2 +; CHECK-NEXT: ret void +; CHECK-NEXT: } } define void @test3(i1 %T) { br i1 %T, label %BB1, label %BB1 BB1: ; preds = %0, %0 ret void +; CHECK: @test3 +; CHECK-NEXT: ret void } define void @test4() { -entry: - br label %return + br label %return return: - ret void + ret void +; CHECK: @test4 +; CHECK-NEXT: ret void } @test4g = global i8* blockaddress(@test4, %return) + + +; PR5795 +define void @test5(i32 %A) { + switch i32 %A, label %return [ + i32 2, label %bb + i32 10, label %bb1 + ] + +bb: ; preds = %entry + ret void + +bb1: ; preds = %entry + ret void + +return: ; preds = %entry + ret void +; CHECK: @test5 +; CHECK-NEXT: bb: +; CHECK-NEXT: ret void +} diff --git a/test/Transforms/SimplifyCFG/duplicate-phis.ll b/test/Transforms/SimplifyCFG/duplicate-phis.ll index a1e5113980047..5129f9fb6d2f6 100644 --- a/test/Transforms/SimplifyCFG/duplicate-phis.ll +++ b/test/Transforms/SimplifyCFG/duplicate-phis.ll @@ -6,7 +6,7 @@ define i32 @foo(i1 %t) { entry: call void @bar() - br i1 %t, label %true, label %false, + br i1 %t, label %true, label %false true: call void @bar() br label %false diff --git a/test/Transforms/SimplifyLibCalls/StrStr.ll b/test/Transforms/SimplifyLibCalls/StrStr.ll new file mode 100644 index 0000000000000..2cac2d498ce78 --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/StrStr.ll @@ -0,0 +1,48 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s +; PR5783 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin9.0" + +@.str = private constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@.str1 = private constant [2 x i8] c"a\00" ; <[2 x i8]*> [#uses=1] +@.str2 = private constant [6 x i8] c"abcde\00" ; <[6 x i8]*> [#uses=1] +@.str3 = private constant [4 x i8] c"bcd\00" ; <[4 x i8]*> [#uses=1] + +define i8* @test1(i8* %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* getelementptr inbounds ([1 x i8]* @.str, i32 0, i32 0)) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr(P, "") -> P +; CHECK: @test1 +; CHECK: ret i8* %P +} + +declare i8* @strstr(i8*, i8* nocapture) nounwind readonly + +define i8* @test2(i8* %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0)) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr(P, "a") -> strchr(P, 'a') +; CHECK: @test2 +; CHECK: @strchr(i8* %P, i32 97) +} + +define i8* @test3(i8* nocapture %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8]* @.str3, i32 0, i32 0)) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr("abcde", "bcd") -> "abcde"+1 +; CHECK: @test3 +; CHECK: getelementptr inbounds ([6 x i8]* @.str2, i32 0, i64 1) +} + +define i8* @test4(i8* %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* %P) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr(P, P) -> P +; CHECK: @test4 +; CHECK: ret i8* %P +} diff --git a/test/Transforms/SimplifyLibCalls/memcmp.ll b/test/Transforms/SimplifyLibCalls/memcmp.ll index ed7bcac467d6b..640d232a7f0c0 100644 --- a/test/Transforms/SimplifyLibCalls/memcmp.ll +++ b/test/Transforms/SimplifyLibCalls/memcmp.ll @@ -14,9 +14,6 @@ define void @test(i8* %P, i8* %Q, i32 %N, i32* %IP, i1* %BP) { volatile store i32 %B, i32* %IP %C = call i32 @memcmp( i8* %P, i8* %Q, i32 1 ) ; <i32> [#uses=1] volatile store i32 %C, i32* %IP - %D = call i32 @memcmp( i8* %P, i8* %Q, i32 2 ) ; <i32> [#uses=1] - %E = icmp eq i32 %D, 0 ; <i1> [#uses=1] - volatile store i1 %E, i1* %BP %F = call i32 @memcmp(i8* getelementptr ([4 x i8]* @hel, i32 0, i32 0), i8* getelementptr ([8 x i8]* @hello_u, i32 0, i32 0), i32 3) |