diff options
Diffstat (limited to 'test/Transforms')
32 files changed, 1569 insertions, 3 deletions
diff --git a/test/Transforms/ABCD/basic.ll b/test/Transforms/ABCD/basic.ll new file mode 100644 index 0000000..f2ce1b9 --- /dev/null +++ b/test/Transforms/ABCD/basic.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -abcd -S | FileCheck %s + +define void @test() { +; CHECK: @test +; CHECK-NOT: br i1 %tmp95 +; CHECK: ret void +entry: + br label %bb19 + +bb: + br label %bb1 + +bb1: + %tmp7 = icmp sgt i32 %tmp94, 1 + br i1 %tmp7, label %bb.i.i, label %return + +bb.i.i: + br label %return + +bb19: + %tmp94 = ashr i32 undef, 3 + %tmp95 = icmp sgt i32 %tmp94, 16 + br i1 %tmp95, label %bb, label %return + +return: + ret void +} diff --git a/test/Transforms/ABCD/dg.exp b/test/Transforms/ABCD/dg.exp new file mode 100644 index 0000000..f200589 --- /dev/null +++ b/test/Transforms/ABCD/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll b/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll new file mode 100644 index 0000000..9a943b4 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/2009-11-10-Trampoline.ll @@ -0,0 +1,16 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare i8* @llvm.init.trampoline(i8*, i8*, i8*) + +declare void @f() + +define void @unused_trampoline() { +; CHECK: @unused_trampoline + %storage = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1] +; CHECK-NOT: alloca + %cast = getelementptr [10 x i8]* %storage, i32 0, i32 0 ; <i8*> [#uses=1] + %tramp = call i8* @llvm.init.trampoline( i8* %cast, i8* bitcast (void ()* @f to i8*), i8* null ) ; <i8*> [#uses=1] +; CHECK-NOT: trampoline + ret void +; CHECK: ret void +} diff --git a/test/Transforms/DeadStoreElimination/const-pointers.ll b/test/Transforms/DeadStoreElimination/const-pointers.ll new file mode 100644 index 0000000..ce18c6f --- /dev/null +++ b/test/Transforms/DeadStoreElimination/const-pointers.ll @@ -0,0 +1,39 @@ +; RUN: opt %s -dse -S | FileCheck %s + +%t = type { i32 } + +@g = global i32 42; + +define void @test1(%t* noalias %pp) { + %p = getelementptr inbounds %t* %pp, i32 0, i32 0 + + store i32 1, i32* %p; <-- This is dead + %x = load i32* inttoptr (i32 12345 to i32*) + store i32 %x, i32* %p + ret void +; CHECK define void @test1 +; CHECK: store +; CHECK-NOT: store +; CHECK: ret void +} + +define void @test3() { + store i32 1, i32* @g; <-- This is dead. + store i32 42, i32* @g + ret void +;CHECK define void @test3 +;CHECK: store +;CHECK-NOT: store +;CHECK: ret void +} + +define void @test4(i32* %p) { + store i32 1, i32* %p + %x = load i32* @g; <-- %p and @g could alias + store i32 %x, i32* %p + ret void +; CHECK define void @test4 +; CHECK: store +; CHECK: store +; CHECK: ret void +} diff --git a/test/Transforms/DeadStoreElimination/lifetime.ll b/test/Transforms/DeadStoreElimination/lifetime.ll new file mode 100644 index 0000000..b2da790 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/lifetime.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare void @llvm.lifetime.end(i64, i8*) +declare void @llvm.memset.i8(i8*, i8, i8, i32) + +define void @test1() { +; CHECK: @test1 + %A = alloca i8 + + store i8 0, i8* %A ;; Written to by memset + call void @llvm.lifetime.end(i64 1, i8* %A) +; CHECK: lifetime.end + + call void @llvm.memset.i8(i8* %A, i8 0, i8 -1, i32 0) +; CHECK-NOT: memset + + ret void +; CHECK: ret void +} diff --git a/test/Transforms/DeadStoreElimination/memintrinsics.ll b/test/Transforms/DeadStoreElimination/memintrinsics.ll new file mode 100644 index 0000000..e31e9fa --- /dev/null +++ b/test/Transforms/DeadStoreElimination/memintrinsics.ll @@ -0,0 +1,47 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare void @llvm.memcpy.i8(i8*, i8*, i8, i32) +declare void @llvm.memmove.i8(i8*, i8*, i8, i32) +declare void @llvm.memset.i8(i8*, i8, i8, i32) + +define void @test1() { +; CHECK: @test1 + %A = alloca i8 + %B = alloca i8 + + store i8 0, i8* %A ;; Written to by memcpy +; CHECK-NOT: store + + call void @llvm.memcpy.i8(i8* %A, i8* %B, i8 -1, i32 0) + + ret void +; CHECK: ret void +} + +define void @test2() { +; CHECK: @test2 + %A = alloca i8 + %B = alloca i8 + + store i8 0, i8* %A ;; Written to by memmove +; CHECK-NOT: store + + call void @llvm.memmove.i8(i8* %A, i8* %B, i8 -1, i32 0) + + ret void +; CHECK: ret void +} + +define void @test3() { +; CHECK: @test3 + %A = alloca i8 + %B = alloca i8 + + store i8 0, i8* %A ;; Written to by memset +; CHECK-NOT: store + + call void @llvm.memset.i8(i8* %A, i8 0, i8 -1, i32 0) + + ret void +; CHECK: ret void +} diff --git a/test/Transforms/DeadStoreElimination/partial-overwrite.ll b/test/Transforms/DeadStoreElimination/partial-overwrite.ll new file mode 100644 index 0000000..048d464 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/partial-overwrite.ll @@ -0,0 +1,14 @@ +; RUN: opt -dse -S %s | FileCheck %s +; Note that we could do better by merging the two stores into one. + +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" +target triple = "x86_64-unknown-linux-gnu" + +define void @test(i32* %P) { + store i32 0, i32* %P +; CHECK: store i32 + %Q = bitcast i32* %P to i16* + store i16 1, i16* %Q +; CHECK: store i16 + ret void +} diff --git a/test/Transforms/GVN/null-aliases-nothing.ll b/test/Transforms/GVN/null-aliases-nothing.ll new file mode 100644 index 0000000..bc5c850 --- /dev/null +++ b/test/Transforms/GVN/null-aliases-nothing.ll @@ -0,0 +1,20 @@ +; RUN: opt %s -gvn -S | FileCheck %s + +%t = type { i32 } +declare void @test1f(i8*) + +define void @test1(%t* noalias %stuff ) { + %p = getelementptr inbounds %t* %stuff, i32 0, i32 0 + %before = load i32* %p + + call void @test1f(i8* null) + + %after = load i32* %p ; <--- This should be a dead load + %sum = add i32 %before, %after; + + store i32 %sum, i32* %p + ret void +; CHECK: load +; CHECK-NOT: load +; CHECK: ret void +} diff --git a/test/Transforms/Inline/delete-call.ll b/test/Transforms/Inline/delete-call.ll new file mode 100644 index 0000000..3505608 --- /dev/null +++ b/test/Transforms/Inline/delete-call.ll @@ -0,0 +1,22 @@ +; RUN: opt %s -S -inline -functionattrs -stats |& grep {Number of call sites deleted, not inlined} +; RUN: opt %s -S -inline -stats |& grep {Number of functions inlined} + +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.8" + +define internal i32 @test(i32 %x, i32 %y, i32 %z) nounwind { +entry: + %0 = add nsw i32 %y, %z ; <i32> [#uses=1] + %1 = mul i32 %0, %x ; <i32> [#uses=1] + %2 = mul i32 %y, %z ; <i32> [#uses=1] + %3 = add nsw i32 %1, %2 ; <i32> [#uses=1] + ret i32 %3 +} + +define i32 @test2() nounwind { +entry: + %0 = call i32 @test(i32 1, i32 2, i32 4) nounwind ; <i32> [#uses=1] + ret i32 14 +} + + diff --git a/test/Transforms/InstCombine/2008-01-21-MulTrunc.ll b/test/Transforms/InstCombine/2008-01-21-MulTrunc.ll index a49829a..87c2b75 100644 --- a/test/Transforms/InstCombine/2008-01-21-MulTrunc.ll +++ b/test/Transforms/InstCombine/2008-01-21-MulTrunc.ll @@ -1,5 +1,7 @@ ; 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" + define i16 @test1(i16 %a) { %tmp = zext i16 %a to i32 ; <i32> [#uses=2] %tmp21 = lshr i32 %tmp, 8 ; <i32> [#uses=1] diff --git a/test/Transforms/InstCombine/apint-cast.ll b/test/Transforms/InstCombine/apint-cast.ll index 9bc539e..85e7a4f 100644 --- a/test/Transforms/InstCombine/apint-cast.ll +++ b/test/Transforms/InstCombine/apint-cast.ll @@ -1,6 +1,8 @@ ; Tests to make sure elimination of casts is working correctly ; 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" + define i17 @test1(i17 %a) { %tmp = zext i17 %a to i37 ; <i37> [#uses=2] %tmp21 = lshr i37 %tmp, 8 ; <i37> [#uses=1] diff --git a/test/Transforms/InstCombine/cast-mul-select.ll b/test/Transforms/InstCombine/cast-mul-select.ll index fcb7e23..f55423c 100644 --- a/test/Transforms/InstCombine/cast-mul-select.ll +++ b/test/Transforms/InstCombine/cast-mul-select.ll @@ -1,5 +1,7 @@ ; 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-n8:16:32" + define i32 @mul(i32 %x, i32 %y) { %A = trunc i32 %x to i8 %B = trunc i32 %y to i8 diff --git a/test/Transforms/InstCombine/cast-set.ll b/test/Transforms/InstCombine/cast-set.ll index 611ded4..8934404 100644 --- a/test/Transforms/InstCombine/cast-set.ll +++ b/test/Transforms/InstCombine/cast-set.ll @@ -1,6 +1,8 @@ ; This tests for various complex cast elimination cases instcombine should ; handle. +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" + ; RUN: opt < %s -instcombine -S | FileCheck %s define i1 @test1(i32 %X) { diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index 79f86e9..e7695b7 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -1,6 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; RUN: opt < %s -instcombine -S | FileCheck %s -target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" @inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1] diff --git a/test/Transforms/InstCombine/compare-signs.ll b/test/Transforms/InstCombine/compare-signs.ll new file mode 100644 index 0000000..2f98641 --- /dev/null +++ b/test/Transforms/InstCombine/compare-signs.ll @@ -0,0 +1,29 @@ +; RUN: opt %s -instcombine -S | FileCheck %s +; XFAIL: * +; PR5438 + +; TODO: This should also optimize down. +;define i32 @bar(i32 %a, i32 %b) nounwind readnone { +;entry: +; %0 = icmp sgt i32 %a, -1 ; <i1> [#uses=1] +; %1 = icmp slt i32 %b, 0 ; <i1> [#uses=1] +; %2 = xor i1 %1, %0 ; <i1> [#uses=1] +; %3 = zext i1 %2 to i32 ; <i32> [#uses=1] +; ret i32 %3 +;} + +define i32 @qaz(i32 %a, i32 %b) nounwind readnone { +; CHECK: @qaz +entry: +; CHECK: xor i32 %a, %b +; CHECK; lshr i32 %0, 31 +; CHECK: xor i32 %1, 1 + %0 = lshr i32 %a, 31 ; <i32> [#uses=1] + %1 = lshr i32 %b, 31 ; <i32> [#uses=1] + %2 = icmp eq i32 %0, %1 ; <i1> [#uses=1] + %3 = zext i1 %2 to i32 ; <i32> [#uses=1] + ret i32 %3 +; CHECK-NOT: icmp +; CHECK-NOT: zext +; CHECK: ret i32 %2 +} diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll new file mode 100644 index 0000000..7abd380 --- /dev/null +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -0,0 +1,12 @@ +; RUN: opt %s -instcombine -S | FileCheck %s + +declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) + +define i8 @test1(i8 %A, i8 %B) { + %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %A, i8 %B) + %y = extractvalue {i8, i1} %x, 0 + ret i8 %y +; CHECK: @test1 +; CHECK-NEXT: %y = add i8 %A, %B +; CHECK-NEXT: ret i8 %y +} diff --git a/test/Transforms/InstCombine/invariant.ll b/test/Transforms/InstCombine/invariant.ll new file mode 100644 index 0000000..c67ad33 --- /dev/null +++ b/test/Transforms/InstCombine/invariant.ll @@ -0,0 +1,16 @@ +; Test to make sure unused llvm.invariant.start calls are not trivially eliminated +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @g(i8*) + +declare { }* @llvm.invariant.start(i64, i8* nocapture) nounwind readonly + +define i8 @f() { + %a = alloca i8 ; <i8*> [#uses=4] + store i8 0, i8* %a + %i = call { }* @llvm.invariant.start(i64 1, i8* %a) ; <{ }*> [#uses=0] + ; CHECK: call { }* @llvm.invariant.start + call void @g(i8* %a) + %r = load i8* %a ; <i8> [#uses=1] + ret i8 %r +} diff --git a/test/Transforms/InstCombine/phi.ll b/test/Transforms/InstCombine/phi.ll index b73ce3f..f0343e4 100644 --- a/test/Transforms/InstCombine/phi.ll +++ b/test/Transforms/InstCombine/phi.ll @@ -2,6 +2,8 @@ ; ; 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:n8:16:32:64" + define i32 @test1(i32 %A, i1 %b) { BB0: br i1 %b, label %BB1, label %BB2 @@ -222,3 +224,141 @@ end: ; CHECK: ret i1 %z } + +define i64 @test12(i1 %cond, i8* %Ptr, i64 %Val) { +entry: + %tmp41 = ptrtoint i8* %Ptr to i64 + %tmp42 = zext i64 %tmp41 to i128 + br i1 %cond, label %end, label %two + +two: + %tmp36 = zext i64 %Val to i128 ; <i128> [#uses=1] + %tmp37 = shl i128 %tmp36, 64 ; <i128> [#uses=1] + %ins39 = or i128 %tmp42, %tmp37 ; <i128> [#uses=1] + br label %end + +end: + %tmp869.0 = phi i128 [ %tmp42, %entry ], [ %ins39, %two ] + %tmp32 = trunc i128 %tmp869.0 to i64 ; <i64> [#uses=1] + %tmp29 = lshr i128 %tmp869.0, 64 ; <i128> [#uses=1] + %tmp30 = trunc i128 %tmp29 to i64 ; <i64> [#uses=1] + + %tmp2 = add i64 %tmp32, %tmp30 + ret i64 %tmp2 +; CHECK: @test12 +; CHECK-NOT: zext +; CHECK: end: +; CHECK-NEXT: phi i64 [ 0, %entry ], [ %Val, %two ] +; CHECK-NOT: phi +; CHECK: ret i64 +} + +declare void @test13f(double, i32) + +define void @test13(i1 %cond, i32 %V1, double %Vald) { +entry: + %tmp42 = zext i32 %V1 to i128 + br i1 %cond, label %end, label %two + +two: + %Val = bitcast double %Vald to i64 + %tmp36 = zext i64 %Val to i128 ; <i128> [#uses=1] + %tmp37 = shl i128 %tmp36, 64 ; <i128> [#uses=1] + %ins39 = or i128 %tmp42, %tmp37 ; <i128> [#uses=1] + br label %end + +end: + %tmp869.0 = phi i128 [ %tmp42, %entry ], [ %ins39, %two ] + %tmp32 = trunc i128 %tmp869.0 to i32 + %tmp29 = lshr i128 %tmp869.0, 64 ; <i128> [#uses=1] + %tmp30 = trunc i128 %tmp29 to i64 ; <i64> [#uses=1] + %tmp31 = bitcast i64 %tmp30 to double + + call void @test13f(double %tmp31, i32 %tmp32) + ret void +; CHECK: @test13 +; CHECK-NOT: zext +; CHECK: end: +; CHECK-NEXT: phi double [ 0.000000e+00, %entry ], [ %Vald, %two ] +; CHECK-NEXT: call void @test13f(double {{[^,]*}}, i32 %V1) +; CHECK: ret void +} + +define i640 @test14a(i320 %A, i320 %B, i1 %b1) { +BB0: + %a = zext i320 %A to i640 + %b = zext i320 %B to i640 + br label %Loop + +Loop: + %C = phi i640 [ %a, %BB0 ], [ %b, %Loop ] + br i1 %b1, label %Loop, label %Exit + +Exit: ; preds = %Loop + ret i640 %C +; CHECK: @test14a +; CHECK: Loop: +; CHECK-NEXT: phi i320 +} + +define i160 @test14b(i320 %A, i320 %B, i1 %b1) { +BB0: + %a = trunc i320 %A to i160 + %b = trunc i320 %B to i160 + br label %Loop + +Loop: + %C = phi i160 [ %a, %BB0 ], [ %b, %Loop ] + br i1 %b1, label %Loop, label %Exit + +Exit: ; preds = %Loop + ret i160 %C +; CHECK: @test14b +; CHECK: Loop: +; CHECK-NEXT: phi i160 +} + +declare i64 @test15a(i64) + +define i64 @test15b(i64 %A, i1 %b) { +; CHECK: @test15b +entry: + %i0 = zext i64 %A to i128 + %i1 = shl i128 %i0, 64 + %i = or i128 %i1, %i0 + br i1 %b, label %one, label %two +; CHECK: entry: +; CHECK-NEXT: br i1 %b + +one: + %x = phi i128 [%i, %entry], [%y, %two] + %x1 = lshr i128 %x, 64 + %x2 = trunc i128 %x1 to i64 + %c = call i64 @test15a(i64 %x2) + %c1 = zext i64 %c to i128 + br label %two + +; CHECK: one: +; CHECK-NEXT: phi i64 +; CHECK-NEXT: %c = call i64 @test15a + +two: + %y = phi i128 [%i, %entry], [%c1, %one] + %y1 = lshr i128 %y, 64 + %y2 = trunc i128 %y1 to i64 + %d = call i64 @test15a(i64 %y2) + %d1 = trunc i64 %d to i1 + br i1 %d1, label %one, label %end + +; CHECK: two: +; CHECK-NEXT: phi i64 +; CHECK-NEXT: phi i64 +; CHECK-NEXT: %d = call i64 @test15a + +end: + %g = trunc i128 %y to i64 + ret i64 %g +; CHECK: end: +; CHECK-NEXT: ret i64 +} + diff --git a/test/Transforms/InstCombine/sext-misc.ll b/test/Transforms/InstCombine/sext-misc.ll index 107bba6..3346ff8 100644 --- a/test/Transforms/InstCombine/sext-misc.ll +++ b/test/Transforms/InstCombine/sext-misc.ll @@ -1,5 +1,7 @@ ; RUN: opt < %s -instcombine -S | not grep sext +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) diff --git a/test/Transforms/InstCombine/udivrem-change-width.ll b/test/Transforms/InstCombine/udivrem-change-width.ll index 56877e3..9983944 100644 --- a/test/Transforms/InstCombine/udivrem-change-width.ll +++ b/test/Transforms/InstCombine/udivrem-change-width.ll @@ -1,6 +1,8 @@ ; RUN: opt < %s -instcombine -S | not grep zext ; PR4548 +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" + define i8 @udiv_i8(i8 %a, i8 %b) nounwind { %conv = zext i8 %a to i32 %conv2 = zext i8 %b to i32 diff --git a/test/Transforms/JumpThreading/basic.ll b/test/Transforms/JumpThreading/basic.ll index 3d936b8..ac31cdb 100644 --- a/test/Transforms/JumpThreading/basic.ll +++ b/test/Transforms/JumpThreading/basic.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -jump-threading -S | FileCheck %s +; RUN: opt %s -jump-threading -S -enable-jump-threading-lvi | FileCheck %s declare i32 @f1() declare i32 @f2() @@ -170,5 +170,241 @@ BB4: } +;; This tests that the branch in 'merge' can be cloned up into T1. +;; rdar://7367025 +define i32 @test7(i1 %cond, i1 %cond2) { +Entry: +; CHECK: @test7 + %v1 = call i32 @f1() + br i1 %cond, label %Merge, label %F1 + +F1: + %v2 = call i32 @f2() + br label %Merge + +Merge: + %B = phi i32 [%v1, %Entry], [%v2, %F1] + %M = icmp ne i32 %B, %v1 + %N = icmp eq i32 %B, 47 + %O = and i1 %M, %N + br i1 %O, label %T2, label %F2 + +; CHECK: Merge: +; CHECK-NOT: phi +; CHECK-NEXT: %v2 = call i32 @f2() + +T2: + call void @f3() + ret i32 %B + +F2: + ret i32 %B +; CHECK: F2: +; CHECK-NEXT: phi i32 +} + + +declare i1 @test8a() + +define i32 @test8b(i1 %cond, i1 %cond2) { +; CHECK: @test8b +T0: + %A = call i1 @test8a() + br i1 %A, label %T1, label %F1 + +; CHECK: T0: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %A, label %T1, label %Y + +T1: + %B = call i1 @test8a() + br i1 %B, label %T2, label %F1 + +; CHECK: T1: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %B, label %T2, label %Y +T2: + %C = call i1 @test8a() + br i1 %cond, label %T3, label %F1 + +; CHECK: T2: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %cond, label %T3, label %Y +T3: + ret i32 0 + +F1: + %D = phi i32 [0, %T0], [0, %T1], [1, %T2] + %E = icmp eq i32 %D, 1 + %F = and i1 %E, %cond + br i1 %F, label %X, label %Y +X: + call i1 @test8a() + ret i32 1 +Y: + ret i32 2 +} + + +;;; Verify that we can handle constraint propagation through "xor x, 1". +define i32 @test9(i1 %cond, i1 %cond2) { +Entry: +; CHECK: @test9 + %v1 = call i32 @f1() + br i1 %cond, label %Merge, label %F1 + +; CHECK: Entry: +; CHECK-NEXT: %v1 = call i32 @f1() +; CHECK-NEXT: br i1 %cond, label %F2, label %Merge + +F1: + %v2 = call i32 @f2() + br label %Merge + +Merge: + %B = phi i32 [%v1, %Entry], [%v2, %F1] + %M = icmp eq i32 %B, %v1 + %M1 = xor i1 %M, 1 + %N = icmp eq i32 %B, 47 + %O = and i1 %M1, %N + br i1 %O, label %T2, label %F2 + +; CHECK: Merge: +; CHECK-NOT: phi +; CHECK-NEXT: %v2 = call i32 @f2() + +T2: + %Q = zext i1 %M to i32 + ret i32 %Q + +F2: + ret i32 %B +; CHECK: F2: +; CHECK-NEXT: phi i32 +} + + + +; CHECK: @test10 +declare i32 @test10f1() +declare i32 @test10f2() +declare void @test10f3() + +;; Non-local condition threading. +define i32 @test10g(i1 %cond) { +; CHECK: @test10g +; CHECK-NEXT: br i1 %cond, label %T2, label %F2 + br i1 %cond, label %T1, label %F1 + +T1: + %v1 = call i32 @test10f1() + br label %Merge + +; CHECK: %v1 = call i32 @test10f1() +; CHECK-NEXT: call void @f3() +; CHECK-NEXT: ret i32 %v1 + +F1: + %v2 = call i32 @test10f2() + br label %Merge + +Merge: + %B = phi i32 [%v1, %T1], [%v2, %F1] + br i1 %cond, label %T2, label %F2 + +T2: + call void @f3() + ret i32 %B + +F2: + ret i32 %B +} + + +; Impossible conditional constraints should get threaded. BB3 is dead here. +define i32 @test11(i32 %A) { +; CHECK: @test11 +; CHECK-NEXT: icmp +; CHECK-NEXT: br i1 %tmp455, label %BB4, label %BB2 + %tmp455 = icmp eq i32 %A, 42 + br i1 %tmp455, label %BB1, label %BB2 + +BB2: +; CHECK: call i32 @f1() +; CHECK-NEXT: ret i32 %C + %C = call i32 @f1() + ret i32 %C + + +BB1: + %tmp459 = icmp eq i32 %A, 43 + br i1 %tmp459, label %BB3, label %BB4 + +BB3: + call i32 @f2() + ret i32 3 + +BB4: + call void @f3() + ret i32 4 +} + +;; Correlated value through boolean expression. GCC PR18046. +define void @test12(i32 %A) { +; CHECK: @test12 +entry: + %cond = icmp eq i32 %A, 0 + br i1 %cond, label %bb, label %bb1 +; Should branch to the return block instead of through BB1. +; CHECK: entry: +; CHECK-NEXT: %cond = icmp eq i32 %A, 0 +; CHECK-NEXT: br i1 %cond, label %bb1, label %return + +bb: + %B = call i32 @test10f2() + br label %bb1 + +bb1: + %C = phi i32 [ %A, %entry ], [ %B, %bb ] + %cond4 = icmp eq i32 %C, 0 + br i1 %cond4, label %bb2, label %return + +; CHECK: bb1: +; CHECK-NEXT: %B = call i32 @test10f2() +; CHECK-NEXT: %cond4 = icmp eq i32 %B, 0 +; CHECK-NEXT: br i1 %cond4, label %bb2, label %return + +bb2: + %D = call i32 @test10f2() + ret void + +return: + ret void +} + + +;;; Duplicate condition to avoid xor of cond. +;;; TODO: Make this happen. +define i32 @testXX(i1 %cond, i1 %cond2) { +Entry: +; CHECK: @testXX + %v1 = call i32 @f1() + br i1 %cond, label %Merge, label %F1 + +F1: + br label %Merge + +Merge: + %B = phi i1 [true, %Entry], [%cond2, %F1] + %M = icmp eq i32 %v1, 192 + %N = xor i1 %B, %M + br i1 %N, label %T2, label %F2 + +T2: + ret i32 123 + +F2: + ret i32 %v1 +} diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll index 862b403..7e2a2a0 100644 --- a/test/Transforms/JumpThreading/crash.ll +++ b/test/Transforms/JumpThreading/crash.ll @@ -170,3 +170,25 @@ bb32.i: ret i32 1 } + +define fastcc void @test5(i1 %tmp, i32 %tmp1) nounwind ssp { +entry: + br i1 %tmp, label %bb12, label %bb13 + + +bb12: + br label %bb13 + +bb13: + %.lcssa31 = phi i32 [ undef, %bb12 ], [ %tmp1, %entry ] + %A = and i1 undef, undef + br i1 %A, label %bb15, label %bb61 + +bb15: + ret void + + +bb61: + ret void +} + diff --git a/test/Transforms/LCSSA/indirectbr.ll b/test/Transforms/LCSSA/indirectbr.ll new file mode 100644 index 0000000..9656448 --- /dev/null +++ b/test/Transforms/LCSSA/indirectbr.ll @@ -0,0 +1,542 @@ +; RUN: opt < %s -lcssa -verify-loop-info -verify-dom-info -disable-output +; PR5437 + +; LCSSA should work correctly in the case of an indirectbr that exits +; the loop, and the loop has exits with predecessors not within the loop +; (and btw these edges are unsplittable due to the indirectbr). + +define i32 @js_Interpret() nounwind { +entry: + br i1 undef, label %"4", label %"3" + +"3": ; preds = %entry + ret i32 0 + +"4": ; preds = %entry + br i1 undef, label %"6", label %"5" + +"5": ; preds = %"4" + unreachable + +"6": ; preds = %"4" + br i1 undef, label %"10", label %"13" + +"10": ; preds = %"6" + br i1 undef, label %"22", label %"15" + +"13": ; preds = %"6" + unreachable + +"15": ; preds = %"23", %"10" + unreachable + +"22": ; preds = %"10" + br label %"23" + +"23": ; preds = %"1375", %"22" + %0 = phi i32 [ undef, %"22" ], [ %1, %"1375" ] ; <i32> [#uses=1] + indirectbr i8* undef, [label %"15", label %"24", label %"25", label %"26", label %"27", label %"28", label %"29", label %"30", label %"32", label %"32", label %"33", label %"167", label %"173", label %"173", label %"173", label %"173", label %"173", label %"192", label %"193", label %"194", label %"196", label %"206", label %"231", label %"241", label %"251", label %"261", label %"307", label %"353", label %"354", label %"355", label %"361", label %"367", label %"400", label %"433", label %"466", label %"499", label %"509", label %"519", label %"529", label %"571", label %"589", label %"607", label %"635", label %"655", label %"664", label %"671", label %"680", label %"687", label %"692", label %"698", label %"704", label %"715", label %"715", label %"716", label %"725", label %"725", label %"725", label %"725", label %"724", label %"724", label %"724", label %"724", label %"737", label %"737", label %"737", label %"737", label %"761", label %"758", label %"759", label %"760", label %"766", label %"763", label %"764", label %"765", label %"771", label %"768", label %"769", label %"770", label %"780", label %"777", label %"778", label %"779", label %"821", label %"826", label %"831", label %"832", label %"833", label %"836", label %"836", label %"886", label %"905", label %"978", label %"978", label %"1136", label %"1166", label %"1179", label %"1201", label %"1212", label %"1212", label %"1274", label %"1284", label %"1284", label %"1346", label %"1347", label %"1348", label %"1349", label %"1350", label %"1353", label %"1353", label %"1353", label %"1355", label %"1355", label %"1357", label %"1357", label %"1358", label %"1359", label %"1374", label %"1375", label %"1376", label %"1377", label %"1378", label %"1379", label %"1386", label %"1395", label %"1394", label %"1425", label %"1426", label %"1440", label %"1449", label %"1455", label %"1461", label %"1471", label %"1482", label %"1484", label %"1486", label %"1489", label %"1489", label %"1492", label %"1494", label %"1494", label %"1497", label %"1499", label %"1499", label %"1515", label %"1546", label %"1546", label %"1566", label %"1584", label %"1587", label %"1591", label %"1605", label %"1609", label %"1609", label %"1640", label %"1648", label %"1651", label %"1703", label %"1710", label %"1718", label %"1724", label %"1725", label %"1726", label %"1727", label %"1728", label %"1731", label %"1732", label %"1733", label %"1734", label %"1735", label %"1741", label %"1750", label %"1752", label %"1754", label %"1755", label %"1757", label %"1759", label %"1761", label %"1764", label %"1764", label %"1766", label %"1768", label %"1775", label %"1775", label %"1781", label %"1781", label %"1790", label %"1827", label %"1836", label %"1836", label %"1845", label %"1845", label %"1848", label %"1849", label %"1851", label %"1853", label %"1856", label %"1861", label %"1861"] + +"24": ; preds = %"23" + unreachable + +"25": ; preds = %"23" + unreachable + +"26": ; preds = %"23" + unreachable + +"27": ; preds = %"23" + unreachable + +"28": ; preds = %"23" + unreachable + +"29": ; preds = %"23" + unreachable + +"30": ; preds = %"23" + unreachable + +"32": ; preds = %"23", %"23" + unreachable + +"33": ; preds = %"23" + unreachable + +"167": ; preds = %"23" + unreachable + +"173": ; preds = %"23", %"23", %"23", %"23", %"23" + unreachable + +"192": ; preds = %"23" + unreachable + +"193": ; preds = %"23" + unreachable + +"194": ; preds = %"23" + unreachable + +"196": ; preds = %"23" + unreachable + +"206": ; preds = %"23" + unreachable + +"231": ; preds = %"23" + unreachable + +"241": ; preds = %"23" + unreachable + +"251": ; preds = %"23" + unreachable + +"261": ; preds = %"23" + unreachable + +"307": ; preds = %"23" + unreachable + +"353": ; preds = %"23" + unreachable + +"354": ; preds = %"23" + unreachable + +"355": ; preds = %"23" + unreachable + +"361": ; preds = %"23" + unreachable + +"367": ; preds = %"23" + unreachable + +"400": ; preds = %"23" + unreachable + +"433": ; preds = %"23" + unreachable + +"466": ; preds = %"23" + unreachable + +"499": ; preds = %"23" + unreachable + +"509": ; preds = %"23" + unreachable + +"519": ; preds = %"23" + unreachable + +"529": ; preds = %"23" + unreachable + +"571": ; preds = %"23" + unreachable + +"589": ; preds = %"23" + unreachable + +"607": ; preds = %"23" + unreachable + +"635": ; preds = %"23" + unreachable + +"655": ; preds = %"23" + unreachable + +"664": ; preds = %"23" + unreachable + +"671": ; preds = %"23" + unreachable + +"680": ; preds = %"23" + unreachable + +"687": ; preds = %"23" + unreachable + +"692": ; preds = %"23" + br label %"1862" + +"698": ; preds = %"23" + unreachable + +"704": ; preds = %"23" + unreachable + +"715": ; preds = %"23", %"23" + unreachable + +"716": ; preds = %"23" + unreachable + +"724": ; preds = %"23", %"23", %"23", %"23" + unreachable + +"725": ; preds = %"23", %"23", %"23", %"23" + unreachable + +"737": ; preds = %"23", %"23", %"23", %"23" + unreachable + +"758": ; preds = %"23" + unreachable + +"759": ; preds = %"23" + unreachable + +"760": ; preds = %"23" + unreachable + +"761": ; preds = %"23" + unreachable + +"763": ; preds = %"23" + unreachable + +"764": ; preds = %"23" + unreachable + +"765": ; preds = %"23" + br label %"766" + +"766": ; preds = %"765", %"23" + unreachable + +"768": ; preds = %"23" + unreachable + +"769": ; preds = %"23" + unreachable + +"770": ; preds = %"23" + unreachable + +"771": ; preds = %"23" + unreachable + +"777": ; preds = %"23" + unreachable + +"778": ; preds = %"23" + unreachable + +"779": ; preds = %"23" + unreachable + +"780": ; preds = %"23" + unreachable + +"821": ; preds = %"23" + unreachable + +"826": ; preds = %"23" + unreachable + +"831": ; preds = %"23" + unreachable + +"832": ; preds = %"23" + unreachable + +"833": ; preds = %"23" + unreachable + +"836": ; preds = %"23", %"23" + unreachable + +"886": ; preds = %"23" + unreachable + +"905": ; preds = %"23" + unreachable + +"978": ; preds = %"23", %"23" + unreachable + +"1136": ; preds = %"23" + unreachable + +"1166": ; preds = %"23" + unreachable + +"1179": ; preds = %"23" + unreachable + +"1201": ; preds = %"23" + unreachable + +"1212": ; preds = %"23", %"23" + unreachable + +"1274": ; preds = %"23" + unreachable + +"1284": ; preds = %"23", %"23" + unreachable + +"1346": ; preds = %"23" + unreachable + +"1347": ; preds = %"23" + unreachable + +"1348": ; preds = %"23" + unreachable + +"1349": ; preds = %"23" + unreachable + +"1350": ; preds = %"23" + unreachable + +"1353": ; preds = %"23", %"23", %"23" + unreachable + +"1355": ; preds = %"23", %"23" + unreachable + +"1357": ; preds = %"23", %"23" + unreachable + +"1358": ; preds = %"23" + unreachable + +"1359": ; preds = %"23" + unreachable + +"1374": ; preds = %"23" + unreachable + +"1375": ; preds = %"23" + %1 = zext i8 undef to i32 ; <i32> [#uses=1] + br label %"23" + +"1376": ; preds = %"23" + unreachable + +"1377": ; preds = %"23" + unreachable + +"1378": ; preds = %"23" + unreachable + +"1379": ; preds = %"23" + unreachable + +"1386": ; preds = %"23" + unreachable + +"1394": ; preds = %"23" + unreachable + +"1395": ; preds = %"23" + unreachable + +"1425": ; preds = %"23" + unreachable + +"1426": ; preds = %"23" + unreachable + +"1440": ; preds = %"23" + unreachable + +"1449": ; preds = %"23" + unreachable + +"1455": ; preds = %"23" + unreachable + +"1461": ; preds = %"23" + unreachable + +"1471": ; preds = %"23" + unreachable + +"1482": ; preds = %"23" + unreachable + +"1484": ; preds = %"23" + unreachable + +"1486": ; preds = %"23" + unreachable + +"1489": ; preds = %"23", %"23" + unreachable + +"1492": ; preds = %"23" + unreachable + +"1494": ; preds = %"23", %"23" + unreachable + +"1497": ; preds = %"23" + unreachable + +"1499": ; preds = %"23", %"23" + unreachable + +"1515": ; preds = %"23" + unreachable + +"1546": ; preds = %"23", %"23" + unreachable + +"1566": ; preds = %"23" + br i1 undef, label %"1569", label %"1568" + +"1568": ; preds = %"1566" + unreachable + +"1569": ; preds = %"1566" + unreachable + +"1584": ; preds = %"23" + unreachable + +"1587": ; preds = %"23" + unreachable + +"1591": ; preds = %"23" + unreachable + +"1605": ; preds = %"23" + unreachable + +"1609": ; preds = %"23", %"23" + unreachable + +"1640": ; preds = %"23" + unreachable + +"1648": ; preds = %"23" + unreachable + +"1651": ; preds = %"23" + unreachable + +"1703": ; preds = %"23" + unreachable + +"1710": ; preds = %"23" + unreachable + +"1718": ; preds = %"23" + unreachable + +"1724": ; preds = %"23" + unreachable + +"1725": ; preds = %"23" + unreachable + +"1726": ; preds = %"23" + unreachable + +"1727": ; preds = %"23" + unreachable + +"1728": ; preds = %"23" + unreachable + +"1731": ; preds = %"23" + unreachable + +"1732": ; preds = %"23" + unreachable + +"1733": ; preds = %"23" + unreachable + +"1734": ; preds = %"23" + unreachable + +"1735": ; preds = %"23" + unreachable + +"1741": ; preds = %"23" + unreachable + +"1750": ; preds = %"23" + unreachable + +"1752": ; preds = %"23" + unreachable + +"1754": ; preds = %"23" + unreachable + +"1755": ; preds = %"23" + unreachable + +"1757": ; preds = %"23" + unreachable + +"1759": ; preds = %"23" + unreachable + +"1761": ; preds = %"23" + unreachable + +"1764": ; preds = %"23", %"23" + %2 = icmp eq i32 %0, 168 ; <i1> [#uses=0] + unreachable + +"1766": ; preds = %"23" + unreachable + +"1768": ; preds = %"23" + unreachable + +"1775": ; preds = %"23", %"23" + unreachable + +"1781": ; preds = %"23", %"23" + unreachable + +"1790": ; preds = %"23" + unreachable + +"1827": ; preds = %"23" + unreachable + +"1836": ; preds = %"23", %"23" + br label %"1862" + +"1845": ; preds = %"23", %"23" + unreachable + +"1848": ; preds = %"23" + unreachable + +"1849": ; preds = %"23" + unreachable + +"1851": ; preds = %"23" + unreachable + +"1853": ; preds = %"23" + unreachable + +"1856": ; preds = %"23" + unreachable + +"1861": ; preds = %"23", %"23" + unreachable + +"41": ; preds = %"23", %"23" + unreachable + +"1862": ; preds = %"1836", %"692" + unreachable +} diff --git a/test/Transforms/LoopSimplify/indirectbr.ll b/test/Transforms/LoopSimplify/indirectbr.ll new file mode 100644 index 0000000..b023847 --- /dev/null +++ b/test/Transforms/LoopSimplify/indirectbr.ll @@ -0,0 +1,83 @@ +; RUN: opt < %s -loopsimplify -lcssa -verify-loop-info -verify-dom-info -S \ +; RUN: | grep -F {indirectbr i8* %x, \[label %L0, label %L1\]} \ +; RUN: | count 6 + +; LoopSimplify should not try to transform loops when indirectbr is involved. + +define void @entry(i8* %x) { +entry: + indirectbr i8* %x, [ label %L0, label %L1 ] + +L0: + br label %L0 + +L1: + ret void +} + +define void @backedge(i8* %x) { +entry: + br label %L0 + +L0: + br label %L1 + +L1: + indirectbr i8* %x, [ label %L0, label %L1 ] +} + +define i64 @exit(i8* %x) { +entry: + br label %L2 + +L2: + %z = bitcast i64 0 to i64 + indirectbr i8* %x, [ label %L0, label %L1 ] + +L0: + br label %L2 + +L1: + ret i64 %z +} + +define i64 @criticalexit(i8* %x, i1 %a) { +entry: + br i1 %a, label %L1, label %L2 + +L2: + %z = bitcast i64 0 to i64 + indirectbr i8* %x, [ label %L0, label %L1 ] + +L0: + br label %L2 + +L1: + %y = phi i64 [ %z, %L2 ], [ 1, %entry ] + ret i64 %y +} + +define i64 @exit_backedge(i8* %x) { +entry: + br label %L0 + +L0: + %z = bitcast i64 0 to i64 + indirectbr i8* %x, [ label %L0, label %L1 ] + +L1: + ret i64 %z +} + +define i64 @criticalexit_backedge(i8* %x, i1 %a) { +entry: + br i1 %a, label %L0, label %L1 + +L0: + %z = bitcast i64 0 to i64 + indirectbr i8* %x, [ label %L0, label %L1 ] + +L1: + %y = phi i64 [ %z, %L0 ], [ 1, %entry ] + ret i64 %y +} diff --git a/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll b/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll new file mode 100644 index 0000000..4032a59 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2009-11-10-LSRCrash.ll @@ -0,0 +1,130 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin11 + +define void @_ZN4llvm20SelectionDAGLowering14visitInlineAsmENS_8CallSiteE() nounwind ssp align 2 { +entry: + br i1 undef, label %bb3.i, label %bb4.i + +bb3.i: ; preds = %entry + unreachable + +bb4.i: ; preds = %entry + br i1 undef, label %bb.i.i, label %_ZNK4llvm8CallSite14getCalledValueEv.exit + +bb.i.i: ; preds = %bb4.i + unreachable + +_ZNK4llvm8CallSite14getCalledValueEv.exit: ; preds = %bb4.i + br i1 undef, label %_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit, label %bb6.i + +bb6.i: ; preds = %_ZNK4llvm8CallSite14getCalledValueEv.exit + unreachable + +_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit: ; preds = %_ZNK4llvm8CallSite14getCalledValueEv.exit + br i1 undef, label %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit, label %bb.i + +bb.i: ; preds = %_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit + br label %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit + +_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit: ; preds = %bb.i, %_ZN4llvm4castINS_9InlineAsmEPNS_5ValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS6_.exit + br i1 undef, label %bb50, label %bb27 + +bb27: ; preds = %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit + br i1 undef, label %bb1.i727, label %bb.i.i726 + +bb.i.i726: ; preds = %bb27 + unreachable + +bb1.i727: ; preds = %bb27 + unreachable + +bb50: ; preds = %_ZL25hasInlineAsmMemConstraintRSt6vectorIN4llvm9InlineAsm14ConstraintInfoESaIS2_EERKNS0_14TargetLoweringE.exit + br label %bb107 + +bb51: ; preds = %bb107 + br i1 undef, label %bb105, label %bb106 + +bb105: ; preds = %bb51 + unreachable + +bb106: ; preds = %bb51 + br label %bb107 + +bb107: ; preds = %bb106, %bb50 + br i1 undef, label %bb108, label %bb51 + +bb108: ; preds = %bb107 + br i1 undef, label %bb242, label %bb114 + +bb114: ; preds = %bb108 + br i1 undef, label %bb141, label %bb116 + +bb116: ; preds = %bb114 + br i1 undef, label %bb120, label %bb121 + +bb120: ; preds = %bb116 + unreachable + +bb121: ; preds = %bb116 + unreachable + +bb141: ; preds = %bb114 + br i1 undef, label %bb182, label %bb143 + +bb143: ; preds = %bb141 + br label %bb157 + +bb144: ; preds = %bb.i.i.i843 + switch i32 undef, label %bb155 [ + i32 2, label %bb153 + i32 6, label %bb153 + i32 4, label %bb153 + ] + +bb153: ; preds = %bb144, %bb144, %bb144 + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br label %bb157 + +bb155: ; preds = %bb144 + unreachable + +bb157: ; preds = %bb153, %bb143 + %indvar = phi i32 [ %indvar.next, %bb153 ], [ 0, %bb143 ] ; <i32> [#uses=2] + %0 = icmp eq i32 undef, %indvar ; <i1> [#uses=1] + switch i16 undef, label %bb6.i841 [ + i16 9, label %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + i16 26, label %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + ] + +bb6.i841: ; preds = %bb157 + unreachable + +_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit: ; preds = %bb157, %bb157 + br i1 undef, label %bb.i.i.i843, label %bb1.i.i.i844 + +bb.i.i.i843: ; preds = %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + br i1 %0, label %bb158, label %bb144 + +bb1.i.i.i844: ; preds = %_ZN4llvm4castINS_14ConstantSDNodeENS_7SDValueEEENS_10cast_rettyIT_T0_E8ret_typeERKS5_.exit + unreachable + +bb158: ; preds = %bb.i.i.i843 + br i1 undef, label %bb177, label %bb176 + +bb176: ; preds = %bb158 + unreachable + +bb177: ; preds = %bb158 + br i1 undef, label %bb179, label %bb178 + +bb178: ; preds = %bb177 + unreachable + +bb179: ; preds = %bb177 + unreachable + +bb182: ; preds = %bb141 + unreachable + +bb242: ; preds = %bb108 + unreachable +} diff --git a/test/Transforms/LoopStrengthReduce/count-to-zero.ll b/test/Transforms/LoopStrengthReduce/count-to-zero.ll new file mode 100644 index 0000000..8cc3b5c --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/count-to-zero.ll @@ -0,0 +1,42 @@ +; RUN: opt < %s -loop-reduce -S | FileCheck %s +; rdar://7382068 + +define void @t(i32 %c) nounwind optsize { +entry: + br label %bb6 + +bb1: ; preds = %bb6 + %tmp = icmp eq i32 %c_addr.1, 20 ; <i1> [#uses=1] + br i1 %tmp, label %bb2, label %bb3 + +bb2: ; preds = %bb1 + %tmp1 = tail call i32 @f20(i32 %c_addr.1) nounwind ; <i32> [#uses=1] + br label %bb7 + +bb3: ; preds = %bb1 + %tmp2 = icmp slt i32 %c_addr.1, 10 ; <i1> [#uses=1] + %tmp3 = add nsw i32 %c_addr.1, 1 ; <i32> [#uses=1] + %tmp4 = add i32 %c_addr.1, -1 ; <i32> [#uses=1] + %c_addr.1.be = select i1 %tmp2, i32 %tmp3, i32 %tmp4 ; <i32> [#uses=1] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] +; CHECK: sub i32 %lsr.iv, 1 + br label %bb6 + +bb6: ; preds = %bb3, %entry + %indvar = phi i32 [ %indvar.next, %bb3 ], [ 0, %entry ] ; <i32> [#uses=2] + %c_addr.1 = phi i32 [ %c_addr.1.be, %bb3 ], [ %c, %entry ] ; <i32> [#uses=7] + %tmp5 = icmp eq i32 %indvar, 9999 ; <i1> [#uses=1] +; CHECK: icmp eq i32 %lsr.iv, 0 + %tmp6 = icmp eq i32 %c_addr.1, 100 ; <i1> [#uses=1] + %or.cond = or i1 %tmp5, %tmp6 ; <i1> [#uses=1] + br i1 %or.cond, label %bb7, label %bb1 + +bb7: ; preds = %bb6, %bb2 + %c_addr.0 = phi i32 [ %tmp1, %bb2 ], [ %c_addr.1, %bb6 ] ; <i32> [#uses=1] + tail call void @bar(i32 %c_addr.0) nounwind + ret void +} + +declare i32 @f20(i32) + +declare void @bar(i32) diff --git a/test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll b/test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll new file mode 100644 index 0000000..4ad5d14 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -loop-reduce -S | FileCheck %s + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind ssp { +entry: + br i1 undef, label %bb4.preheader, label %bb.nph8 + +bb4.preheader: ; preds = %entry + br label %bb4 + +bb1: ; preds = %bb4 + br i1 undef, label %bb.nph8, label %bb3 + +bb3: ; preds = %bb1 + %phitmp = add i32 %indvar, 1 ; <i32> [#uses=1] + br label %bb4 + +bb4: ; preds = %bb3, %bb4.preheader +; CHECK: %lsr.iv = phi +; CHECK: %lsr.iv.next = add i32 %lsr.iv, 1 +; CHECK: %0 = icmp slt i32 %lsr.iv.next, %argc + %indvar = phi i32 [ 1, %bb4.preheader ], [ %phitmp, %bb3 ] ; <i32> [#uses=2] + %0 = icmp slt i32 %indvar, %argc ; <i1> [#uses=1] + br i1 %0, label %bb1, label %bb.nph8 + +bb.nph8: ; preds = %bb4, %bb1, %entry + unreachable +} diff --git a/test/Transforms/SCCP/crash.ll b/test/Transforms/SCCP/crash.ll index e34eaca..2f6da1d 100644 --- a/test/Transforms/SCCP/crash.ll +++ b/test/Transforms/SCCP/crash.ll @@ -22,3 +22,8 @@ bb34: return: ret void } + +define i32 @test2([4 x i32] %A) { + %B = extractvalue [4 x i32] %A, 1 + ret i32 %B +} diff --git a/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll b/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll index 7b8a918..c6ae6ac 100644 --- a/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll +++ b/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -simplifycfg | llvm-dis +; RUN: opt < %s -simplifycfg -disable-output ; PR3016 ; Dead use caused invariant violation. diff --git a/test/Transforms/SimplifyLibCalls/memcmp.ll b/test/Transforms/SimplifyLibCalls/memcmp.ll index 7008736..ed7bcac 100644 --- a/test/Transforms/SimplifyLibCalls/memcmp.ll +++ b/test/Transforms/SimplifyLibCalls/memcmp.ll @@ -17,6 +17,10 @@ define void @test(i8* %P, i8* %Q, i32 %N, i32* %IP, i1* %BP) { %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) + volatile store i32 %F, i32* %IP ret void } diff --git a/test/Transforms/TailCallElim/nocapture.ll b/test/Transforms/TailCallElim/nocapture.ll new file mode 100644 index 0000000..87cb9dd --- /dev/null +++ b/test/Transforms/TailCallElim/nocapture.ll @@ -0,0 +1,25 @@ +; RUN: opt %s -tailcallelim -S | FileCheck %s +; XFAIL: * + +declare void @use(i8* nocapture, i8* nocapture) + +define i8* @foo(i8* nocapture %A, i1 %cond) { +; CHECK: tailrecurse: +; CHECK: %A.tr = phi i8* [ %A, %0 ], [ %B, %cond_true ] +; CHECK: %cond.tr = phi i1 [ %cond, %0 ], [ false, %cond_true ] + %B = alloca i8 +; CHECK: %B = alloca i8 + br i1 %cond, label %cond_true, label %cond_false +; CHECK: br i1 %cond.tr, label %cond_true, label %cond_false +cond_true: +; CHECK: cond_true: +; CHECK: br label %tailrecurse + call i8* @foo(i8* %B, i1 false) + ret i8* null +cond_false: +; CHECK: cond_false + call void @use(i8* %A, i8* %B) +; CHECK: tail call void @use(i8* %A.tr, i8* %B) + ret i8* null +; CHECK: ret i8* null +} diff --git a/test/Transforms/TailCallElim/switch.ll b/test/Transforms/TailCallElim/switch.ll new file mode 100644 index 0000000..3388431 --- /dev/null +++ b/test/Transforms/TailCallElim/switch.ll @@ -0,0 +1,34 @@ +; RUN: opt %s -tailcallelim -S | FileCheck %s + +define i64 @fib(i64 %n) nounwind readnone { +; CHECK: @fib +entry: +; CHECK: tailrecurse: +; CHECK: %accumulator.tr = phi i64 [ %n, %entry ], [ %3, %bb1 ] +; CHECK: %n.tr = phi i64 [ %n, %entry ], [ %2, %bb1 ] + switch i64 %n, label %bb1 [ +; CHECK: switch i64 %n.tr, label %bb1 [ + i64 0, label %bb2 + i64 1, label %bb2 + ] + +bb1: +; CHECK: bb1: + %0 = add i64 %n, -1 +; CHECK: %0 = add i64 %n.tr, -1 + %1 = tail call i64 @fib(i64 %0) nounwind +; CHECK: %1 = tail call i64 @fib(i64 %0) + %2 = add i64 %n, -2 +; CHECK: %2 = add i64 %n.tr, -2 + %3 = tail call i64 @fib(i64 %2) nounwind +; CHECK-NOT: tail call i64 @fib + %4 = add nsw i64 %3, %1 +; CHECK: add nsw i64 %accumulator.tr, %1 + ret i64 %4 +; CHECK: br label %tailrecurse + +bb2: +; CHECK: bb2: + ret i64 %n +; CHECK: ret i64 %accumulator.tr +} |