diff options
Diffstat (limited to 'test/Transforms/InstCombine')
32 files changed, 596 insertions, 135 deletions
diff --git a/test/Transforms/InstCombine/2007-04-04-BadFoldBitcastIntoMalloc.ll b/test/Transforms/InstCombine/2007-04-04-BadFoldBitcastIntoMalloc.ll deleted file mode 100644 index b59d3c8..0000000 --- a/test/Transforms/InstCombine/2007-04-04-BadFoldBitcastIntoMalloc.ll +++ /dev/null @@ -1,19 +0,0 @@ -; In the presence of a negative offset (the -8 below), a fold of a bitcast into -; a malloc messes up the element count, causing an extra 4GB to be allocated on -; 64-bit targets. -; -; RUN: opt < %s -instcombine -S | not grep {= add } - -target datalayout = "e-p:64:64:64-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" -target triple = "x86_64-unknown-freebsd6.2" - -define i1 @test(i32 %tmp141, double** %tmp145) -{ - %tmp133 = add i32 %tmp141, 1 - %tmp134 = shl i32 %tmp133, 3 - %tmp135 = add i32 %tmp134, -8 - %tmp136 = malloc i8, i32 %tmp135 - %tmp137 = bitcast i8* %tmp136 to double* - store double* %tmp137, double** %tmp145 - ret i1 false -} diff --git a/test/Transforms/InstCombine/2007-05-18-CastFoldBug.ll b/test/Transforms/InstCombine/2007-05-18-CastFoldBug.ll index 40818d4..1c24df3 100644 --- a/test/Transforms/InstCombine/2007-05-18-CastFoldBug.ll +++ b/test/Transforms/InstCombine/2007-05-18-CastFoldBug.ll @@ -3,7 +3,7 @@ define void @blah(i16* %tmp10) { entry: - call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend_stret to void (i16* sret )*)( i16* %tmp10 sret ) + call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend_stret to void (i16* sret )*)( i16* sret %tmp10 ) ret void } diff --git a/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll b/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll index 24394c6..2109d34 100644 --- a/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll +++ b/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll @@ -5,7 +5,7 @@ define i32 @main(i32 %argc, i8** %argv) { entry: - %tmp32 = tail call i32 (i8* noalias , ...) nounwind * bitcast (i32 (i8*, ...) nounwind * @printf to i32 (i8* noalias , ...) nounwind *)( i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0) noalias , i32 0 ) nounwind ; <i32> [#uses=0] + %tmp32 = tail call i32 (i8* noalias , ...) * bitcast (i32 (i8*, ...) nounwind * @printf to i32 (i8* noalias , ...) nounwind *)( i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0) , i32 0 ) nounwind ; <i32> [#uses=0] ret i32 undef } diff --git a/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll b/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll index 5f4fa47..23b6067 100644 --- a/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll +++ b/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll @@ -5,7 +5,7 @@ define void @a() { ret void } -define i32 @b(i32* inreg %x) signext { +define signext i32 @b(i32* inreg %x) { ret i32 0 } diff --git a/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll b/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll index 7b3281f..510a68c 100644 --- a/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll +++ b/test/Transforms/InstCombine/2008-01-13-NoBitCastAttributes.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -instcombine -S | grep bitcast | count 2 -define i32 @b(i32* inreg %x) signext { +define signext i32 @b(i32* inreg %x) { ret i32 0 } diff --git a/test/Transforms/InstCombine/2011-05-02-VectorBoolean.ll b/test/Transforms/InstCombine/2011-05-02-VectorBoolean.ll new file mode 100644 index 0000000..02b64e3 --- /dev/null +++ b/test/Transforms/InstCombine/2011-05-02-VectorBoolean.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -instcombine +; PR9579 + +define <2 x i16> @entry(<2 x i16> %a) nounwind { +entry: + %a.addr = alloca <2 x i16>, align 4 + %.compoundliteral = alloca <2 x i16>, align 4 + store <2 x i16> %a, <2 x i16>* %a.addr, align 4 + %tmp = load <2 x i16>* %a.addr, align 4 + store <2 x i16> zeroinitializer, <2 x i16>* %.compoundliteral + %tmp1 = load <2 x i16>* %.compoundliteral + %cmp = icmp uge <2 x i16> %tmp, %tmp1 + %sext = sext <2 x i1> %cmp to <2 x i16> + ret <2 x i16> %sext +} diff --git a/test/Transforms/InstCombine/2011-05-13-InBoundsGEP.ll b/test/Transforms/InstCombine/2011-05-13-InBoundsGEP.ll new file mode 100644 index 0000000..fba7239 --- /dev/null +++ b/test/Transforms/InstCombine/2011-05-13-InBoundsGEP.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -S -instcombine | FileCheck %s +; rdar://problem/9267970 +; ideally this test will run on a 32-bit host +; must not discard GEPs that might overflow at runtime (aren't inbounds) + +define i32 @main(i32 %argc) { +entry: + %tmp1 = add i32 %argc, -2 + %tmp2 = add i32 %argc, 1879048192 + %p = alloca i8 +; CHECK: getelementptr + %p1 = getelementptr i8* %p, i32 %tmp1 +; CHECK: getelementptr + %p2 = getelementptr i8* %p, i32 %tmp2 + %cmp = icmp ult i8* %p1, %p2 + br i1 %cmp, label %bbtrue, label %bbfalse +bbtrue: ; preds = %entry + ret i32 -1 +bbfalse: ; preds = %entry + ret i32 0 +} diff --git a/test/Transforms/InstCombine/2011-05-28-swapmulsub.ll b/test/Transforms/InstCombine/2011-05-28-swapmulsub.ll new file mode 100644 index 0000000..b096d1f --- /dev/null +++ b/test/Transforms/InstCombine/2011-05-28-swapmulsub.ll @@ -0,0 +1,57 @@ +; ModuleID = 'test1.c' +; RUN: opt -S -instcombine < %s | FileCheck %s +target triple = "x86_64-apple-macosx10.6.6" + +define zeroext i16 @foo1(i32 %on_off) nounwind uwtable ssp { +entry: + %on_off.addr = alloca i32, align 4 + %a = alloca i32, align 4 + store i32 %on_off, i32* %on_off.addr, align 4 + %tmp = load i32* %on_off.addr, align 4 + %sub = sub i32 1, %tmp +; CHECK-NOT: mul i32 + %mul = mul i32 %sub, -2 +; CHECK: shl +; CHECK-NEXT: add + store i32 %mul, i32* %a, align 4 + %tmp1 = load i32* %a, align 4 + %conv = trunc i32 %tmp1 to i16 + ret i16 %conv +} + +define zeroext i16 @foo2(i32 %on_off, i32 %q) nounwind uwtable ssp { +entry: + %on_off.addr = alloca i32, align 4 + %q.addr = alloca i32, align 4 + %a = alloca i32, align 4 + store i32 %on_off, i32* %on_off.addr, align 4 + store i32 %q, i32* %q.addr, align 4 + %tmp = load i32* %q.addr, align 4 + %tmp1 = load i32* %on_off.addr, align 4 + %sub = sub i32 %tmp, %tmp1 +; CHECK-NOT: mul i32 + %mul = mul i32 %sub, -4 +; CHECK: sub i32 +; CHECK-NEXT: shl + store i32 %mul, i32* %a, align 4 + %tmp2 = load i32* %a, align 4 + %conv = trunc i32 %tmp2 to i16 + ret i16 %conv +} + +define zeroext i16 @foo3(i32 %on_off) nounwind uwtable ssp { +entry: + %on_off.addr = alloca i32, align 4 + %a = alloca i32, align 4 + store i32 %on_off, i32* %on_off.addr, align 4 + %tmp = load i32* %on_off.addr, align 4 + %sub = sub i32 7, %tmp +; CHECK-NOT: mul i32 + %mul = mul i32 %sub, -4 +; CHECK: shl +; CHECK-NEXT: add + store i32 %mul, i32* %a, align 4 + %tmp1 = load i32* %a, align 4 + %conv = trunc i32 %tmp1 to i16 + ret i16 %conv +} diff --git a/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll b/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll new file mode 100644 index 0000000..2f72b73 --- /dev/null +++ b/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll @@ -0,0 +1,60 @@ +; 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:128:128-n8:16:32" +target triple = "i386-apple-darwin10.0.0" + +define void @fu1(i32 %parm) nounwind ssp { + %1 = alloca i32, align 4 + %ptr = alloca double*, align 4 + store i32 %parm, i32* %1, align 4 + store double* null, double** %ptr, align 4 + %2 = load i32* %1, align 4 + %3 = icmp ne i32 %2, 0 + br i1 %3, label %4, label %10 + +; <label>:4 ; preds = %0 + %5 = load i32* %1, align 4 + %6 = mul nsw i32 %5, 8 +; With "nsw", the alloca and its bitcast can be fused: + %7 = add nsw i32 %6, 2048 +; CHECK: alloca double* + %8 = alloca i8, i32 %7 + %9 = bitcast i8* %8 to double* + store double* %9, double** %ptr, align 4 + br label %10 + +; <label>:10 ; preds = %4, %0 + %11 = load double** %ptr, align 4 + call void @bar(double* %11) +; CHECK: ret + ret void +} + +declare void @bar(double*) + +define void @fu2(i32 %parm) nounwind ssp { + %1 = alloca i32, align 4 + %ptr = alloca double*, align 4 + store i32 %parm, i32* %1, align 4 + store double* null, double** %ptr, align 4 + %2 = load i32* %1, align 4 + %3 = icmp ne i32 %2, 0 + br i1 %3, label %4, label %10 + +; <label>:4 ; preds = %0 + %5 = load i32* %1, align 4 + %6 = mul nsw i32 %5, 8 +; Without "nsw", the alloca and its bitcast cannot be fused: + %7 = add i32 %6, 2048 +; CHECK: alloca i8 + %8 = alloca i8, i32 %7 +; CHECK-NEXT: bitcast i8* + %9 = bitcast i8* %8 to double* + store double* %9, double** %ptr, align 4 + br label %10 + +; <label>:10 ; preds = %4, %0 + %11 = load double** %ptr, align 4 + call void @bar(double* %11) + ret void +} + diff --git a/test/Transforms/InstCombine/and-or-not.ll b/test/Transforms/InstCombine/and-or-not.ll index 37ec3bc..bd878b0 100644 --- a/test/Transforms/InstCombine/and-or-not.ll +++ b/test/Transforms/InstCombine/and-or-not.ll @@ -4,7 +4,7 @@ ; PR1510 -; These are all equivelent to A^B +; These are all equivalent to A^B define i32 @test1(i32 %a, i32 %b) { entry: diff --git a/test/Transforms/InstCombine/call.ll b/test/Transforms/InstCombine/call.ll index 2ef8dc0..d084873 100644 --- a/test/Transforms/InstCombine/call.ll +++ b/test/Transforms/InstCombine/call.ll @@ -53,8 +53,8 @@ define i8 @test4a() { define i32 @test4() { %X = call i32 bitcast (i8 ()* @test4a to i32 ()*)( ) ; <i32> [#uses=1] ret i32 %X -; CHECK: %X1 = call i8 @test4a() -; CHECK: %tmp = zext i8 %X1 to i32 +; CHECK: %X = call i8 @test4a() +; CHECK: %tmp = zext i8 %X to i32 ; CHECK: ret i32 %tmp } @@ -77,8 +77,8 @@ declare i32 @test6a(i32) define i32 @test6() { %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( ) ret i32 %X -; CHECK: %X1 = call i32 @test6a(i32 0) -; CHECK: ret i32 %X1 +; CHECK: %X = call i32 @test6a(i32 0) +; CHECK: ret i32 %X } diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index bc5e365..f85636f 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -99,14 +99,6 @@ define void @test11(i32* %P) { ; CHECK: ret void } -define i32* @test12() { - %p = malloc [4 x i8] ; <[4 x i8]*> [#uses=1] - %c = bitcast [4 x i8]* %p to i32* ; <i32*> [#uses=1] - ret i32* %c -; CHECK: %malloccall = tail call i8* @malloc(i32 4) -; CHECK: ret i32* %c -} - define i8* @test13(i64 %A) { %c = getelementptr [0 x i8]* bitcast ([32832 x i8]* @inbuf to [0 x i8]*), i64 0, i64 %A ; <i8*> [#uses=1] ret i8* %c @@ -265,22 +257,11 @@ define i1 @test31(i64 %A) { %C = and i32 %B, 42 ; <i32> [#uses=1] %D = icmp eq i32 %C, 10 ; <i1> [#uses=1] ret i1 %D -; CHECK: %C1 = and i64 %A, 42 -; CHECK: %D = icmp eq i64 %C1, 10 +; CHECK: %C = and i64 %A, 42 +; CHECK: %D = icmp eq i64 %C, 10 ; CHECK: ret i1 %D } -define void @test32(double** %tmp) { - %tmp8 = malloc [16 x i8] ; <[16 x i8]*> [#uses=1] - %tmp8.upgrd.1 = bitcast [16 x i8]* %tmp8 to double* ; <double*> [#uses=1] - store double* %tmp8.upgrd.1, double** %tmp - ret void -; CHECK: %malloccall = tail call i8* @malloc(i32 16) -; CHECK: %tmp8.upgrd.1 = bitcast i8* %malloccall to double* -; CHECK: store double* %tmp8.upgrd.1, double** %tmp -; CHECK: ret void -} - define i32 @test33(i32 %c1) { %x = bitcast i32 %c1 to float ; <float> [#uses=1] %y = bitcast float %x to i32 ; <i32> [#uses=1] diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll index 0d13980..8a0897b 100644 --- a/test/Transforms/InstCombine/div.ll +++ b/test/Transforms/InstCombine/div.ll @@ -1,34 +1,44 @@ ; This test makes sure that div instructions are properly eliminated. -; RUN: opt < %s -instcombine -S | not grep div +; RUN: opt < %s -instcombine -S | FileCheck %s define i32 @test1(i32 %A) { %B = sdiv i32 %A, 1 ; <i32> [#uses=1] ret i32 %B +; CHECK: @test1 +; CHECK-NEXT: ret i32 %A } define i32 @test2(i32 %A) { ; => Shift %B = udiv i32 %A, 8 ; <i32> [#uses=1] ret i32 %B +; CHECK: @test2 +; CHECK-NEXT: lshr i32 %A, 3 } define i32 @test3(i32 %A) { ; => 0, don't need to keep traps %B = sdiv i32 0, %A ; <i32> [#uses=1] ret i32 %B +; CHECK: @test3 +; CHECK-NEXT: ret i32 0 } define i32 @test4(i32 %A) { ; 0-A %B = sdiv i32 %A, -1 ; <i32> [#uses=1] ret i32 %B +; CHECK: @test4 +; CHECK-NEXT: sub i32 0, %A } define i32 @test5(i32 %A) { %B = udiv i32 %A, -16 ; <i32> [#uses=1] %C = udiv i32 %B, -4 ; <i32> [#uses=1] ret i32 %C +; CHECK: @test5 +; CHECK-NEXT: ret i32 0 } define i1 @test6(i32 %A) { @@ -36,6 +46,8 @@ define i1 @test6(i32 %A) { ; A < 123 %C = icmp eq i32 %B, 0 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test6 +; CHECK-NEXT: icmp ult i32 %A, 123 } define i1 @test7(i32 %A) { @@ -43,6 +55,9 @@ define i1 @test7(i32 %A) { ; A >= 20 && A < 30 %C = icmp eq i32 %B, 2 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test7 +; CHECK-NEXT: add i32 %A, -20 +; CHECK-NEXT: icmp ult i32 } define i1 @test8(i8 %A) { @@ -50,6 +65,8 @@ define i1 @test8(i8 %A) { ; A >= 246 %C = icmp eq i8 %B, 2 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test8 +; CHECK-NEXT: icmp ugt i8 %A, -11 } define i1 @test9(i8 %A) { @@ -57,28 +74,61 @@ define i1 @test9(i8 %A) { ; A < 246 %C = icmp ne i8 %B, 2 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test9 +; CHECK-NEXT: icmp ult i8 %A, -10 } define i32 @test10(i32 %X, i1 %C) { %V = select i1 %C, i32 64, i32 8 ; <i32> [#uses=1] %R = udiv i32 %X, %V ; <i32> [#uses=1] ret i32 %R +; CHECK: @test10 +; CHECK-NEXT: select i1 %C, i32 6, i32 3 +; CHECK-NEXT: lshr i32 %X } define i32 @test11(i32 %X, i1 %C) { %A = select i1 %C, i32 1024, i32 32 ; <i32> [#uses=1] %B = udiv i32 %X, %A ; <i32> [#uses=1] ret i32 %B +; CHECK: @test11 +; CHECK-NEXT: select i1 %C, i32 10, i32 5 +; CHECK-NEXT: lshr i32 %X } ; PR2328 define i32 @test12(i32 %x) nounwind { %tmp3 = udiv i32 %x, %x ; 1 ret i32 %tmp3 +; CHECK: @test12 +; CHECK-NEXT: ret i32 1 } define i32 @test13(i32 %x) nounwind { %tmp3 = sdiv i32 %x, %x ; 1 ret i32 %tmp3 +; CHECK: @test13 +; CHECK-NEXT: ret i32 1 } +define i32 @test14(i8 %x) nounwind { + %zext = zext i8 %x to i32 + %div = udiv i32 %zext, 257 ; 0 + ret i32 %div +; CHECK: @test14 +; CHECK-NEXT: ret i32 0 +} + +; PR9814 +define i32 @test15(i32 %a, i32 %b) nounwind { + %shl = shl i32 1, %b + %div = lshr i32 %shl, 2 + %div2 = udiv i32 %a, %div + ret i32 %div2 +; CHECK: @test15 +; CHECK-NEXT: add i32 %b, -2 +; CHECK-NEXT: lshr i32 %a, +; CHECK-NEXT: ret i32 +} + + diff --git a/test/Transforms/InstCombine/exact.ll b/test/Transforms/InstCombine/exact.ll index 58f8b5d..14741e3 100644 --- a/test/Transforms/InstCombine/exact.ll +++ b/test/Transforms/InstCombine/exact.ll @@ -96,6 +96,22 @@ define i1 @ashr_icmp2(i64 %X) nounwind { ret i1 %Z } +; PR9998 +; Make sure we don't transform the ashr here into an sdiv +; CHECK: @pr9998 +; CHECK: = and i32 %V, 1 +; CHECK: %Z = icmp ne +; CHECK: ret i1 %Z +define i1 @pr9998(i32 %V) nounwind { +entry: + %W = shl i32 %V, 31 + %X = ashr exact i32 %W, 31 + %Y = sext i32 %X to i64 + %Z = icmp ugt i64 %Y, 7297771788697658747 + ret i1 %Z +} + + ; CHECK: @udiv_icmp1 ; CHECK: icmp ne i64 %X, 0 define i1 @udiv_icmp1(i64 %X) nounwind { diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index 9e8547b..b869392 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -52,14 +52,6 @@ define void @test5(i8 %B) { ; CHECK: store i8 %B, i8* getelementptr inbounds ([10 x i8]* @Global, i64 0, i64 4) } -define i32* @test6() { - %M = malloc [4 x i32] - %A = getelementptr [4 x i32]* %M, i64 0, i64 0 - %B = getelementptr i32* %A, i64 2 - ret i32* %B -; CHECK: @test6 -; CHECK: getelementptr i8* %malloccall, i64 8 -} define i32* @test7(i32* %I, i64 %C, i64 %D) { %A = getelementptr i32* %I, i64 %C diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 7ba4368..c8f7f81 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -494,3 +494,56 @@ define i1 @test51(i32 %X, i32 %Y) { %C = icmp sgt i32 %B, -1 ret i1 %C } + +; CHECK: @test52 +; CHECK-NEXT: and i32 %x1, 16711935 +; CHECK-NEXT: icmp eq i32 {{.*}}, 4980863 +; CHECK-NEXT: ret i1 +define i1 @test52(i32 %x1) nounwind { + %conv = and i32 %x1, 255 + %cmp = icmp eq i32 %conv, 127 + %tmp2 = lshr i32 %x1, 16 + %tmp3 = trunc i32 %tmp2 to i8 + %cmp15 = icmp eq i8 %tmp3, 76 + + %A = and i1 %cmp, %cmp15 + ret i1 %A +} + +; PR9838 +; CHECK: @test53 +; CHECK-NEXT: ashr exact +; CHECK-NEXT: ashr +; CHECK-NEXT: icmp +define i1 @test53(i32 %a, i32 %b) nounwind { + %x = ashr exact i32 %a, 30 + %y = ashr i32 %b, 30 + %z = icmp eq i32 %x, %y + ret i1 %z +} + +; CHECK: @test54 +; CHECK-NEXT: %and = and i8 %a, -64 +; CHECK-NEXT icmp eq i8 %and, -128 +define i1 @test54(i8 %a) nounwind { + %ext = zext i8 %a to i32 + %and = and i32 %ext, 192 + %ret = icmp eq i32 %and, 128 + ret i1 %ret +} + +; CHECK: @test55 +; CHECK-NEXT: icmp eq i32 %a, -123 +define i1 @test55(i32 %a) { + %sub = sub i32 0, %a + %cmp = icmp eq i32 %sub, 123 + ret i1 %cmp +} + +; CHECK: @test56 +; CHECK-NEXT: icmp eq i32 %a, -113 +define i1 @test56(i32 %a) { + %sub = sub i32 10, %a + %cmp = icmp eq i32 %sub, 123 + ret i1 %cmp +} diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 332cd46..107f313 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -30,9 +30,9 @@ define i8 @uaddtest2(i8 %A, i8 %B, i1* %overflowPtr) { ; CHECK: @uaddtest2 ; CHECK-NEXT: %and.A = and i8 %A, 127 ; CHECK-NEXT: %and.B = and i8 %B, 127 -; CHECK-NEXT: %1 = add nuw i8 %and.A, %and.B +; CHECK-NEXT: %x = add nuw i8 %and.A, %and.B ; CHECK-NEXT: store i1 false, i1* %overflowPtr -; CHECK-NEXT: ret i8 %1 +; CHECK-NEXT: ret i8 %x } define i8 @uaddtest3(i8 %A, i8 %B, i1* %overflowPtr) { @@ -46,9 +46,9 @@ define i8 @uaddtest3(i8 %A, i8 %B, i1* %overflowPtr) { ; CHECK: @uaddtest3 ; CHECK-NEXT: %or.A = or i8 %A, -128 ; CHECK-NEXT: %or.B = or i8 %B, -128 -; CHECK-NEXT: %1 = add i8 %or.A, %or.B +; CHECK-NEXT: %x = add i8 %or.A, %or.B ; CHECK-NEXT: store i1 true, i1* %overflowPtr -; CHECK-NEXT: ret i8 %1 +; CHECK-NEXT: ret i8 %x } define i8 @uaddtest4(i8 %A, i1* %overflowPtr) { diff --git a/test/Transforms/InstCombine/malloc-free-delete.ll b/test/Transforms/InstCombine/malloc-free-delete.ll index 317786f..8455300 100644 --- a/test/Transforms/InstCombine/malloc-free-delete.ll +++ b/test/Transforms/InstCombine/malloc-free-delete.ll @@ -1,14 +1,14 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s ; PR1201 define i32 @main(i32 %argc, i8** %argv) { - %c_19 = alloca i8* - %malloc_206 = malloc i8, i32 10 + %c_19 = alloca i8* + %malloc_206 = tail call i8* @malloc(i32 mul (i32 ptrtoint (i8* getelementptr (i8* null, i32 1) to i32), i32 10)) + store i8* %malloc_206, i8** %c_19 + %tmp_207 = load i8** %c_19 + tail call void @free(i8* %tmp_207) + ret i32 0 ; CHECK-NOT: malloc - store i8* %malloc_206, i8** %c_19 - %tmp_207 = load i8** %c_19 - free i8* %tmp_207 ; CHECK-NOT: free - ret i32 0 ; CHECK: ret i32 0 } diff --git a/test/Transforms/InstCombine/malloc.ll b/test/Transforms/InstCombine/malloc.ll deleted file mode 100644 index b6ebbea..0000000 --- a/test/Transforms/InstCombine/malloc.ll +++ /dev/null @@ -1,7 +0,0 @@ -; test that malloc's with a constant argument are promoted to array allocations -; RUN: opt < %s -instcombine -S | grep getelementptr - -define i32* @test() { - %X = malloc i32, i32 4 - ret i32* %X -} diff --git a/test/Transforms/InstCombine/malloc2.ll b/test/Transforms/InstCombine/malloc2.ll deleted file mode 100644 index 8462dac..0000000 --- a/test/Transforms/InstCombine/malloc2.ll +++ /dev/null @@ -1,22 +0,0 @@ -; RUN: opt < %s -instcombine -S | FileCheck %s -; PR1313 - -define i32 @test1(i32 %argc, i8* %argv, i8* %envp) { - %tmp15.i.i.i23 = malloc [2564 x i32] ; <[2564 x i32]*> [#uses=1] -; CHECK-NOT: call i8* @malloc - %c = icmp eq [2564 x i32]* %tmp15.i.i.i23, null ; <i1>:0 [#uses=1] - %retval = zext i1 %c to i32 ; <i32> [#uses=1] - ret i32 %retval -; CHECK: ret i32 0 -} - -define i32 @test2(i32 %argc, i8* %argv, i8* %envp) { - %tmp15.i.i.i23 = malloc [2564 x i32] ; <[2564 x i32]*> [#uses=1] -; CHECK-NOT: call i8* @malloc - %X = bitcast [2564 x i32]* %tmp15.i.i.i23 to i32* - %c = icmp ne i32* %X, null - %retval = zext i1 %c to i32 ; <i32> [#uses=1] - ret i32 %retval -; CHECK: ret i32 1 -} - diff --git a/test/Transforms/InstCombine/malloc3.ll b/test/Transforms/InstCombine/malloc3.ll deleted file mode 100644 index f1c0cae..0000000 --- a/test/Transforms/InstCombine/malloc3.ll +++ /dev/null @@ -1,26 +0,0 @@ -; RUN: opt < %s -instcombine -S | not grep load -; PR1728 - -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 triple = "i686-apple-darwin8" - %struct.foo = type { %struct.foo*, [10 x i32] } -@.str = internal constant [21 x i8] c"tmp = %p, next = %p\0A\00" ; <[21 x i8]*> [#uses=1] - -define i32 @main() { -entry: - %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] - %tmp1 = malloc i8, i32 44 ; <i8*> [#uses=1] - %tmp12 = bitcast i8* %tmp1 to %struct.foo* ; <%struct.foo*> [#uses=3] - %tmp3 = malloc i8, i32 44 ; <i8*> [#uses=1] - %tmp34 = bitcast i8* %tmp3 to %struct.foo* ; <%struct.foo*> [#uses=1] - %tmp6 = getelementptr %struct.foo* %tmp12, i32 0, i32 0 ; <%struct.foo**> [#uses=1] - store %struct.foo* %tmp34, %struct.foo** %tmp6, align 4 - %tmp8 = getelementptr %struct.foo* %tmp12, i32 0, i32 0 ; <%struct.foo**> [#uses=1] - %tmp9 = load %struct.foo** %tmp8, align 4 ; <%struct.foo*> [#uses=1] - %tmp10 = getelementptr [21 x i8]* @.str, i32 0, i32 0 ; <i8*> [#uses=1] - %tmp13 = call i32 (i8*, ...)* @printf( i8* %tmp10, %struct.foo* %tmp12, %struct.foo* %tmp9 ) ; <i32> [#uses=0] - ret i32 undef -} - -declare i32 @printf(i8*, ...) - diff --git a/test/Transforms/InstCombine/merge-icmp.ll b/test/Transforms/InstCombine/merge-icmp.ll new file mode 100644 index 0000000..00020b1 --- /dev/null +++ b/test/Transforms/InstCombine/merge-icmp.ll @@ -0,0 +1,29 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define i1 @test1(i16* %x) { + %load = load i16* %x, align 4 + %trunc = trunc i16 %load to i8 + %cmp1 = icmp eq i8 %trunc, 127 + %and = and i16 %load, -256 + %cmp2 = icmp eq i16 %and, 17664 + %or = and i1 %cmp1, %cmp2 + ret i1 %or +; CHECK: @test1 +; CHECK-NEXT: load i16 +; CHECK-NEXT: icmp eq i16 %load, 17791 +; CHECK-NEXT: ret i1 +} + +define i1 @test2(i16* %x) { + %load = load i16* %x, align 4 + %and = and i16 %load, -256 + %cmp1 = icmp eq i16 %and, 32512 + %trunc = trunc i16 %load to i8 + %cmp2 = icmp eq i8 %trunc, 69 + %or = and i1 %cmp1, %cmp2 + ret i1 %or +; CHECK: @test2 +; CHECK-NEXT: load i16 +; CHECK-NEXT: icmp eq i16 %load, 32581 +; CHECK-NEXT: ret i1 +} diff --git a/test/Transforms/InstCombine/not.ll b/test/Transforms/InstCombine/not.ll index c58ce11..4a8825b 100644 --- a/test/Transforms/InstCombine/not.ll +++ b/test/Transforms/InstCombine/not.ll @@ -43,7 +43,7 @@ define i32 @test5(i32 %A, i32 %B) { } ; PR2298 -define i8 @test6(i32 %a, i32 %b) zeroext nounwind { +define zeroext i8 @test6(i32 %a, i32 %b) nounwind { entry: %tmp1not = xor i32 %a, -1 ; <i32> [#uses=1] %tmp2not = xor i32 %b, -1 ; <i32> [#uses=1] diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll index f82f9fa..c0bb28d 100644 --- a/test/Transforms/InstCombine/or.ll +++ b/test/Transforms/InstCombine/or.ll @@ -332,8 +332,8 @@ define i64 @test31(i64 %A) nounwind readnone ssp noredzone { %F = or i64 %D, %E ret i64 %F ; CHECK: @test31 -; CHECK-NEXT: %E1 = and i64 %A, 4294908984 -; CHECK-NEXT: %F = or i64 %E1, 32962 +; CHECK-NEXT: %E = and i64 %A, 4294908984 +; CHECK-NEXT: %F = or i64 %E, 32962 ; CHECK-NEXT: ret i64 %F } @@ -390,3 +390,22 @@ define i1 @test36(i32 %x) { ; CHECK-NEXT: ret i1 } +define i32 @test37(i32* %xp, i32 %y) { +; CHECK: @test37 +; CHECK: select i1 %tobool, i32 -1, i32 %x + %tobool = icmp ne i32 %y, 0 + %sext = sext i1 %tobool to i32 + %x = load i32* %xp + %or = or i32 %sext, %x + ret i32 %or +} + +define i32 @test38(i32* %xp, i32 %y) { +; CHECK: @test38 +; CHECK: select i1 %tobool, i32 -1, i32 %x + %tobool = icmp ne i32 %y, 0 + %sext = sext i1 %tobool to i32 + %x = load i32* %xp + %or = or i32 %x, %sext + ret i32 %or +} diff --git a/test/Transforms/InstCombine/phi.ll b/test/Transforms/InstCombine/phi.ll index 62c6a63..cd865ae 100644 --- a/test/Transforms/InstCombine/phi.ll +++ b/test/Transforms/InstCombine/phi.ll @@ -197,25 +197,25 @@ declare i1 @test11a() define i1 @test11() { entry: %a = alloca i32 - %i = ptrtoint i32* %a to i32 + %i = ptrtoint i32* %a to i64 %b = call i1 @test11a() br i1 %b, label %one, label %two one: - %x = phi i32 [%i, %entry], [%y, %two] + %x = phi i64 [%i, %entry], [%y, %two] %c = call i1 @test11a() br i1 %c, label %two, label %end two: - %y = phi i32 [%i, %entry], [%x, %one] + %y = phi i64 [%i, %entry], [%x, %one] %d = call i1 @test11a() br i1 %d, label %one, label %end end: - %f = phi i32 [ %x, %one], [%y, %two] + %f = phi i64 [ %x, %one], [%y, %two] ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter ; even though %f must equal %i at this point - %g = inttoptr i32 %f to i32* + %g = inttoptr i64 %f to i32* store i32 10, i32* %g %z = call i1 @test11a() ret i1 %z @@ -544,3 +544,79 @@ BB2: ; CHECK-NEXT: %C = add nuw i32 %A, 1 ; CHECK-NEXT: ret i32 %C } + +; Same as test11, but used to be missed due to a bug. +declare i1 @test25a() + +define i1 @test25() { +entry: + %a = alloca i32 + %i = ptrtoint i32* %a to i64 + %b = call i1 @test25a() + br i1 %b, label %one, label %two + +one: + %x = phi i64 [%y, %two], [%i, %entry] + %c = call i1 @test25a() + br i1 %c, label %two, label %end + +two: + %y = phi i64 [%x, %one], [%i, %entry] + %d = call i1 @test25a() + br i1 %d, label %one, label %end + +end: + %f = phi i64 [ %x, %one], [%y, %two] + ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter + ; even though %f must equal %i at this point + %g = inttoptr i64 %f to i32* + store i32 10, i32* %g + %z = call i1 @test25a() + ret i1 %z +; CHECK: @test25 +; CHECK-NOT: phi i32 +; CHECK: ret i1 %z +} + +declare i1 @test26a() + +define i1 @test26(i32 %n) { +entry: + %a = alloca i32 + %i = ptrtoint i32* %a to i64 + %b = call i1 @test26a() + br label %one + +one: + %x = phi i64 [%y, %two], [%w, %three], [%i, %entry] + %c = call i1 @test26a() + switch i32 %n, label %end [ + i32 2, label %two + i32 3, label %three + ] + +two: + %y = phi i64 [%x, %one], [%w, %three] + %d = call i1 @test26a() + switch i32 %n, label %end [ + i32 10, label %one + i32 30, label %three + ] + +three: + %w = phi i64 [%y, %two], [%x, %one] + %e = call i1 @test26a() + br i1 %e, label %one, label %two + +end: + %f = phi i64 [ %x, %one], [%y, %two] + ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter + ; even though %f must equal %i at this point + %g = inttoptr i64 %f to i32* + store i32 10, i32* %g + %z = call i1 @test26a() + ret i1 %z +; CHECK: @test26 +; CHECK-NOT: phi i32 +; CHECK: ret i1 %z +} diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index 3925907..4ca9bd2 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -749,3 +749,53 @@ define i1 @test55(i1 %X, i32 %Y, i32 %Z) { ; CHECK: icmp eq ; CHECK: ret i1 } + +define i32 @test56(i16 %x) nounwind { + %tobool = icmp eq i16 %x, 0 + %conv = zext i16 %x to i32 + %cond = select i1 %tobool, i32 0, i32 %conv + ret i32 %cond +; CHECK: @test56 +; CHECK-NEXT: zext +; CHECK-NEXT: ret +} + +define i32 @test57(i32 %x, i32 %y) nounwind { + %and = and i32 %x, %y + %tobool = icmp eq i32 %x, 0 + %.and = select i1 %tobool, i32 0, i32 %and + ret i32 %.and +; CHECK: @test57 +; CHECK-NEXT: and i32 %x, %y +; CHECK-NEXT: ret +} + +define i32 @test58(i16 %x) nounwind { + %tobool = icmp ne i16 %x, 1 + %conv = zext i16 %x to i32 + %cond = select i1 %tobool, i32 %conv, i32 1 + ret i32 %cond +; CHECK: @test58 +; CHECK-NEXT: zext +; CHECK-NEXT: ret +} + +define i32 @test59(i32 %x, i32 %y) nounwind { + %and = and i32 %x, %y + %tobool = icmp ne i32 %x, %y + %.and = select i1 %tobool, i32 %and, i32 %y + ret i32 %.and +; CHECK: @test59 +; CHECK-NEXT: and i32 %x, %y +; CHECK-NEXT: ret +} + +define i1 @test60(i32 %x, i1* %y) nounwind { + %cmp = icmp eq i32 %x, 0 + %load = load i1* %y, align 1 + %cmp1 = icmp slt i32 %x, 1 + %sel = select i1 %cmp, i1 %load, i1 %cmp1 + ret i1 %sel +; CHECK: @test60 +; CHECK: select +} diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index 7fab1d2..d9ac9cb 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -485,3 +485,45 @@ entry: ; CHECK: ret i8 %tmp551 ret i8 %tmp55 } + +; PR9809 +define i32 @test40(i32 %a, i32 %b) nounwind { + %shl1 = shl i32 1, %b + %shl2 = shl i32 %shl1, 2 + %div = udiv i32 %a, %shl2 + ret i32 %div +; CHECK: @test40 +; CHECK-NEXT: add i32 %b, 2 +; CHECK-NEXT: lshr i32 %a +; CHECK-NEXT: ret i32 +} + +define i32 @test41(i32 %a, i32 %b) nounwind { + %1 = shl i32 1, %b + %2 = shl i32 %1, 3 + ret i32 %2 +; CHECK: @test41 +; CHECK-NEXT: shl i32 8, %b +; CHECK-NEXT: ret i32 +} + +define i32 @test42(i32 %a, i32 %b) nounwind { + %div = lshr i32 4096, %b ; must be exact otherwise we'd divide by zero + %div2 = udiv i32 %a, %div + ret i32 %div2 +; CHECK: @test42 +; CHECK-NEXT: lshr exact i32 4096, %b +} + +define i32 @test43(i32 %a, i32 %b) nounwind { + %div = shl i32 4096, %b ; must be exact otherwise we'd divide by zero + %div2 = udiv i32 %a, %div + ret i32 %div2 +; CHECK: @test43 +; CHECK-NEXT: add i32 %b, 12 +; CHECK-NEXT: lshr +; CHECK-NEXT: ret +} + + + diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll index 9656a7e..37de328 100644 --- a/test/Transforms/InstCombine/sub.ll +++ b/test/Transforms/InstCombine/sub.ll @@ -203,7 +203,7 @@ define i1 @test21(i32 %g, i32 %h) { } ; PR2298 -define i1 @test22(i32 %a, i32 %b) zeroext nounwind { +define zeroext i1 @test22(i32 %a, i32 %b) nounwind { %tmp2 = sub i32 0, %a %tmp4 = sub i32 0, %b %tmp5 = icmp eq i32 %tmp2, %tmp4 diff --git a/test/Transforms/InstCombine/udivrem-change-width.ll b/test/Transforms/InstCombine/udivrem-change-width.ll index 9983944..b388a3b 100644 --- a/test/Transforms/InstCombine/udivrem-change-width.ll +++ b/test/Transforms/InstCombine/udivrem-change-width.ll @@ -1,14 +1,16 @@ -; RUN: opt < %s -instcombine -S | not grep zext -; PR4548 +; RUN: opt < %s -instcombine -S | 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" +; PR4548 define i8 @udiv_i8(i8 %a, i8 %b) nounwind { %conv = zext i8 %a to i32 %conv2 = zext i8 %b to i32 %div = udiv i32 %conv, %conv2 %conv3 = trunc i32 %div to i8 ret i8 %conv3 +; CHECK: @udiv_i8 +; CHECK: udiv i8 %a, %b } define i8 @urem_i8(i8 %a, i8 %b) nounwind { @@ -17,5 +19,44 @@ define i8 @urem_i8(i8 %a, i8 %b) nounwind { %div = urem i32 %conv, %conv2 %conv3 = trunc i32 %div to i8 ret i8 %conv3 +; CHECK: @urem_i8 +; CHECK: urem i8 %a, %b } +define i32 @udiv_i32(i8 %a, i8 %b) nounwind { + %conv = zext i8 %a to i32 + %conv2 = zext i8 %b to i32 + %div = udiv i32 %conv, %conv2 + ret i32 %div +; CHECK: @udiv_i32 +; CHECK: udiv i8 %a, %b +; CHECK: zext +} + +define i32 @urem_i32(i8 %a, i8 %b) nounwind { + %conv = zext i8 %a to i32 + %conv2 = zext i8 %b to i32 + %div = urem i32 %conv, %conv2 + ret i32 %div +; CHECK: @urem_i32 +; CHECK: urem i8 %a, %b +; CHECK: zext +} + +define i32 @udiv_i32_c(i8 %a) nounwind { + %conv = zext i8 %a to i32 + %div = udiv i32 %conv, 10 + ret i32 %div +; CHECK: @udiv_i32_c +; CHECK: udiv i8 %a, 10 +; CHECK: zext +} + +define i32 @urem_i32_c(i8 %a) nounwind { + %conv = zext i8 %a to i32 + %div = urem i32 %conv, 10 + ret i32 %div +; CHECK: @urem_i32_c +; CHECK: urem i8 %a, 10 +; CHECK: zext +} diff --git a/test/Transforms/InstCombine/vec_demanded_elts.ll b/test/Transforms/InstCombine/vec_demanded_elts.ll index 9f308aa..e0188fe 100644 --- a/test/Transforms/InstCombine/vec_demanded_elts.ll +++ b/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -136,3 +136,19 @@ declare i32 @llvm.x86.sse2.cvtsd2si(<2 x double>) declare i64 @llvm.x86.sse2.cvtsd2si64(<2 x double>) declare i32 @llvm.x86.sse2.cvttsd2si(<2 x double>) declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>) + +; <rdar://problem/6945110> +define <4 x i32> @kernel3_vertical(<4 x i16> * %src, <8 x i16> * %foo) nounwind { +entry: + %tmp = load <4 x i16>* %src + %tmp1 = load <8 x i16>* %foo +; CHECK: %tmp2 = shufflevector + %tmp2 = shufflevector <4 x i16> %tmp, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef> +; pmovzxwd ignores the upper 64-bits of its input; -instcombine should remove this shuffle: +; CHECK-NOT: shufflevector + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7> +; CHECK-NEXT: pmovzxwd + %0 = call <4 x i32> @llvm.x86.sse41.pmovzxwd(<8 x i16> %tmp3) + ret <4 x i32> %0 +} +declare <4 x i32> @llvm.x86.sse41.pmovzxwd(<8 x i16>) nounwind readnone diff --git a/test/Transforms/InstCombine/x86-crc32-demanded.ll b/test/Transforms/InstCombine/x86-crc32-demanded.ll new file mode 100644 index 0000000..878b97d --- /dev/null +++ b/test/Transforms/InstCombine/x86-crc32-demanded.ll @@ -0,0 +1,17 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +; crc32 with 64-bit destination zeros high 32-bit. +; rdar://9467055 + +define i64 @test() nounwind { +entry: +; CHECK: test +; CHECK: tail call i64 @llvm.x86.sse42.crc32.64.64 +; CHECK-NOT: and +; CHECK: ret + %0 = tail call i64 @llvm.x86.sse42.crc32.64.64(i64 0, i64 4) nounwind + %1 = and i64 %0, 4294967295 + ret i64 %1 +} + +declare i64 @llvm.x86.sse42.crc32.64.64(i64, i64) nounwind readnone diff --git a/test/Transforms/InstCombine/zext-or-icmp.ll b/test/Transforms/InstCombine/zext-or-icmp.ll index 969c301..ddc6083 100644 --- a/test/Transforms/InstCombine/zext-or-icmp.ll +++ b/test/Transforms/InstCombine/zext-or-icmp.ll @@ -4,7 +4,7 @@ %struct.Rock = type { i16, i16 } @some_idx = internal constant [4 x i8] c"\0A\0B\0E\0F" ; <[4 x i8]*> [#uses=1] -define i8 @t(%struct.FooBar* %up, i8 zeroext %intra_flag, i32 %blk_i) zeroext nounwind { +define zeroext i8 @t(%struct.FooBar* %up, i8 zeroext %intra_flag, i32 %blk_i) nounwind { entry: %tmp2 = lshr i32 %blk_i, 1 ; <i32> [#uses=1] %tmp3 = and i32 %tmp2, 2 ; <i32> [#uses=1] |