diff options
author | Shih-wei Liao <sliao@google.com> | 2010-02-10 11:10:31 -0800 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-02-10 11:10:31 -0800 |
commit | e264f62ca09a8f65c87a46d562a4d0f9ec5d457e (patch) | |
tree | 59e3d57ef656cef79afa708ae0a3daf25cd91fcf /test/Transforms/LoopStrengthReduce | |
download | external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.gz external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.bz2 external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.zip |
Check in LLVM r95781.
Diffstat (limited to 'test/Transforms/LoopStrengthReduce')
42 files changed, 1694 insertions, 0 deletions
diff --git a/test/Transforms/LoopStrengthReduce/2005-08-15-AddRecIV.ll b/test/Transforms/LoopStrengthReduce/2005-08-15-AddRecIV.ll new file mode 100644 index 0000000000..1f08a4367b --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2005-08-15-AddRecIV.ll @@ -0,0 +1,57 @@ +; RUN: opt < %s -loop-reduce -disable-output + +define void @try_swap() { +entry: + br i1 false, label %cond_continue.0.i, label %cond_false.0.i +cond_false.0.i: ; preds = %entry + ret void +cond_continue.0.i: ; preds = %entry + br i1 false, label %cond_continue.1.i, label %cond_false.1.i +cond_false.1.i: ; preds = %cond_continue.0.i + ret void +cond_continue.1.i: ; preds = %cond_continue.0.i + br i1 false, label %endif.3.i, label %else.0.i +endif.3.i: ; preds = %cond_continue.1.i + br i1 false, label %my_irand.exit82, label %endif.0.i62 +else.0.i: ; preds = %cond_continue.1.i + ret void +endif.0.i62: ; preds = %endif.3.i + ret void +my_irand.exit82: ; preds = %endif.3.i + br i1 false, label %else.2, label %then.4 +then.4: ; preds = %my_irand.exit82 + ret void +else.2: ; preds = %my_irand.exit82 + br i1 false, label %find_affected_nets.exit, label %loopentry.1.i107.outer.preheader +loopentry.1.i107.outer.preheader: ; preds = %else.2 + ret void +find_affected_nets.exit: ; preds = %else.2 + br i1 false, label %save_region_occ.exit, label %loopentry.1 +save_region_occ.exit: ; preds = %find_affected_nets.exit + br i1 false, label %no_exit.1.preheader, label %loopexit.1 +loopentry.1: ; preds = %find_affected_nets.exit + ret void +no_exit.1.preheader: ; preds = %save_region_occ.exit + ret void +loopexit.1: ; preds = %save_region_occ.exit + br i1 false, label %then.10, label %loopentry.3 +then.10: ; preds = %loopexit.1 + ret void +loopentry.3: ; preds = %endif.16, %loopexit.1 + %indvar342 = phi i32 [ %indvar.next343, %endif.16 ], [ 0, %loopexit.1 ] ; <i32> [#uses=2] + br i1 false, label %loopexit.3, label %endif.16 +endif.16: ; preds = %loopentry.3 + %indvar.next343 = add i32 %indvar342, 1 ; <i32> [#uses=1] + br label %loopentry.3 +loopexit.3: ; preds = %loopentry.3 + br label %loopentry.4 +loopentry.4: ; preds = %loopentry.4, %loopexit.3 + %indvar340 = phi i32 [ 0, %loopexit.3 ], [ %indvar.next341, %loopentry.4 ] ; <i32> [#uses=2] + %tmp. = add i32 %indvar340, %indvar342 ; <i32> [#uses=1] + %tmp.526 = load i32** null ; <i32*> [#uses=1] + %gep.upgrd.1 = zext i32 %tmp. to i64 ; <i64> [#uses=1] + %tmp.528 = getelementptr i32* %tmp.526, i64 %gep.upgrd.1 ; <i32*> [#uses=1] + store i32 0, i32* %tmp.528 + %indvar.next341 = add i32 %indvar340, 1 ; <i32> [#uses=1] + br label %loopentry.4 +} diff --git a/test/Transforms/LoopStrengthReduce/2005-08-17-OutOfLoopVariant.ll b/test/Transforms/LoopStrengthReduce/2005-08-17-OutOfLoopVariant.ll new file mode 100644 index 0000000000..f1c523ae6c --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2005-08-17-OutOfLoopVariant.ll @@ -0,0 +1,17 @@ +; RUN: opt < %s -loop-reduce -disable-output + +define i32 @image_to_texture(i32 %indvar454) { +loopentry.1.outer: + %j.2.1.ph = bitcast i32 %indvar454 to i32 ; <i32> [#uses=1] + br label %loopentry.1 +loopentry.1: ; preds = %loopentry.1, %loopentry.1.outer + %i.3 = phi i32 [ 0, %loopentry.1.outer ], [ %i.3.be, %loopentry.1 ] ; <i32> [#uses=2] + %tmp.390 = load i32* null ; <i32> [#uses=1] + %tmp.392 = mul i32 %tmp.390, %j.2.1.ph ; <i32> [#uses=1] + %tmp.394 = add i32 %tmp.392, %i.3 ; <i32> [#uses=1] + %i.3.be = add i32 %i.3, 1 ; <i32> [#uses=1] + br i1 false, label %loopentry.1, label %label.6 +label.6: ; preds = %loopentry.1 + ret i32 %tmp.394 +} + diff --git a/test/Transforms/LoopStrengthReduce/2005-09-12-UsesOutOutsideOfLoop.ll b/test/Transforms/LoopStrengthReduce/2005-09-12-UsesOutOutsideOfLoop.ll new file mode 100644 index 0000000000..f56a55379c --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2005-09-12-UsesOutOutsideOfLoop.ll @@ -0,0 +1,32 @@ +; RUN: opt < %s -loop-reduce -disable-output + +define void @main() { +entry: + br label %loopentry.0 +loopentry.0: ; preds = %then.5, %entry + %arg_index.1.ph = phi i32 [ 1, %entry ], [ %arg_index.1.ph.be, %then.5 ] ; <i32> [#uses=1] + br i1 false, label %no_exit.0, label %loopexit.0 +no_exit.0: ; preds = %loopentry.0 + %arg_index.1.1 = add i32 0, %arg_index.1.ph ; <i32> [#uses=2] + br i1 false, label %then.i55, label %endif.i61 +then.i55: ; preds = %no_exit.0 + br i1 false, label %then.4, label %else.1 +endif.i61: ; preds = %no_exit.0 + ret void +then.4: ; preds = %then.i55 + %tmp.19993 = add i32 %arg_index.1.1, 2 ; <i32> [#uses=0] + ret void +else.1: ; preds = %then.i55 + br i1 false, label %then.i86, label %loopexit.i97 +then.i86: ; preds = %else.1 + ret void +loopexit.i97: ; preds = %else.1 + br i1 false, label %then.5, label %else.2 +then.5: ; preds = %loopexit.i97 + %arg_index.1.ph.be = add i32 %arg_index.1.1, 2 ; <i32> [#uses=1] + br label %loopentry.0 +else.2: ; preds = %loopexit.i97 + ret void +loopexit.0: ; preds = %loopentry.0 + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/2007-04-23-UseIterator.ll b/test/Transforms/LoopStrengthReduce/2007-04-23-UseIterator.ll new file mode 100644 index 0000000000..8c2cfaf321 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2007-04-23-UseIterator.ll @@ -0,0 +1,71 @@ +; RUN: opt < %s -loop-reduce -disable-output + +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" + +target triple = "i686-apple-darwin9" + +define i8* @foo( i8* %ABC) { +entry: + switch i8 0, label %bb129 [ + i8 0, label %UnifiedReturnBlock + i8 9, label %UnifiedReturnBlock + i8 32, label %UnifiedReturnBlock + i8 35, label %UnifiedReturnBlock + i8 37, label %bb16.preheader + ] + +bb16.preheader: ; preds = %entry + br label %bb16 + +bb16: ; preds = %cond_next102, %bb16.preheader + %indvar = phi i32 [ %indvar.next, %cond_next102 ], [ 0, %bb16.preheader ] ; <i32> [#uses=2] + %ABC.2146.0.rec = mul i32 %indvar, 3 ; <i32> [#uses=1] + br i1 false, label %UnifiedReturnBlock.loopexit, label %cond_next102 + +cond_next102: ; preds = %bb16 + %tmp138145.rec = add i32 %ABC.2146.0.rec, 3 ; <i32> [#uses=1] + %tmp138145 = getelementptr i8* %ABC, i32 %tmp138145.rec ; <i8*> [#uses=4] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + switch i8 0, label %bb129.loopexit [ + i8 0, label %UnifiedReturnBlock.loopexit + i8 9, label %UnifiedReturnBlock.loopexit + i8 32, label %UnifiedReturnBlock.loopexit + i8 35, label %UnifiedReturnBlock.loopexit + i8 37, label %bb16 + ] + +bb129.loopexit: ; preds = %cond_next102 + br label %bb129 + +bb129: ; preds = %bb129.loopexit, %entry + ret i8* null + +UnifiedReturnBlock.loopexit: ; preds = %cond_next102, %cond_next102, %cond_next102, %cond_next102, %bb16 + %UnifiedRetVal.ph = phi i8* [ %tmp138145, %cond_next102 ], [ %tmp138145, %cond_next102 ], [ %tmp138145, %cond_next102 ], [ %tmp138145, %cond_next102 ], [ null, %bb16 ] ; <i8*> [#uses=0] + br label %UnifiedReturnBlock + +UnifiedReturnBlock: ; preds = %UnifiedReturnBlock.loopexit, %entry, %entry, %entry, %entry + ret i8* null +} + +define i8* @bar() { +entry: + switch i8 0, label %bb158 [ + i8 37, label %bb74 + i8 58, label %cond_true + i8 64, label %bb11 + ] + +bb11: ; preds = %entry + ret i8* null + +cond_true: ; preds = %entry + ret i8* null + +bb74: ; preds = %entry + ret i8* null + +bb158: ; preds = %entry + ret i8* null +} + diff --git a/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll b/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll new file mode 100644 index 0000000000..7c7a21c013 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2008-08-06-CmpStride.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -loop-reduce -S | grep ugt +; PR2535 + +@.str = internal constant [4 x i8] c"%d\0A\00" + +declare i32 @printf(i8* noalias , ...) nounwind + +define i32 @main() nounwind { +entry: + br label %forbody + +forbody: + %i.0 = phi i32 [ 0, %entry ], [ %inc, %forbody ] ; <i32>[#uses=3] + %sub14 = sub i32 1027, %i.0 ; <i32> [#uses=1] + %mul15 = mul i32 %sub14, 10 ; <i32> [#uses=1] + %add166 = or i32 %mul15, 1 ; <i32> [#uses=1] * + call i32 (i8*, ...)* @printf( i8* noalias getelementptr ([4 x i8]* @.str, i32 0, i32 0), i32 %add166 ) nounwind + %inc = add i32 %i.0, 1 ; <i32> [#uses=3] + %cmp = icmp ult i32 %inc, 1027 ; <i1> [#uses=1] + br i1 %cmp, label %forbody, label %afterfor + +afterfor: ; preds = %forcond + ret i32 0 +} diff --git a/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll b/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll new file mode 100644 index 0000000000..90477d1069 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -loop-reduce -S | grep add | count 2 +; PR 2662 +@g_3 = common global i16 0 ; <i16*> [#uses=2] +@"\01LC" = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + +define void @func_1() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %l_2.0.reg2mem.0 = phi i16 [ 0, %entry ], [ %t1, %bb ] ; <i16> [#uses=2] + %t0 = shl i16 %l_2.0.reg2mem.0, 1 ; <i16>:0 [#uses=1] + volatile store i16 %t0, i16* @g_3, align 2 + %t1 = add i16 %l_2.0.reg2mem.0, -3 ; <i16>:1 [#uses=2] + %t2 = icmp slt i16 %t1, 1 ; <i1>:2 [#uses=1] + br i1 %t2, label %bb, label %return + +return: ; preds = %bb + ret void +} + +define i32 @main() nounwind { +entry: + tail call void @func_1( ) nounwind + volatile load i16* @g_3, align 2 ; <i16>:0 [#uses=1] + zext i16 %0 to i32 ; <i32>:1 [#uses=1] + tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i32 %1 ) nounwind ; <i32>:2 [#uses=0] + ret i32 0 +} + +declare i32 @printf(i8*, ...) nounwind diff --git a/test/Transforms/LoopStrengthReduce/2008-08-14-ShadowIV.ll b/test/Transforms/LoopStrengthReduce/2008-08-14-ShadowIV.ll new file mode 100644 index 0000000000..c650d8cf76 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2008-08-14-ShadowIV.ll @@ -0,0 +1,99 @@ +; RUN: opt < %s -loop-reduce -S | grep "phi double" | count 1 + +define void @foobar(i32 %n) nounwind { +entry: + icmp eq i32 %n, 0 ; <i1>:0 [#uses=2] + br i1 %0, label %return, label %bb.nph + +bb.nph: ; preds = %entry + %umax = select i1 %0, i32 1, i32 %n ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %i.03 = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3] + tail call void @bar( i32 %i.03 ) nounwind + uitofp i32 %i.03 to double ; <double>:1 [#uses=1] + tail call void @foo( double %1 ) nounwind + %indvar.next = add i32 %i.03, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %umax ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} + +; Unable to eliminate cast because the mantissa bits for double are not enough +; to hold all of i64 IV bits. +define void @foobar2(i64 %n) nounwind { +entry: + icmp eq i64 %n, 0 ; <i1>:0 [#uses=2] + br i1 %0, label %return, label %bb.nph + +bb.nph: ; preds = %entry + %umax = select i1 %0, i64 1, i64 %n ; <i64> [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %i.03 = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i64> [#uses=3] + trunc i64 %i.03 to i32 ; <i32>:1 [#uses=1] + tail call void @bar( i32 %1 ) nounwind + uitofp i64 %i.03 to double ; <double>:2 [#uses=1] + tail call void @foo( double %2 ) nounwind + %indvar.next = add i64 %i.03, 1 ; <i64> [#uses=2] + %exitcond = icmp eq i64 %indvar.next, %umax ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} + +; Unable to eliminate cast due to potentional overflow. +define void @foobar3() nounwind { +entry: + tail call i32 (...)* @nn( ) nounwind ; <i32>:0 [#uses=1] + icmp eq i32 %0, 0 ; <i1>:1 [#uses=1] + br i1 %1, label %return, label %bb + +bb: ; preds = %bb, %entry + %i.03 = phi i32 [ 0, %entry ], [ %3, %bb ] ; <i32> [#uses=3] + tail call void @bar( i32 %i.03 ) nounwind + uitofp i32 %i.03 to double ; <double>:2 [#uses=1] + tail call void @foo( double %2 ) nounwind + add i32 %i.03, 1 ; <i32>:3 [#uses=2] + tail call i32 (...)* @nn( ) nounwind ; <i32>:4 [#uses=1] + icmp ugt i32 %4, %3 ; <i1>:5 [#uses=1] + br i1 %5, label %bb, label %return + +return: ; preds = %bb, %entry + ret void +} + +; Unable to eliminate cast due to overflow. +define void @foobar4() nounwind { +entry: + br label %bb.nph + +bb.nph: ; preds = %entry + br label %bb + +bb: ; preds = %bb, %bb.nph + %i.03 = phi i8 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=3] + %tmp2 = sext i8 %i.03 to i32 ; <i32>:0 [#uses=1] + tail call void @bar( i32 %tmp2 ) nounwind + %tmp3 = uitofp i8 %i.03 to double ; <double>:1 [#uses=1] + tail call void @foo( double %tmp3 ) nounwind + %indvar.next = add i8 %i.03, 1 ; <i32> [#uses=2] + %tmp = sext i8 %indvar.next to i32 + %exitcond = icmp eq i32 %tmp, 32767 ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} + +declare void @bar(i32) + +declare void @foo(double) + +declare i32 @nn(...) + diff --git a/test/Transforms/LoopStrengthReduce/2008-09-09-Overflow.ll b/test/Transforms/LoopStrengthReduce/2008-09-09-Overflow.ll new file mode 100644 index 0000000000..1ee6b5cdf1 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2008-09-09-Overflow.ll @@ -0,0 +1,48 @@ +; RUN: opt < %s -loop-reduce -S | grep phi | count 2 +; PR 2779 +@g_19 = common global i32 0 ; <i32*> [#uses=3] +@"\01LC" = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + +define i32 @func_8(i8 zeroext %p_9) nounwind { +entry: + ret i32 1 +} + +define i32 @func_3(i8 signext %p_5) nounwind { +entry: + ret i32 1 +} + +define void @func_1() nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %indvar = phi i16 [ 0, %entry ], [ %indvar.next, %bb ] ; <i16> [#uses=2] + %tmp = sub i16 0, %indvar ; <i16> [#uses=1] + %tmp27 = trunc i16 %tmp to i8 ; <i8> [#uses=1] + load i32* @g_19, align 4 ; <i32>:0 [#uses=2] + add i32 %0, 1 ; <i32>:1 [#uses=1] + store i32 %1, i32* @g_19, align 4 + trunc i32 %0 to i8 ; <i8>:2 [#uses=1] + tail call i32 @func_8( i8 zeroext %2 ) nounwind ; <i32>:3 [#uses=0] + shl i8 %tmp27, 2 ; <i8>:4 [#uses=1] + add i8 %4, -112 ; <i8>:5 [#uses=1] + tail call i32 @func_3( i8 signext %5 ) nounwind ; <i32>:6 [#uses=0] + %indvar.next = add i16 %indvar, 1 ; <i16> [#uses=2] + %exitcond = icmp eq i16 %indvar.next, -28 ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb + ret void +} + +define i32 @main() nounwind { +entry: + tail call void @func_1( ) nounwind + load i32* @g_19, align 4 ; <i32>:0 [#uses=1] + tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i32 %0 ) nounwind ; <i32>:1 [#uses=0] + ret i32 0 +} + +declare i32 @printf(i8*, ...) nounwind diff --git a/test/Transforms/LoopStrengthReduce/2009-01-13-nonconstant-stride-outside-loop.ll b/test/Transforms/LoopStrengthReduce/2009-01-13-nonconstant-stride-outside-loop.ll new file mode 100644 index 0000000000..b2cf818dc4 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2009-01-13-nonconstant-stride-outside-loop.ll @@ -0,0 +1,39 @@ +; RUN: opt < %s -loop-reduce -S | grep phi | count 1 +; RUN: opt < %s -loop-reduce -S | grep mul | count 1 +; ModuleID = '<stdin>' +; Make sure examining a fuller expression outside the loop doesn't cause us to create a second +; IV of stride %3. +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 = "i386-apple-darwin9.5" + %struct.anon = type { %struct.obj*, %struct.obj* } + %struct.obj = type { i16, i16, { %struct.anon } } +@heap_size = external global i32 ; <i32*> [#uses=1] +@"\01LC85" = external constant [39 x i8] ; <[39 x i8]*> [#uses=1] + +declare i32 @sprintf(i8*, i8*, ...) nounwind + +define %struct.obj* @gc_status(%struct.obj* %args) nounwind { +entry: + br label %bb1.i + +bb.i2: ; preds = %bb2.i3 + %indvar.next24 = add i32 %m.0.i, 1 ; <i32> [#uses=1] + br label %bb1.i + +bb1.i: ; preds = %bb.i2, %entry + %m.0.i = phi i32 [ 0, %entry ], [ %indvar.next24, %bb.i2 ] ; <i32> [#uses=4] + %0 = icmp slt i32 %m.0.i, 0 ; <i1> [#uses=1] + br i1 %0, label %bb2.i3, label %nactive_heaps.exit + +bb2.i3: ; preds = %bb1.i + %1 = load %struct.obj** null, align 4 ; <%struct.obj*> [#uses=1] + %2 = icmp eq %struct.obj* %1, null ; <i1> [#uses=1] + br i1 %2, label %nactive_heaps.exit, label %bb.i2 + +nactive_heaps.exit: ; preds = %bb2.i3, %bb1.i + %3 = load i32* @heap_size, align 4 ; <i32> [#uses=1] + %4 = mul i32 %3, %m.0.i ; <i32> [#uses=1] + %5 = sub i32 %4, 0 ; <i32> [#uses=1] + %6 = tail call i32 (i8*, i8*, ...)* @sprintf(i8* null, i8* getelementptr ([39 x i8]* @"\01LC85", i32 0, i32 0), i32 %m.0.i, i32 0, i32 %5, i32 0) nounwind ; <i32> [#uses=0] + ret %struct.obj* null +} diff --git a/test/Transforms/LoopStrengthReduce/2009-02-09-ivs-different-sizes.ll b/test/Transforms/LoopStrengthReduce/2009-02-09-ivs-different-sizes.ll new file mode 100644 index 0000000000..36cc535451 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2009-02-09-ivs-different-sizes.ll @@ -0,0 +1,33 @@ +; RUN: llc < %s +; This used to crash. +; ModuleID = 'bugpoint-reduced-simplified.bc' +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 @parse_number(i8* nocapture %p) nounwind { +entry: + %shift.0 = select i1 false, i32 4, i32 2 ; <i32> [#uses=1] + br label %bb47 + +bb47: ; preds = %bb47, %entry + br i1 false, label %bb54, label %bb47 + +bb54: ; preds = %bb47 + br i1 false, label %bb56, label %bb66 + +bb56: ; preds = %bb62, %bb54 + %p_addr.0.pn.rec = phi i64 [ %p_addr.6.rec, %bb62 ], [ 0, %bb54 ] ; <i64> [#uses=2] + %ch.6.in.in = phi i8* [ %p_addr.6, %bb62 ], [ null, %bb54 ] ; <i8*> [#uses=0] + %indvar202 = trunc i64 %p_addr.0.pn.rec to i32 ; <i32>[#uses=1] + %frac_bits.0 = mul i32 %indvar202, %shift.0 ; <i32>[#uses=1] + %p_addr.6.rec = add i64 %p_addr.0.pn.rec, 1 ; <i64>[#uses=2] + %p_addr.6 = getelementptr i8* null, i64 %p_addr.6.rec ; <i8*>[#uses=1] + br i1 false, label %bb66, label %bb62 + +bb62: ; preds = %bb56 + br label %bb56 + +bb66: ; preds = %bb56, %bb54 + %frac_bits.1 = phi i32 [ 0, %bb54 ], [ %frac_bits.0, %bb56 ] ; <i32> [#uses=0] + unreachable +} diff --git a/test/Transforms/LoopStrengthReduce/2009-04-28-no-reduce-mul.ll b/test/Transforms/LoopStrengthReduce/2009-04-28-no-reduce-mul.ll new file mode 100644 index 0000000000..002a878b7b --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/2009-04-28-no-reduce-mul.ll @@ -0,0 +1,48 @@ +; RUN: opt < %s -loop-reduce -S | FileCheck %s + +; The multiply in bb2 must not be reduced to an add, as the sext causes the +; %1 argument to become negative after a while. + +; CHECK: sext i8 +; CHECK: mul i32 +; CHECK: store i32 + +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 = "i386-apple-darwin9.6" +@table = common global [32 x [256 x i32]] zeroinitializer, align 32 ; <[32 x [256 x i32]]*> [#uses=2] + +define i32 @main() nounwind { +bb4.thread: + br label %bb2 + +bb2: ; preds = %bb4, %bb2, %bb4.thread + %i.0.reg2mem.0.ph = phi i32 [ 0, %bb4.thread ], [ %i.0.reg2mem.0.ph, %bb2 ], [ %indvar.next9, %bb4 ] ; <i32> [#uses=4] + %j.0.reg2mem.0 = phi i32 [ 0, %bb4.thread ], [ %indvar.next, %bb2 ], [ 0, %bb4 ] ; <i32> [#uses=3] + %0 = trunc i32 %j.0.reg2mem.0 to i8 ; <i8> [#uses=1] + %1 = sext i8 %0 to i32 ; <i32> [#uses=1] + %2 = mul i32 %1, %i.0.reg2mem.0.ph ; <i32> [#uses=1] + %3 = getelementptr [32 x [256 x i32]]* @table, i32 0, i32 %i.0.reg2mem.0.ph, i32 %j.0.reg2mem.0 ; <i32*> [#uses=1] + store i32 %2, i32* %3, align 4 + %indvar.next = add i32 %j.0.reg2mem.0, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next, 256 ; <i1> [#uses=1] + br i1 %exitcond, label %bb4, label %bb2 + +bb4: ; preds = %bb2 + %indvar.next9 = add i32 %i.0.reg2mem.0.ph, 1 ; <i32> [#uses=2] + %exitcond10 = icmp eq i32 %indvar.next9, 32 ; <i1> [#uses=1] + br i1 %exitcond10, label %bb5, label %bb2 + +bb5: ; preds = %bb4 + %4 = load i32* getelementptr ([32 x [256 x i32]]* @table, i32 0, i32 9, i32 132), align 16 ; <i32> [#uses=1] + %5 = icmp eq i32 %4, -1116 ; <i1> [#uses=1] + br i1 %5, label %bb7, label %bb6 + +bb6: ; preds = %bb5 + tail call void @abort() noreturn nounwind + unreachable + +bb7: ; preds = %bb5 + ret i32 0 +} + +declare void @abort() noreturn nounwind 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 0000000000..4032a599e8 --- /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/change-compare-stride-trickiness-0.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll new file mode 100644 index 0000000000..36941ad6d3 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll @@ -0,0 +1,24 @@ +; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmpl \$4} +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-apple-darwin9" + +; This is like change-compare-stride-trickiness-1.ll except the comparison +; happens before the relevant use, so the comparison stride can't be +; easily changed. + +define void @foo() nounwind { +entry: + br label %loop + +loop: + %indvar = phi i32 [ 0, %entry ], [ %i.2.0.us1534, %loop ] ; <i32> [#uses=1] + %i.2.0.us1534 = add i32 %indvar, 1 ; <i32> [#uses=3] + %tmp611.us1535 = icmp eq i32 %i.2.0.us1534, 4 ; <i1> [#uses=2] + %tmp623.us1538 = select i1 %tmp611.us1535, i32 6, i32 0 ; <i32> [#uses=0] + %tmp628.us1540 = shl i32 %i.2.0.us1534, 1 ; <i32> [#uses=1] + %tmp645646647.us1547 = sext i32 %tmp628.us1540 to i64 ; <i64> [#uses=0] + br i1 %tmp611.us1535, label %exit, label %loop + +exit: + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll new file mode 100644 index 0000000000..ea8a259ecd --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll @@ -0,0 +1,26 @@ +; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmp. \$8} +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin9" + +; The comparison happens after the relevant use, so the stride can easily +; be changed. The comparison can be done in a narrower mode than the +; induction variable. + +define void @foo() nounwind { +entry: + br label %loop + +loop: + %indvar = phi i32 [ 0, %entry ], [ %i.2.0.us1534, %loop ] ; <i32> [#uses=1] + %i.2.0.us1534 = add i32 %indvar, 1 ; <i32> [#uses=3] + %tmp628.us1540 = shl i32 %i.2.0.us1534, 1 ; <i32> [#uses=1] + %tmp645646647.us1547 = sext i32 %tmp628.us1540 to i64 ; <i64> [#uses=1] + store i64 %tmp645646647.us1547, i64* null + %tmp611.us1535 = icmp eq i32 %i.2.0.us1534, 4 ; <i1> [#uses=2] + %tmp623.us1538 = select i1 %tmp611.us1535, i32 6, i32 0 ; <i32> [#uses=1] + store i32 %tmp623.us1538, i32* null + br i1 %tmp611.us1535, label %exit, label %loop + +exit: + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-2.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-2.ll new file mode 100644 index 0000000000..ae27383895 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-2.ll @@ -0,0 +1,58 @@ +; RUN: llc < %s +; PR4222 + +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-f80:128:128" +target triple = "x86_64-pc-linux-gnu" +module asm ".ident\09\22$FreeBSD: head/sys/amd64/amd64/minidump_machdep.c 184499 2008-10-31 10:11:35Z kib $\22" + %struct.dumperinfo = type <{ i32 (i8*, i8*, i64, i64, i64)*, i8*, i32, i32, i64, i64 }> + +define void @minidumpsys(%struct.dumperinfo* %di) nounwind { +entry: + br label %if.end + +if.end: ; preds = %if.end52, %entry + br label %for.cond.i.preheader + +for.cond.i.preheader: ; preds = %if.end52, %if.end + %indvar688 = phi i64 [ 0, %if.end ], [ %indvar.next689, %if.end52 ] ; <i64> [#uses=3] + %tmp690 = shl i64 %indvar688, 12 ; <i64> [#uses=1] + %pa.0642 = add i64 %tmp690, 0 ; <i64> [#uses=1] + %indvar688703 = trunc i64 %indvar688 to i32 ; <i32> [#uses=1] + %tmp692693 = add i32 %indvar688703, 1 ; <i32> [#uses=1] + %phitmp = sext i32 %tmp692693 to i64 ; <i64> [#uses=1] + br i1 false, label %if.end52, label %land.lhs.true.i + +land.lhs.true.i: ; preds = %for.cond.i.preheader + %shr2.i = lshr i64 %pa.0642, 18 ; <i64> [#uses=0] + unreachable + +if.end52: ; preds = %for.cond.i.preheader + %phitmp654 = icmp ult i64 %phitmp, 512 ; <i1> [#uses=1] + %indvar.next689 = add i64 %indvar688, 1 ; <i64> [#uses=1] + br i1 %phitmp654, label %for.cond.i.preheader, label %if.end +} + +define void @promote(%struct.dumperinfo* %di) nounwind { +entry: + br label %if.end + +if.end: ; preds = %if.end52, %entry + br label %for.cond.i.preheader + +for.cond.i.preheader: ; preds = %if.end52, %if.end + %indvar688 = phi i32 [ 0, %if.end ], [ %indvar.next689, %if.end52 ] ; <i64> [#uses=3] + %tmp690 = shl i32 %indvar688, 12 ; <i64> [#uses=1] + %pa.0642 = add i32 %tmp690, 0 ; <i64> [#uses=1] + %tmp692693 = add i32 %indvar688, 1 ; <i32> [#uses=1] + %phitmp = sext i32 %tmp692693 to i64 ; <i64> [#uses=1] + br i1 false, label %if.end52, label %land.lhs.true.i + +land.lhs.true.i: ; preds = %for.cond.i.preheader + %shr2.i = lshr i32 %pa.0642, 18 ; <i64> [#uses=0] + unreachable + +if.end52: ; preds = %for.cond.i.preheader + %phitmp654 = icmp ult i64 %phitmp, 512 ; <i1> [#uses=1] + %indvar.next689 = add i32 %indvar688, 1 ; <i64> [#uses=1] + br i1 %phitmp654, label %for.cond.i.preheader, label %if.end +} diff --git a/test/Transforms/LoopStrengthReduce/count-to-zero.ll b/test/Transforms/LoopStrengthReduce/count-to-zero.ll new file mode 100644 index 0000000000..8cc3b5c103 --- /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/dead-phi.ll b/test/Transforms/LoopStrengthReduce/dead-phi.ll new file mode 100644 index 0000000000..07a942f70b --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/dead-phi.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -loop-reduce -S | grep phi | count 1 + +define void @foo(i32 %n) { +entry: + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] + + ; These three instructions form an isolated cycle and can be deleted. + %j = phi i32 [ 0, %entry ], [ %j.y, %loop ] + %j.x = add i32 %j, 1 + %j.y = mul i32 %j.x, 2 + + %i.next = add i32 %i, 1 + %c = icmp ne i32 %i.next, %n + br i1 %c, label %loop, label %exit + +exit: + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/dg.exp b/test/Transforms/LoopStrengthReduce/dg.exp new file mode 100644 index 0000000000..f2005891a5 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/LoopStrengthReduce/different-type-ivs.ll b/test/Transforms/LoopStrengthReduce/different-type-ivs.ll new file mode 100644 index 0000000000..8cdd264591 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/different-type-ivs.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -loop-reduce -disable-output +; Test to make sure that loop-reduce never crashes on IV's +; with different types but identical strides. + +define void @foo() { +entry: + br label %no_exit +no_exit: ; preds = %no_exit, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %no_exit ] ; <i32> [#uses=3] + %indvar.upgrd.1 = trunc i32 %indvar to i16 ; <i16> [#uses=1] + %X.0.0 = mul i16 %indvar.upgrd.1, 1234 ; <i16> [#uses=1] + %tmp. = mul i32 %indvar, 1234 ; <i32> [#uses=1] + %tmp.5 = sext i16 %X.0.0 to i32 ; <i32> [#uses=1] + %tmp.3 = call i32 (...)* @bar( i32 %tmp.5, i32 %tmp. ) ; <i32> [#uses=0] + %tmp.0 = call i1 @pred( ) ; <i1> [#uses=1] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 %tmp.0, label %return, label %no_exit +return: ; preds = %no_exit + ret void +} + +declare i1 @pred() + +declare i32 @bar(...) + diff --git a/test/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll b/test/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll new file mode 100644 index 0000000000..4136486fef --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/dont-hoist-simple-loop-constants.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -loop-reduce -S | \ +; RUN: not grep {bitcast i32 1 to i32} +; END. +; The setlt wants to use a value that is incremented one more than the dominant +; IV. Don't insert the 1 outside the loop, preventing folding it into the add. + +define void @test([700 x i32]* %nbeaux_.0__558, i32* %i_.16574) { +then.0: + br label %no_exit.2 +no_exit.2: ; preds = %no_exit.2, %then.0 + %indvar630 = phi i32 [ 0, %then.0 ], [ %indvar.next631, %no_exit.2 ] ; <i32> [#uses=4] + %gep.upgrd.1 = zext i32 %indvar630 to i64 ; <i64> [#uses=1] + %tmp.38 = getelementptr [700 x i32]* %nbeaux_.0__558, i32 0, i64 %gep.upgrd.1 ; <i32*> [#uses=1] + store i32 0, i32* %tmp.38 + %inc.2 = add i32 %indvar630, 2 ; <i32> [#uses=2] + %tmp.34 = icmp slt i32 %inc.2, 701 ; <i1> [#uses=1] + %indvar.next631 = add i32 %indvar630, 1 ; <i32> [#uses=1] + br i1 %tmp.34, label %no_exit.2, label %loopexit.2.loopexit +loopexit.2.loopexit: ; preds = %no_exit.2 + store i32 %inc.2, i32* %i_.16574 + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/dont_insert_redundant_ops.ll b/test/Transforms/LoopStrengthReduce/dont_insert_redundant_ops.ll new file mode 100644 index 0000000000..90051e3542 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/dont_insert_redundant_ops.ll @@ -0,0 +1,36 @@ +; Check that this test makes INDVAR and related stuff dead. +; RUN: opt < %s -loop-reduce -S | grep phi | count 2 + +declare i1 @pred() + +define void @test1({ i32, i32 }* %P) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=3] + %gep1 = getelementptr { i32, i32 }* %P, i32 %INDVAR, i32 0 ; <i32*> [#uses=1] + store i32 0, i32* %gep1 + %gep2 = getelementptr { i32, i32 }* %P, i32 %INDVAR, i32 1 ; <i32*> [#uses=1] + store i32 0, i32* %gep2 + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + %cond = call i1 @pred( ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + +define void @test2([2 x i32]* %P) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=3] + %gep1 = getelementptr [2 x i32]* %P, i32 %INDVAR, i64 0 ; <i32*> [#uses=1] + store i32 0, i32* %gep1 + %gep2 = getelementptr [2 x i32]* %P, i32 %INDVAR, i64 1 ; <i32*> [#uses=1] + store i32 0, i32* %gep2 + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + %cond = call i1 @pred( ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll b/test/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll new file mode 100644 index 0000000000..20300002eb --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/dont_reduce_bytes.ll @@ -0,0 +1,22 @@ +; Don't reduce the byte access to P[i], at least not on targets that +; support an efficient 'mem[r1+r2]' addressing mode. + +; RUN: opt < %s -loop-reduce -disable-output + + +declare i1 @pred(i32) + +define void @test(i8* %PTR) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2] + %STRRED = getelementptr i8* %PTR, i32 %INDVAR ; <i8*> [#uses=1] + store i8 0, i8* %STRRED + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=2] + ;; cannot eliminate indvar + %cond = call i1 @pred( i32 %INDVAR2 ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/dont_reverse.ll b/test/Transforms/LoopStrengthReduce/dont_reverse.ll new file mode 100644 index 0000000000..4c5db04b21 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/dont_reverse.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -loop-reduce -S \ +; RUN: | grep {icmp eq i2 %lsr.iv.next, %xmp4344} + +; Don't reverse the iteration if the rhs of the compare is defined +; inside the loop. + +define void @Fill_Buffer(i2* %p) nounwind { +entry: + br label %bb8 + +bb8: + %indvar34 = phi i32 [ 0, %entry ], [ %indvar.next35, %bb8 ] + %indvar3451 = trunc i32 %indvar34 to i2 + %xmp4344 = load i2* %p + %xmp104 = icmp eq i2 %indvar3451, %xmp4344 + %indvar.next35 = add i32 %indvar34, 1 + br i1 %xmp104, label %bb10, label %bb8 + +bb10: + unreachable +} diff --git a/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll b/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll new file mode 100644 index 0000000000..abbfda6e92 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll @@ -0,0 +1,21 @@ +; Make sure that the compare instruction occurs after the increment to avoid +; having overlapping live ranges that result in copies. We want the setcc +; instruction immediately before the conditional branch. +; +; RUN: opt -S -loop-reduce %s | FileCheck %s + +define void @foo(float* %D, i32 %E) { +entry: + br label %no_exit +no_exit: ; preds = %no_exit, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %no_exit ] ; <i32> [#uses=1] + volatile store float 0.000000e+00, float* %D + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2] +; CHECK: icmp +; CHECK-NEXT: br i1 + %exitcond = icmp eq i32 %indvar.next, %E ; <i1> [#uses=1] + br i1 %exitcond, label %loopexit, label %no_exit +loopexit: ; preds = %no_exit + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll new file mode 100644 index 0000000000..f86638b0a8 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll @@ -0,0 +1,23 @@ +; Check that the index of 'P[outer]' is pulled out of the loop. +; RUN: opt < %s -loop-reduce -S | \ +; RUN: not grep {getelementptr.*%outer.*%INDVAR} + +declare i1 @pred() + +declare i32 @foo() + +define void @test([10000 x i32]* %P) { +; <label>:0 + %outer = call i32 @foo( ) ; <i32> [#uses=1] + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2] + %STRRED = getelementptr [10000 x i32]* %P, i32 %outer, i32 %INDVAR ; <i32*> [#uses=1] + store i32 0, i32* %STRRED + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + %cond = call i1 @pred( ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll new file mode 100644 index 0000000000..37acf0f61d --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll @@ -0,0 +1,20 @@ +; Check that the index of 'P[outer]' is pulled out of the loop. +; RUN: opt < %s -loop-reduce -S | \ +; RUN: not grep {getelementptr.*%outer.*%INDVAR} + +declare i1 @pred() + +define void @test([10000 x i32]* %P, i32 %outer) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2] + %STRRED = getelementptr [10000 x i32]* %P, i32 %outer, i32 %INDVAR ; <i32*> [#uses=1] + store i32 0, i32* %STRRED + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + %cond = call i1 @pred( ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/nested-reduce.ll b/test/Transforms/LoopStrengthReduce/nested-reduce.ll new file mode 100644 index 0000000000..58b8d3eecd --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/nested-reduce.ll @@ -0,0 +1,49 @@ +; RUN: opt < %s -loop-reduce -S | not grep mul + +; Make sure we don't get a multiply by 6 in this loop. + +define i32 @foo(i32 %A, i32 %B, i32 %C, i32 %D) { +entry: + %tmp.5 = icmp sgt i32 %C, 0 ; <i1> [#uses=1] + %tmp.25 = and i32 %A, 1 ; <i32> [#uses=1] + br label %loopentry.1 +loopentry.1: ; preds = %loopexit.1, %entry + %indvar20 = phi i32 [ 0, %entry ], [ %indvar.next21, %loopexit.1 ] ; <i32> [#uses=2] + %k.1 = phi i32 [ 0, %entry ], [ %k.1.3, %loopexit.1 ] ; <i32> [#uses=2] + br i1 %tmp.5, label %no_exit.1.preheader, label %loopexit.1 +no_exit.1.preheader: ; preds = %loopentry.1 + %i.0.0 = bitcast i32 %indvar20 to i32 ; <i32> [#uses=1] + %tmp.9 = mul i32 %i.0.0, 6 ; <i32> [#uses=1] + br label %no_exit.1.outer +no_exit.1.outer: ; preds = %cond_true, %no_exit.1.preheader + %k.1.2.ph = phi i32 [ %k.1, %no_exit.1.preheader ], [ %k.09, %cond_true ] ; <i32> [#uses=2] + %j.1.2.ph = phi i32 [ 0, %no_exit.1.preheader ], [ %inc.1, %cond_true ] ; <i32> [#uses=1] + br label %no_exit.1 +no_exit.1: ; preds = %cond_continue, %no_exit.1.outer + %indvar.ui = phi i32 [ 0, %no_exit.1.outer ], [ %indvar.next, %cond_continue ] ; <i32> [#uses=2] + %indvar = bitcast i32 %indvar.ui to i32 ; <i32> [#uses=1] + %j.1.2 = add i32 %indvar, %j.1.2.ph ; <i32> [#uses=2] + %tmp.11 = add i32 %j.1.2, %tmp.9 ; <i32> [#uses=1] + %tmp.12 = trunc i32 %tmp.11 to i8 ; <i8> [#uses=1] + %shift.upgrd.1 = zext i8 %tmp.12 to i32 ; <i32> [#uses=1] + %tmp.13 = shl i32 %D, %shift.upgrd.1 ; <i32> [#uses=2] + %tmp.15 = icmp eq i32 %tmp.13, %B ; <i1> [#uses=1] + %inc.1 = add i32 %j.1.2, 1 ; <i32> [#uses=3] + br i1 %tmp.15, label %cond_true, label %cond_continue +cond_true: ; preds = %no_exit.1 + %tmp.26 = and i32 %tmp.25, %tmp.13 ; <i32> [#uses=1] + %k.09 = add i32 %tmp.26, %k.1.2.ph ; <i32> [#uses=2] + %tmp.517 = icmp slt i32 %inc.1, %C ; <i1> [#uses=1] + br i1 %tmp.517, label %no_exit.1.outer, label %loopexit.1 +cond_continue: ; preds = %no_exit.1 + %tmp.519 = icmp slt i32 %inc.1, %C ; <i1> [#uses=1] + %indvar.next = add i32 %indvar.ui, 1 ; <i32> [#uses=1] + br i1 %tmp.519, label %no_exit.1, label %loopexit.1 +loopexit.1: ; preds = %cond_continue, %cond_true, %loopentry.1 + %k.1.3 = phi i32 [ %k.1, %loopentry.1 ], [ %k.09, %cond_true ], [ %k.1.2.ph, %cond_continue ] ; <i32> [#uses=2] + %indvar.next21 = add i32 %indvar20, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next21, 4 ; <i1> [#uses=1] + br i1 %exitcond, label %loopexit.0, label %loopentry.1 +loopexit.0: ; preds = %loopexit.1 + ret i32 %k.1.3 +} diff --git a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll new file mode 100644 index 0000000000..a032cc9735 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll @@ -0,0 +1,24 @@ +; Check that this test makes INDVAR and related stuff dead, because P[indvar] +; gets reduced, making INDVAR dead. + +; RUN: opt < %s -loop-reduce -S | not grep INDVAR + +declare i1 @pred() + +declare i32 @getidx() + +define void @test([10000 x i32]* %P) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2] + %idx = call i32 @getidx( ) ; <i32> [#uses=1] + %STRRED = getelementptr [10000 x i32]* %P, i32 %INDVAR, i32 %idx ; <i32*> [#uses=1] + store i32 0, i32* %STRRED + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + %cond = call i1 @pred( ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/phi_node_update_multiple_preds.ll b/test/Transforms/LoopStrengthReduce/phi_node_update_multiple_preds.ll new file mode 100644 index 0000000000..7ef494debd --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/phi_node_update_multiple_preds.ll @@ -0,0 +1,28 @@ +; RUN: opt < %s -loop-reduce -disable-output +; LSR should not crash on this. + +define fastcc void @loadloop() { +entry: + switch i8 0, label %shortcirc_next [ + i8 32, label %loopexit.2 + i8 59, label %loopexit.2 + ] +shortcirc_next: ; preds = %no_exit.2, %entry + %indvar37 = phi i32 [ 0, %entry ], [ %indvar.next38, %no_exit.2 ] ; <i32> [#uses=3] + %gep.upgrd.1 = zext i32 %indvar37 to i64 ; <i64> [#uses=1] + %wp.2.4 = getelementptr i8* null, i64 %gep.upgrd.1 ; <i8*> [#uses=1] + br i1 false, label %loopexit.2, label %no_exit.2 +no_exit.2: ; preds = %shortcirc_next + %wp.2.4.rec = bitcast i32 %indvar37 to i32 ; <i32> [#uses=1] + %inc.1.rec = add i32 %wp.2.4.rec, 1 ; <i32> [#uses=1] + %inc.1 = getelementptr i8* null, i32 %inc.1.rec ; <i8*> [#uses=2] + %indvar.next38 = add i32 %indvar37, 1 ; <i32> [#uses=1] + switch i8 0, label %shortcirc_next [ + i8 32, label %loopexit.2 + i8 59, label %loopexit.2 + ] +loopexit.2: ; preds = %no_exit.2, %no_exit.2, %shortcirc_next, %entry, %entry + %wp.2.7 = phi i8* [ null, %entry ], [ null, %entry ], [ %wp.2.4, %shortcirc_next ], [ %inc.1, %no_exit.2 ], [ %inc.1, %no_exit.2 ] ; <i8*> [#uses=0] + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/pr2537.ll b/test/Transforms/LoopStrengthReduce/pr2537.ll new file mode 100644 index 0000000000..73c3152d30 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/pr2537.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -loop-reduce -disable-output +; PR 2537 + +define void @a() { +entry: + br label %dobody + +dobody: ; preds = %dobody, %entry + %y.0 = phi i128 [ 0, %entry ], [ %add, %dobody ] + %x.0 = phi i128 [ 0, %entry ], [ %add2, %dobody ] + %add = add i128 %y.0, shl (i128 1, i128 64) + %add2 = add i128 %x.0, shl (i128 1, i128 48) + call void @b( i128 %add ) + %cmp = icmp ult i128 %add2, shl (i128 1, i128 64) + br i1 %cmp, label %dobody, label %afterdo + +afterdo: ; preds = %dobody + ret void +} + +declare void @b(i128 %add)
\ No newline at end of file diff --git a/test/Transforms/LoopStrengthReduce/pr2570.ll b/test/Transforms/LoopStrengthReduce/pr2570.ll new file mode 100644 index 0000000000..aafd24ebba --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/pr2570.ll @@ -0,0 +1,287 @@ +; RUN: opt < %s -loop-reduce -S | grep {phi\\>} | count 10 +; PR2570 + +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" +target triple = "i386-pc-linux-gnu" +@g_14 = internal global i32 1 ; <i32*> [#uses=1] +@g_39 = internal global i16 -5 ; <i16*> [#uses=2] +@g_43 = internal global i32 -6 ; <i32*> [#uses=3] +@g_33 = internal global i32 -1269044541 ; <i32*> [#uses=1] +@g_137 = internal global i32 8 ; <i32*> [#uses=1] +@g_82 = internal global i32 -5 ; <i32*> [#uses=3] +@g_91 = internal global i32 1 ; <i32*> [#uses=1] +@g_197 = internal global i32 1 ; <i32*> [#uses=4] +@g_207 = internal global i32 1 ; <i32*> [#uses=2] +@g_222 = internal global i16 4165 ; <i16*> [#uses=1] +@g_247 = internal global i8 -21 ; <i8*> [#uses=2] +@g_260 = internal global i32 1 ; <i32*> [#uses=2] +@g_221 = internal global i16 -17503 ; <i16*> [#uses=3] +@g_267 = internal global i16 1 ; <i16*> [#uses=1] +@llvm.used = appending global [1 x i8*] [ i8* bitcast (i32 (i32, i32, i16, i32, i8, i32)* @func_44 to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define i32 @func_44(i32 %p_45, i32 %p_46, i16 zeroext %p_48, i32 %p_49, i8 zeroext %p_50, i32 %p_52) nounwind { +entry: + tail call i32 @func_116( i8 zeroext 2 ) nounwind ; <i32>:0 [#uses=0] + tail call i32 @func_63( i16 signext 2 ) nounwind ; <i32>:1 [#uses=1] + load i16* @g_39, align 2 ; <i16>:2 [#uses=1] + tail call i32 @func_63( i16 signext %2 ) nounwind ; <i32>:3 [#uses=1] + trunc i32 %3 to i16 ; <i16>:4 [#uses=1] + and i16 %4, 1 ; <i16>:5 [#uses=1] + trunc i32 %p_52 to i8 ; <i8>:6 [#uses=1] + trunc i32 %1 to i16 ; <i16>:7 [#uses=1] + tail call i32 @func_74( i16 zeroext %5, i8 zeroext %6, i16 zeroext %7, i16 zeroext 0 ) nounwind ; <i32>:8 [#uses=0] + tail call i32 @func_124( i32 544824386 ) nounwind ; <i32>:9 [#uses=0] + zext i8 %p_50 to i32 ; <i32>:10 [#uses=1] + load i32* @g_43, align 4 ; <i32>:11 [#uses=1] + icmp sle i32 %10, %11 ; <i1>:12 [#uses=1] + zext i1 %12 to i32 ; <i32>:13 [#uses=2] + load i8* @g_247, align 1 ; <i8>:14 [#uses=1] + trunc i32 %p_45 to i16 ; <i16>:15 [#uses=1] + zext i8 %14 to i16 ; <i16>:16 [#uses=1] + tail call i32 @func_74( i16 zeroext %15, i8 zeroext 0, i16 zeroext %16, i16 zeroext 23618 ) nounwind ; <i32>:17 [#uses=4] + icmp slt i32 %17, 0 ; <i1>:18 [#uses=1] + br i1 %18, label %bb162, label %bb152 + +bb152: ; preds = %entry + lshr i32 2147483647, %13 ; <i32>:19 [#uses=1] + icmp slt i32 %19, %17 ; <i1>:20 [#uses=1] + select i1 %20, i32 0, i32 %13 ; <i32>:21 [#uses=1] + %.348 = shl i32 %17, %21 ; <i32> [#uses=1] + br label %bb162 + +bb162: ; preds = %bb152, %entry + %.0346 = phi i32 [ %.348, %bb152 ], [ %17, %entry ] ; <i32> [#uses=1] + tail call i32 @func_124( i32 1 ) nounwind ; <i32>:22 [#uses=1] + mul i32 %22, %.0346 ; <i32>:23 [#uses=1] + icmp slt i32 %p_45, 0 ; <i1>:24 [#uses=1] + icmp ugt i32 %p_45, 31 ; <i1>:25 [#uses=1] + %or.cond = or i1 %24, %25 ; <i1> [#uses=1] + br i1 %or.cond, label %bb172, label %bb168 + +bb168: ; preds = %bb162 + lshr i32 2147483647, %p_45 ; <i32>:26 [#uses=1] + shl i32 1392859848, %p_45 ; <i32>:27 [#uses=1] + icmp slt i32 %26, 1392859848 ; <i1>:28 [#uses=1] + %.op355 = add i32 %27, 38978 ; <i32> [#uses=1] + %phitmp = select i1 %28, i32 1392898826, i32 %.op355 ; <i32> [#uses=1] + br label %bb172 + +bb172: ; preds = %bb168, %bb162 + %.0343 = phi i32 [ %phitmp, %bb168 ], [ 1392898826, %bb162 ] ; <i32> [#uses=2] + tail call i32 @func_84( i32 1, i16 zeroext 0, i16 zeroext 8 ) nounwind ; <i32>:29 [#uses=0] + icmp eq i32 %.0343, 0 ; <i1>:30 [#uses=1] + %.0341 = select i1 %30, i32 1, i32 %.0343 ; <i32> [#uses=1] + urem i32 %23, %.0341 ; <i32>:31 [#uses=1] + load i32* @g_137, align 4 ; <i32>:32 [#uses=4] + icmp slt i32 %32, 0 ; <i1>:33 [#uses=1] + br i1 %33, label %bb202, label %bb198 + +bb198: ; preds = %bb172 + %not. = icmp slt i32 %32, 1073741824 ; <i1> [#uses=1] + zext i1 %not. to i32 ; <i32>:34 [#uses=1] + %.351 = shl i32 %32, %34 ; <i32> [#uses=1] + br label %bb202 + +bb202: ; preds = %bb198, %bb172 + %.0335 = phi i32 [ %.351, %bb198 ], [ %32, %bb172 ] ; <i32> [#uses=1] + icmp ne i32 %31, %.0335 ; <i1>:35 [#uses=1] + zext i1 %35 to i32 ; <i32>:36 [#uses=1] + tail call i32 @func_128( i32 %36 ) nounwind ; <i32>:37 [#uses=0] + icmp eq i32 %p_45, 293685862 ; <i1>:38 [#uses=1] + br i1 %38, label %bb205, label %bb311 + +bb205: ; preds = %bb202 + icmp sgt i32 %p_46, 214 ; <i1>:39 [#uses=1] + zext i1 %39 to i32 ; <i32>:40 [#uses=2] + tail call i32 @func_128( i32 %40 ) nounwind ; <i32>:41 [#uses=0] + icmp sgt i32 %p_46, 65532 ; <i1>:42 [#uses=1] + zext i1 %42 to i16 ; <i16>:43 [#uses=1] + tail call i32 @func_74( i16 zeroext 23618, i8 zeroext -29, i16 zeroext %43, i16 zeroext 1 ) nounwind ; <i32>:44 [#uses=2] + tail call i32 @func_103( i16 zeroext -869 ) nounwind ; <i32>:45 [#uses=0] + udiv i32 %44, 34162 ; <i32>:46 [#uses=1] + icmp ult i32 %44, 34162 ; <i1>:47 [#uses=1] + %.0331 = select i1 %47, i32 1, i32 %46 ; <i32> [#uses=1] + urem i32 293685862, %.0331 ; <i32>:48 [#uses=1] + tail call i32 @func_112( i32 %p_52, i16 zeroext 1 ) nounwind ; <i32>:49 [#uses=0] + icmp eq i32 %p_52, 0 ; <i1>:50 [#uses=2] + br i1 %50, label %bb222, label %bb215 + +bb215: ; preds = %bb205 + zext i16 %p_48 to i32 ; <i32>:51 [#uses=1] + icmp eq i16 %p_48, 0 ; <i1>:52 [#uses=1] + %.0329 = select i1 %52, i32 1, i32 %51 ; <i32> [#uses=1] + udiv i32 -1, %.0329 ; <i32>:53 [#uses=1] + icmp eq i32 %53, 0 ; <i1>:54 [#uses=1] + br i1 %54, label %bb222, label %bb223 + +bb222: ; preds = %bb215, %bb205 + br label %bb223 + +bb223: ; preds = %bb222, %bb215 + %iftmp.437.0 = phi i32 [ 0, %bb222 ], [ 1, %bb215 ] ; <i32> [#uses=1] + load i32* @g_91, align 4 ; <i32>:55 [#uses=3] + tail call i32 @func_103( i16 zeroext 4 ) nounwind ; <i32>:56 [#uses=0] + tail call i32 @func_112( i32 0, i16 zeroext -31374 ) nounwind ; <i32>:57 [#uses=0] + load i32* @g_197, align 4 ; <i32>:58 [#uses=1] + tail call i32 @func_124( i32 28156 ) nounwind ; <i32>:59 [#uses=1] + load i32* @g_260, align 4 ; <i32>:60 [#uses=1] + load i32* @g_43, align 4 ; <i32>:61 [#uses=1] + xor i32 %61, %60 ; <i32>:62 [#uses=1] + mul i32 %62, %59 ; <i32>:63 [#uses=1] + trunc i32 %63 to i8 ; <i8>:64 [#uses=1] + trunc i32 %58 to i16 ; <i16>:65 [#uses=1] + tail call i32 @func_74( i16 zeroext 0, i8 zeroext %64, i16 zeroext %65, i16 zeroext 0 ) nounwind ; <i32>:66 [#uses=2] + icmp slt i32 %66, 0 ; <i1>:67 [#uses=1] + icmp slt i32 %55, 0 ; <i1>:68 [#uses=1] + icmp ugt i32 %55, 31 ; <i1>:69 [#uses=1] + or i1 %68, %69 ; <i1>:70 [#uses=1] + %or.cond352 = or i1 %70, %67 ; <i1> [#uses=1] + select i1 %or.cond352, i32 0, i32 %55 ; <i32>:71 [#uses=1] + %.353 = ashr i32 %66, %71 ; <i32> [#uses=2] + load i16* @g_221, align 2 ; <i16>:72 [#uses=1] + zext i16 %72 to i32 ; <i32>:73 [#uses=1] + icmp ugt i32 %.353, 31 ; <i1>:74 [#uses=1] + select i1 %74, i32 0, i32 %.353 ; <i32>:75 [#uses=1] + %.0323 = lshr i32 %73, %75 ; <i32> [#uses=1] + add i32 %.0323, %iftmp.437.0 ; <i32>:76 [#uses=1] + and i32 %48, 255 ; <i32>:77 [#uses=2] + add i32 %77, 2042556439 ; <i32>:78 [#uses=1] + load i32* @g_207, align 4 ; <i32>:79 [#uses=2] + icmp ugt i32 %79, 31 ; <i1>:80 [#uses=1] + select i1 %80, i32 0, i32 %79 ; <i32>:81 [#uses=1] + %.0320 = lshr i32 %77, %81 ; <i32> [#uses=1] + icmp ne i32 %78, %.0320 ; <i1>:82 [#uses=1] + zext i1 %82 to i8 ; <i8>:83 [#uses=1] + tail call i32 @func_25( i8 zeroext %83 ) nounwind ; <i32>:84 [#uses=1] + xor i32 %84, 1 ; <i32>:85 [#uses=1] + load i32* @g_197, align 4 ; <i32>:86 [#uses=1] + add i32 %86, 1 ; <i32>:87 [#uses=1] + add i32 %87, %85 ; <i32>:88 [#uses=1] + icmp ugt i32 %76, %88 ; <i1>:89 [#uses=1] + br i1 %89, label %bb241, label %bb311 + +bb241: ; preds = %bb223 + store i16 -9, i16* @g_221, align 2 + udiv i32 %p_52, 1538244727 ; <i32>:90 [#uses=1] + load i32* @g_207, align 4 ; <i32>:91 [#uses=1] + sub i32 %91, %90 ; <i32>:92 [#uses=1] + load i32* @g_14, align 4 ; <i32>:93 [#uses=1] + trunc i32 %93 to i16 ; <i16>:94 [#uses=1] + trunc i32 %p_46 to i16 ; <i16>:95 [#uses=2] + sub i16 %94, %95 ; <i16>:96 [#uses=1] + load i32* @g_197, align 4 ; <i32>:97 [#uses=1] + trunc i32 %97 to i16 ; <i16>:98 [#uses=1] + tail call i32 @func_55( i32 -346178830, i16 zeroext %98, i16 zeroext %95 ) nounwind ; <i32>:99 [#uses=0] + zext i16 %p_48 to i32 ; <i32>:100 [#uses=1] + load i8* @g_247, align 1 ; <i8>:101 [#uses=1] + zext i8 %101 to i32 ; <i32>:102 [#uses=1] + sub i32 %100, %102 ; <i32>:103 [#uses=1] + tail call i32 @func_55( i32 %103, i16 zeroext -2972, i16 zeroext %96 ) nounwind ; <i32>:104 [#uses=0] + xor i32 %92, 2968 ; <i32>:105 [#uses=1] + load i32* @g_197, align 4 ; <i32>:106 [#uses=1] + icmp ugt i32 %105, %106 ; <i1>:107 [#uses=1] + zext i1 %107 to i32 ; <i32>:108 [#uses=1] + store i32 %108, i32* @g_33, align 4 + br label %bb248 + +bb248: ; preds = %bb284, %bb241 + %p_49_addr.1.reg2mem.0 = phi i32 [ 0, %bb241 ], [ %134, %bb284 ] ; <i32> [#uses=2] + %p_48_addr.2.reg2mem.0 = phi i16 [ %p_48, %bb241 ], [ %p_48_addr.1, %bb284 ] ; <i16> [#uses=1] + %p_46_addr.1.reg2mem.0 = phi i32 [ %p_46, %bb241 ], [ %133, %bb284 ] ; <i32> [#uses=1] + %p_45_addr.1.reg2mem.0 = phi i32 [ %p_45, %bb241 ], [ %p_45_addr.0, %bb284 ] ; <i32> [#uses=2] + tail call i32 @func_63( i16 signext 1 ) nounwind ; <i32>:109 [#uses=1] + icmp eq i32 %109, 0 ; <i1>:110 [#uses=1] + br i1 %110, label %bb272.thread, label %bb255.thread + +bb272.thread: ; preds = %bb248 + store i32 1, i32* @g_82 + load i16* @g_267, align 2 ; <i16>:111 [#uses=1] + icmp eq i16 %111, 0 ; <i1>:112 [#uses=1] + br i1 %112, label %bb311.loopexit.split, label %bb268 + +bb255.thread: ; preds = %bb248 + load i32* @g_260, align 4 ; <i32>:113 [#uses=1] + sub i32 %113, %p_52 ; <i32>:114 [#uses=1] + and i32 %114, -20753 ; <i32>:115 [#uses=1] + icmp ne i32 %115, 0 ; <i1>:116 [#uses=1] + zext i1 %116 to i16 ; <i16>:117 [#uses=1] + store i16 %117, i16* @g_221, align 2 + br label %bb284 + +bb268: ; preds = %bb268, %bb272.thread + %indvar = phi i32 [ 0, %bb272.thread ], [ %g_82.tmp.0, %bb268 ] ; <i32> [#uses=2] + %p_46_addr.0.reg2mem.0 = phi i32 [ %p_46_addr.1.reg2mem.0, %bb272.thread ], [ %119, %bb268 ] ; <i32> [#uses=1] + %g_82.tmp.0 = add i32 %indvar, 1 ; <i32> [#uses=2] + trunc i32 %p_46_addr.0.reg2mem.0 to i16 ; <i16>:118 [#uses=1] + and i32 %g_82.tmp.0, 28156 ; <i32>:119 [#uses=1] + add i32 %indvar, 2 ; <i32>:120 [#uses=4] + icmp sgt i32 %120, -1 ; <i1>:121 [#uses=1] + br i1 %121, label %bb268, label %bb274.split + +bb274.split: ; preds = %bb268 + store i32 %120, i32* @g_82 + br i1 %50, label %bb279, label %bb276 + +bb276: ; preds = %bb274.split + store i16 0, i16* @g_222, align 2 + br label %bb284 + +bb279: ; preds = %bb274.split + icmp eq i32 %120, 0 ; <i1>:122 [#uses=1] + %.0317 = select i1 %122, i32 1, i32 %120 ; <i32> [#uses=1] + udiv i32 -8, %.0317 ; <i32>:123 [#uses=1] + trunc i32 %123 to i16 ; <i16>:124 [#uses=1] + br label %bb284 + +bb284: ; preds = %bb279, %bb276, %bb255.thread + %p_49_addr.0 = phi i32 [ %p_49_addr.1.reg2mem.0, %bb279 ], [ %p_49_addr.1.reg2mem.0, %bb276 ], [ 0, %bb255.thread ] ; <i32> [#uses=1] + %p_48_addr.1 = phi i16 [ %124, %bb279 ], [ %118, %bb276 ], [ %p_48_addr.2.reg2mem.0, %bb255.thread ] ; <i16> [#uses=1] + %p_45_addr.0 = phi i32 [ %p_45_addr.1.reg2mem.0, %bb279 ], [ %p_45_addr.1.reg2mem.0, %bb276 ], [ 8, %bb255.thread ] ; <i32> [#uses=3] + load i32* @g_43, align 4 ; <i32>:125 [#uses=1] + trunc i32 %125 to i8 ; <i8>:126 [#uses=1] + tail call i32 @func_116( i8 zeroext %126 ) nounwind ; <i32>:127 [#uses=0] + lshr i32 65255, %p_45_addr.0 ; <i32>:128 [#uses=1] + icmp ugt i32 %p_45_addr.0, 31 ; <i1>:129 [#uses=1] + %.op = lshr i32 %128, 31 ; <i32> [#uses=1] + %.op.op = xor i32 %.op, 1 ; <i32> [#uses=1] + %.354..lobit.not = select i1 %129, i32 1, i32 %.op.op ; <i32> [#uses=1] + load i16* @g_39, align 2 ; <i16>:130 [#uses=1] + zext i16 %130 to i32 ; <i32>:131 [#uses=1] + icmp slt i32 %.354..lobit.not, %131 ; <i1>:132 [#uses=1] + zext i1 %132 to i32 ; <i32>:133 [#uses=1] + add i32 %p_49_addr.0, 1 ; <i32>:134 [#uses=2] + icmp sgt i32 %134, -1 ; <i1>:135 [#uses=1] + br i1 %135, label %bb248, label %bb307 + +bb307: ; preds = %bb284 + tail call i32 @func_103( i16 zeroext 0 ) nounwind ; <i32>:136 [#uses=0] + ret i32 %40 + +bb311.loopexit.split: ; preds = %bb272.thread + store i32 1, i32* @g_82 + ret i32 1 + +bb311: ; preds = %bb223, %bb202 + %.0 = phi i32 [ 1, %bb202 ], [ 0, %bb223 ] ; <i32> [#uses=1] + ret i32 %.0 +} + +declare i32 @func_25(i8 zeroext ) nounwind + +declare i32 @func_55(i32, i16 zeroext , i16 zeroext ) nounwind + +declare i32 @func_63(i16 signext ) nounwind + +declare i32 @func_74(i16 zeroext , i8 zeroext , i16 zeroext , i16 zeroext ) nounwind + +declare i32 @func_84(i32, i16 zeroext , i16 zeroext ) nounwind + +declare i32 @func_103(i16 zeroext ) nounwind + +declare i32 @func_124(i32) nounwind + +declare i32 @func_128(i32) nounwind + +declare i32 @func_116(i8 zeroext ) nounwind + +declare i32 @func_112(i32, i16 zeroext ) nounwind diff --git a/test/Transforms/LoopStrengthReduce/pr3086.ll b/test/Transforms/LoopStrengthReduce/pr3086.ll new file mode 100644 index 0000000000..599633a11f --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/pr3086.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -loop-reduce +; RUN: opt < %s -analyze -scalar-evolution +; PR 3086 + + %struct.Cls = type { i32, i8, [2 x %struct.Cls*], [2 x %struct.Lit*] } + %struct.Lit = type { i8 } + +define fastcc i64 @collect_clauses() nounwind { +entry: + br label %bb11 + +bb5: ; preds = %bb9 + %0 = load %struct.Lit** %storemerge, align 8 ; <%struct.Lit*> [#uses=0] + %indvar.next8 = add i64 %storemerge.rec, 1 ; <i64> [#uses=1] + br label %bb9 + +bb9: ; preds = %bb22, %bb5 + %storemerge.rec = phi i64 [ %indvar.next8, %bb5 ], [ 0, %bb22 ] ; <i64> [#uses=2] + %storemerge = getelementptr %struct.Lit** null, i64 %storemerge.rec ; <%struct.Lit**> [#uses=2] + %1 = icmp ugt %struct.Lit** null, %storemerge ; <i1> [#uses=1] + br i1 %1, label %bb5, label %bb22 + +bb11: ; preds = %bb22, %entry + %2 = load %struct.Cls** null, align 8 ; <%struct.Cls*> [#uses=0] + br label %bb22 + +bb22: ; preds = %bb11, %bb9 + br i1 false, label %bb11, label %bb9 +} diff --git a/test/Transforms/LoopStrengthReduce/pr3399.ll b/test/Transforms/LoopStrengthReduce/pr3399.ll new file mode 100644 index 0000000000..b809007fea --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/pr3399.ll @@ -0,0 +1,32 @@ +; RUN: opt < %s -loop-reduce | llvm-dis +; PR3399 + +@g_53 = external global i32 ; <i32*> [#uses=1] + +define i32 @foo() nounwind { +bb5.thread: + br label %bb + +bb: ; preds = %bb5, %bb5.thread + %indvar = phi i32 [ 0, %bb5.thread ], [ %indvar.next, %bb5 ] ; <i32> [#uses=2] + br i1 false, label %bb5, label %bb1 + +bb1: ; preds = %bb + %l_2.0.reg2mem.0 = sub i32 0, %indvar ; <i32> [#uses=1] + %0 = volatile load i32* @g_53, align 4 ; <i32> [#uses=1] + %1 = trunc i32 %l_2.0.reg2mem.0 to i16 ; <i16> [#uses=1] + %2 = trunc i32 %0 to i16 ; <i16> [#uses=1] + %3 = mul i16 %2, %1 ; <i16> [#uses=1] + %4 = icmp eq i16 %3, 0 ; <i1> [#uses=1] + br i1 %4, label %bb7, label %bb2 + +bb2: ; preds = %bb2, %bb1 + br label %bb2 + +bb5: ; preds = %bb + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br label %bb + +bb7: ; preds = %bb1 + ret i32 1 +} diff --git a/test/Transforms/LoopStrengthReduce/pr3571.ll b/test/Transforms/LoopStrengthReduce/pr3571.ll new file mode 100644 index 0000000000..9ad27d5ff1 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/pr3571.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -loop-reduce | llvm-dis +; PR3571 + +target triple = "i386-mingw32" +define void @_ZNK18qdesigner_internal10TreeWidget12drawBranchesEP8QPainterRK5QRectRK11QModelIndex() nounwind { +entry: + br label %_ZNK11QModelIndex7isValidEv.exit.i + +bb.i: ; preds = %_ZNK11QModelIndex7isValidEv.exit.i + %indvar.next = add i32 %result.0.i, 1 ; <i32> [#uses=1] + br label %_ZNK11QModelIndex7isValidEv.exit.i + +_ZNK11QModelIndex7isValidEv.exit.i: ; preds = %bb.i, %entry + %result.0.i = phi i32 [ 0, %entry ], [ %indvar.next, %bb.i ] ; <i32> [#uses=2] + %0 = load i32** null, align 4 ; <%struct.QAbstractItemDelegate*> [#uses=0] + br i1 false, label %_ZN18qdesigner_internalL5levelEP18QAbstractItemModelRK11QModelIndex.exit, label %bb.i + +_ZN18qdesigner_internalL5levelEP18QAbstractItemModelRK11QModelIndex.exit: ; preds = %_ZNK11QModelIndex7isValidEv.exit.i + %1 = call i32 @_ZNK9QTreeView11indentationEv(i32* null) nounwind ; <i32> [#uses=1] + %2 = mul i32 %1, %result.0.i ; <i32> [#uses=1] + %3 = add i32 %2, -2 ; <i32> [#uses=1] + %4 = add i32 %3, 0 ; <i32> [#uses=1] + store i32 %4, i32* null, align 8 + unreachable +} + +declare i32 @_ZNK9QTreeView11indentationEv(i32*) diff --git a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll new file mode 100644 index 0000000000..c91f5cd4ca --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -analyze -iv-users | grep {Stride i64 {3,+,2}<%loop>:} + +; The value of %r is dependent on a polynomial iteration expression. + +define i64 @foo(i64 %n) { +entry: + br label %loop + +loop: + %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ] + %indvar.next = add i64 %indvar, 1 + %c = icmp eq i64 %indvar.next, %n + br i1 %c, label %exit, label %loop + +exit: + %r = mul i64 %indvar.next, %indvar.next + ret i64 %r +} diff --git a/test/Transforms/LoopStrengthReduce/related_indvars.ll b/test/Transforms/LoopStrengthReduce/related_indvars.ll new file mode 100644 index 0000000000..12942bf10a --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/related_indvars.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -loop-reduce -S | grep phi | count 1 + +; This should only result in one PHI node! + +; void foo(double *D, double *E, double F) { +; while (D != E) +; *D++ = F; +; } + +define void @foo(double* %D, double* %E, double %F) nounwind { +entry: + %tmp.24 = icmp eq double* %D, %E ; <i1> [#uses=1] + br i1 %tmp.24, label %return, label %no_exit +no_exit: ; preds = %no_exit, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %no_exit ] ; <i32> [#uses=2] + %D_addr.0.0.rec = bitcast i32 %indvar to i32 ; <i32> [#uses=2] + %D_addr.0.0 = getelementptr double* %D, i32 %D_addr.0.0.rec ; <double*> [#uses=1] + %inc.rec = add i32 %D_addr.0.0.rec, 1 ; <i32> [#uses=1] + %inc = getelementptr double* %D, i32 %inc.rec ; <double*> [#uses=1] + store double %F, double* %D_addr.0.0 + %tmp.2 = icmp eq double* %inc, %E ; <i1> [#uses=1] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 %tmp.2, label %return, label %no_exit +return: ; preds = %no_exit, %entry + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/remove_indvar.ll b/test/Transforms/LoopStrengthReduce/remove_indvar.ll new file mode 100644 index 0000000000..53f4b9d5b9 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/remove_indvar.ll @@ -0,0 +1,19 @@ +; Check that this test makes INDVAR and related stuff dead. +; RUN: opt < %s -loop-reduce -S | not grep INDVAR + +declare i1 @pred() + +define void @test(i32* %P) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2] + %STRRED = getelementptr i32* %P, i32 %INDVAR ; <i32*> [#uses=1] + store i32 0, i32* %STRRED + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + %cond = call i1 @pred( ) ; <i1> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/share_code_in_preheader.ll b/test/Transforms/LoopStrengthReduce/share_code_in_preheader.ll new file mode 100644 index 0000000000..412a716bc4 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/share_code_in_preheader.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -loop-reduce -S | grep mul | count 1 +; LSR should not make two copies of the Q*L expression in the preheader! + +define i8 @test(i8* %A, i8* %B, i32 %L, i32 %Q, i32 %N.s) { +entry: + %tmp.6 = mul i32 %Q, %L ; <i32> [#uses=1] + %N = bitcast i32 %N.s to i32 ; <i32> [#uses=1] + br label %no_exit +no_exit: ; preds = %no_exit, %entry + %indvar.ui = phi i32 [ 0, %entry ], [ %indvar.next, %no_exit ] ; <i32> [#uses=2] + %Sum.0.0 = phi i8 [ 0, %entry ], [ %tmp.21, %no_exit ] ; <i8> [#uses=1] + %indvar = bitcast i32 %indvar.ui to i32 ; <i32> [#uses=1] + %N_addr.0.0 = sub i32 %N.s, %indvar ; <i32> [#uses=1] + %tmp.8 = add i32 %N_addr.0.0, %tmp.6 ; <i32> [#uses=2] + %tmp.9 = getelementptr i8* %A, i32 %tmp.8 ; <i8*> [#uses=1] + %tmp.10 = load i8* %tmp.9 ; <i8> [#uses=1] + %tmp.17 = getelementptr i8* %B, i32 %tmp.8 ; <i8*> [#uses=1] + %tmp.18 = load i8* %tmp.17 ; <i8> [#uses=1] + %tmp.19 = sub i8 %tmp.10, %tmp.18 ; <i8> [#uses=1] + %tmp.21 = add i8 %tmp.19, %Sum.0.0 ; <i8> [#uses=2] + %indvar.next = add i32 %indvar.ui, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %N ; <i1> [#uses=1] + br i1 %exitcond, label %loopexit, label %no_exit +loopexit: ; preds = %no_exit + ret i8 %tmp.21 +} + diff --git a/test/Transforms/LoopStrengthReduce/share_ivs.ll b/test/Transforms/LoopStrengthReduce/share_ivs.ll new file mode 100644 index 0000000000..0459bc849b --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/share_ivs.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -loop-reduce -S | grep phi | count 1 + +; This testcase should have ONE stride 18 indvar, the other use should have a +; loop invariant value (B) added to it inside of the loop, instead of having +; a whole indvar based on B for it. + +declare i1 @cond(i32) + +define void @test(i32 %B) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %IV = phi i32 [ 0, %0 ], [ %IVn, %Loop ] ; <i32> [#uses=3] + %C = mul i32 %IV, 18 ; <i32> [#uses=1] + %D = mul i32 %IV, 18 ; <i32> [#uses=1] + %E = add i32 %D, %B ; <i32> [#uses=1] + %cnd = call i1 @cond( i32 %E ) ; <i1> [#uses=1] + call i1 @cond( i32 %C ) ; <i1>:1 [#uses=0] + %IVn = add i32 %IV, 1 ; <i32> [#uses=1] + br i1 %cnd, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll b/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll new file mode 100644 index 0000000000..a99a823a3b --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/use_postinc_value_outside_loop.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -loop-reduce -S | \ +; RUN: grep {add i32 %lsr.iv.next, 1} +; +; Make sure that the use of the IV outside of the loop (the store) uses the +; post incremented value of the IV, not the preincremented value. This +; prevents the loop from having to keep the post and pre-incremented value +; around for the duration of the loop, adding a copy and an extra register +; to the loop. + +declare i1 @pred(i32) + +define void @test([700 x i32]* %nbeaux_.0__558, i32* %i_.16574) { +then.0: + br label %no_exit.2 +no_exit.2: ; preds = %no_exit.2, %then.0 + %indvar630.ui = phi i32 [ 0, %then.0 ], [ %indvar.next631, %no_exit.2 ] ; <i32> [#uses=3] + %indvar630 = bitcast i32 %indvar630.ui to i32 ; <i32> [#uses=2] + %gep.upgrd.1 = zext i32 %indvar630.ui to i64 ; <i64> [#uses=1] + %tmp.38 = getelementptr [700 x i32]* %nbeaux_.0__558, i32 0, i64 %gep.upgrd.1 ; <i32*> [#uses=1] + store i32 0, i32* %tmp.38 + %inc.2 = add i32 %indvar630, 2 ; <i32> [#uses=1] + %tmp.34 = call i1 @pred( i32 %indvar630 ) ; <i1> [#uses=1] + %indvar.next631 = add i32 %indvar630.ui, 1 ; <i32> [#uses=1] + br i1 %tmp.34, label %no_exit.2, label %loopexit.2.loopexit +loopexit.2.loopexit: ; preds = %no_exit.2 + store i32 %inc.2, i32* %i_.16574 + ret void +} + diff --git a/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll b/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll new file mode 100644 index 0000000000..0a9fab0d5e --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll @@ -0,0 +1,41 @@ +; Base should not be i*3, it should be i*2. +; RUN: opt < %s -loop-reduce -S | \ +; RUN: not grep {mul.*%i, 3} + +; Indvar should not start at zero: +; RUN: opt < %s -loop-reduce -S | \ +; RUN: not grep {phi i32 .* 0} +; END. + +; mul uint %i, 3 + +target datalayout = "e-p:32:32" +target triple = "i686-apple-darwin8" +@flags2 = external global [8193 x i8], align 32 ; <[8193 x i8]*> [#uses=1] + +define void @foo(i32 %k, i32 %i.s) { +entry: + %i = bitcast i32 %i.s to i32 ; <i32> [#uses=2] + %k_addr.012 = shl i32 %i.s, 1 ; <i32> [#uses=1] + %tmp14 = icmp sgt i32 %k_addr.012, 8192 ; <i1> [#uses=1] + br i1 %tmp14, label %return, label %bb.preheader +bb.preheader: ; preds = %entry + %tmp. = shl i32 %i, 1 ; <i32> [#uses=1] + br label %bb +bb: ; preds = %bb, %bb.preheader + %indvar = phi i32 [ %indvar.next, %bb ], [ 0, %bb.preheader ] ; <i32> [#uses=2] + %tmp.15 = mul i32 %indvar, %i ; <i32> [#uses=1] + %tmp.16 = add i32 %tmp.15, %tmp. ; <i32> [#uses=2] + %k_addr.0.0 = bitcast i32 %tmp.16 to i32 ; <i32> [#uses=1] + %gep.upgrd.1 = zext i32 %tmp.16 to i64 ; <i64> [#uses=1] + %tmp = getelementptr [8193 x i8]* @flags2, i32 0, i64 %gep.upgrd.1 ; <i8*> [#uses=1] + store i8 0, i8* %tmp + %k_addr.0 = add i32 %k_addr.0.0, %i.s ; <i32> [#uses=1] + %tmp.upgrd.2 = icmp sgt i32 %k_addr.0, 8192 ; <i1> [#uses=1] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 %tmp.upgrd.2, label %return.loopexit, label %bb +return.loopexit: ; preds = %bb + br label %return +return: ; preds = %return.loopexit, %entry + ret void +} diff --git a/test/Transforms/LoopStrengthReduce/variable_stride.ll b/test/Transforms/LoopStrengthReduce/variable_stride.ll new file mode 100644 index 0000000000..7c0f053e4c --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/variable_stride.ll @@ -0,0 +1,18 @@ +; Check that variable strides are reduced to adds instead of multiplies. +; RUN: opt < %s -loop-reduce -S | not grep mul + +declare i1 @pred(i32) + +define void @test([10000 x i32]* %P, i32 %STRIDE) { +; <label>:0 + br label %Loop +Loop: ; preds = %Loop, %0 + %INDVAR = phi i32 [ 0, %0 ], [ %INDVAR2, %Loop ] ; <i32> [#uses=2] + %Idx = mul i32 %INDVAR, %STRIDE ; <i32> [#uses=1] + %cond = call i1 @pred( i32 %Idx ) ; <i1> [#uses=1] + %INDVAR2 = add i32 %INDVAR, 1 ; <i32> [#uses=1] + br i1 %cond, label %Loop, label %Out +Out: ; preds = %Loop + ret void +} + |