diff options
author | Eric Christopher <echristo@gmail.com> | 2019-04-17 02:12:23 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gmail.com> | 2019-04-17 02:12:23 +0000 |
commit | a86343512845c9c1fdbac865fea88aa5fce7142a (patch) | |
tree | 666fc6353de19ad8b00e56b67edd33f24104e4a7 /llvm/test/Transforms/LICM/sinking.ll | |
parent | 7f8ca6e3679b3af951cb7a4b1377edfaa3244b93 (diff) | |
download | bcm5719-llvm-a86343512845c9c1fdbac865fea88aa5fce7142a.tar.gz bcm5719-llvm-a86343512845c9c1fdbac865fea88aa5fce7142a.zip |
Temporarily Revert "Add basic loop fusion pass."
As it's causing some bot failures (and per request from kbarton).
This reverts commit r358543/ab70da07286e618016e78247e4a24fcb84077fda.
llvm-svn: 358546
Diffstat (limited to 'llvm/test/Transforms/LICM/sinking.ll')
-rw-r--r-- | llvm/test/Transforms/LICM/sinking.ll | 743 |
1 files changed, 0 insertions, 743 deletions
diff --git a/llvm/test/Transforms/LICM/sinking.ll b/llvm/test/Transforms/LICM/sinking.ll deleted file mode 100644 index cc30494a518..00000000000 --- a/llvm/test/Transforms/LICM/sinking.ll +++ /dev/null @@ -1,743 +0,0 @@ -; RUN: opt < %s -basicaa -licm -S | FileCheck %s -; RUN: opt < %s -debugify -basicaa -licm -S | FileCheck %s -check-prefix=DEBUGIFY -; RUN: opt < %s -basicaa -licm -S -enable-mssa-loop-dependency=true -verify-memoryssa | FileCheck %s - - -declare i32 @strlen(i8*) readonly nounwind - -declare void @foo() - -; Sink readonly function. -define i32 @test1(i8* %P) { - br label %Loop - -Loop: ; preds = %Loop, %0 - %A = call i32 @strlen( i8* %P ) readonly - br i1 false, label %Loop, label %Out - -Out: ; preds = %Loop - ret i32 %A -; CHECK-LABEL: @test1( -; CHECK: Out: -; CHECK-NEXT: call i32 @strlen -; CHECK-NEXT: ret i32 %A -} - -declare double @sin(double) readnone nounwind - -; Sink readnone function out of loop with unknown memory behavior. -define double @test2(double %X) { - br label %Loop - -Loop: ; preds = %Loop, %0 - call void @foo( ) - %A = call double @sin( double %X ) readnone - br i1 true, label %Loop, label %Out - -Out: ; preds = %Loop - ret double %A -; CHECK-LABEL: @test2( -; CHECK: Out: -; CHECK-NEXT: call double @sin -; CHECK-NEXT: ret double %A -} - -; FIXME: Should be able to sink this case -define i32 @test2b(i32 %X) { - br label %Loop - -Loop: ; preds = %Loop, %0 - call void @foo( ) - %A = sdiv i32 10, %X - br i1 true, label %Loop, label %Out - -Out: ; preds = %Loop - ret i32 %A -; CHECK-LABEL: @test2b( -; CHECK: Out: -; CHECK-NEXT: sdiv -; CHECK-NEXT: ret i32 %A -} - -define double @test2c(double* %P) { - br label %Loop - -Loop: ; preds = %Loop, %0 - call void @foo( ) - %A = load double, double* %P, !invariant.load !{} - br i1 true, label %Loop, label %Out - -Out: ; preds = %Loop - ret double %A -; CHECK-LABEL: @test2c( -; CHECK: Out: -; CHECK-NEXT: load double -; CHECK-NEXT: ret double %A -} - -; This testcase checks to make sure the sinker does not cause problems with -; critical edges. -define void @test3() { -Entry: - br i1 false, label %Loop, label %Exit -Loop: - %X = add i32 0, 1 - br i1 false, label %Loop, label %Exit -Exit: - %Y = phi i32 [ 0, %Entry ], [ %X, %Loop ] - ret void - -; CHECK-LABEL: @test3( -; CHECK: Exit.loopexit: -; CHECK-NEXT: %X.le = add i32 0, 1 -; CHECK-NEXT: br label %Exit - -} - -; If the result of an instruction is only used outside of the loop, sink -; the instruction to the exit blocks instead of executing it on every -; iteration of the loop. -; -define i32 @test4(i32 %N) { -Entry: - br label %Loop -Loop: ; preds = %Loop, %Entry - %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] - %tmp.6 = mul i32 %N, %N_addr.0.pn ; <i32> [#uses=1] - %tmp.7 = sub i32 %tmp.6, %N ; <i32> [#uses=1] - %dec = add i32 %N_addr.0.pn, -1 ; <i32> [#uses=1] - %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 ; <i1> [#uses=1] - br i1 %tmp.1, label %Loop, label %Out -Out: ; preds = %Loop - ret i32 %tmp.7 -; CHECK-LABEL: @test4( -; CHECK: Out: -; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn -; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] -; CHECK-NEXT: sub i32 %tmp.6.le, %N -; CHECK-NEXT: ret i32 -} - -; To reduce register pressure, if a load is hoistable out of the loop, and the -; result of the load is only used outside of the loop, sink the load instead of -; hoisting it! -; -@X = global i32 5 ; <i32*> [#uses=1] - -define i32 @test5(i32 %N) { -Entry: - br label %Loop -Loop: ; preds = %Loop, %Entry - %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] - %tmp.6 = load i32, i32* @X ; <i32> [#uses=1] - %dec = add i32 %N_addr.0.pn, -1 ; <i32> [#uses=1] - %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 ; <i1> [#uses=1] - br i1 %tmp.1, label %Loop, label %Out -Out: ; preds = %Loop - ret i32 %tmp.6 -; CHECK-LABEL: @test5( -; CHECK: Out: -; CHECK-NEXT: %tmp.6.le = load i32, i32* @X -; CHECK-NEXT: ret i32 %tmp.6.le -} - - - -; The loop sinker was running from the bottom of the loop to the top, causing -; it to miss opportunities to sink instructions that depended on sinking other -; instructions from the loop. Instead they got hoisted, which is better than -; leaving them in the loop, but increases register pressure pointlessly. - - %Ty = type { i32, i32 } -@X2 = external global %Ty - -define i32 @test6() { - br label %Loop -Loop: - %dead = getelementptr %Ty, %Ty* @X2, i64 0, i32 0 - %sunk2 = load i32, i32* %dead - br i1 false, label %Loop, label %Out -Out: ; preds = %Loop - ret i32 %sunk2 -; CHECK-LABEL: @test6( -; CHECK: Out: -; CHECK-NEXT: %dead.le = getelementptr %Ty, %Ty* @X2, i64 0, i32 0 -; CHECK-NEXT: %sunk2.le = load i32, i32* %dead.le -; CHECK-NEXT: ret i32 %sunk2.le -} - - - -; This testcase ensures that we can sink instructions from loops with -; multiple exits. -; -define i32 @test7(i32 %N, i1 %C) { -Entry: - br label %Loop -Loop: ; preds = %ContLoop, %Entry - %N_addr.0.pn = phi i32 [ %dec, %ContLoop ], [ %N, %Entry ] - %tmp.6 = mul i32 %N, %N_addr.0.pn - %tmp.7 = sub i32 %tmp.6, %N ; <i32> [#uses=2] - %dec = add i32 %N_addr.0.pn, -1 ; <i32> [#uses=1] - br i1 %C, label %ContLoop, label %Out1 -ContLoop: - %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 - br i1 %tmp.1, label %Loop, label %Out2 -Out1: ; preds = %Loop - ret i32 %tmp.7 -Out2: ; preds = %ContLoop - ret i32 %tmp.7 -; CHECK-LABEL: @test7( -; CHECK: Out1: -; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn -; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] -; CHECK-NEXT: sub i32 %tmp.6.le, %N -; CHECK-NEXT: ret -; CHECK: Out2: -; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn -; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] -; CHECK-NEXT: sub i32 %tmp.6.le4, %N -; CHECK-NEXT: ret -} - - -; This testcase checks to make sure we can sink values which are only live on -; some exits out of the loop, and that we can do so without breaking dominator -; info. -define i32 @test8(i1 %C1, i1 %C2, i32* %P, i32* %Q) { -Entry: - br label %Loop -Loop: ; preds = %Cont, %Entry - br i1 %C1, label %Cont, label %exit1 -Cont: ; preds = %Loop - %X = load i32, i32* %P ; <i32> [#uses=2] - store i32 %X, i32* %Q - %V = add i32 %X, 1 ; <i32> [#uses=1] - br i1 %C2, label %Loop, label %exit2 -exit1: ; preds = %Loop - ret i32 0 -exit2: ; preds = %Cont - ret i32 %V -; CHECK-LABEL: @test8( -; CHECK: exit1: -; CHECK-NEXT: ret i32 0 -; CHECK: exit2: -; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %X -; CHECK-NEXT: %V.le = add i32 %[[LCSSAPHI]], 1 -; CHECK-NEXT: ret i32 %V.le -} - - -define void @test9() { -loopentry.2.i: - br i1 false, label %no_exit.1.i.preheader, label %loopentry.3.i.preheader -no_exit.1.i.preheader: ; preds = %loopentry.2.i - br label %no_exit.1.i -no_exit.1.i: ; preds = %endif.8.i, %no_exit.1.i.preheader - br i1 false, label %return.i, label %endif.8.i -endif.8.i: ; preds = %no_exit.1.i - %inc.1.i = add i32 0, 1 ; <i32> [#uses=1] - br i1 false, label %no_exit.1.i, label %loopentry.3.i.preheader.loopexit -loopentry.3.i.preheader.loopexit: ; preds = %endif.8.i - br label %loopentry.3.i.preheader -loopentry.3.i.preheader: ; preds = %loopentry.3.i.preheader.loopexit, %loopentry.2.i - %arg_num.0.i.ph13000 = phi i32 [ 0, %loopentry.2.i ], [ %inc.1.i, %loopentry.3.i.preheader.loopexit ] ; <i32> [#uses=0] - ret void -return.i: ; preds = %no_exit.1.i - ret void - -; CHECK-LABEL: @test9( -; CHECK: loopentry.3.i.preheader.loopexit: -; CHECK-NEXT: %inc.1.i.le = add i32 0, 1 -; CHECK-NEXT: br label %loopentry.3.i.preheader -} - - -; Potentially trapping instructions may be sunk as long as they are guaranteed -; to be executed. -define i32 @test10(i32 %N) { -Entry: - br label %Loop -Loop: ; preds = %Loop, %Entry - %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] ; <i32> [#uses=3] - %tmp.6 = sdiv i32 %N, %N_addr.0.pn ; <i32> [#uses=1] - %dec = add i32 %N_addr.0.pn, -1 ; <i32> [#uses=1] - %tmp.1 = icmp ne i32 %N_addr.0.pn, 0 ; <i1> [#uses=1] - br i1 %tmp.1, label %Loop, label %Out -Out: ; preds = %Loop - ret i32 %tmp.6 - -; CHECK-LABEL: @test10( -; CHECK: Out: -; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn -; CHECK-NEXT: %tmp.6.le = sdiv i32 %N, %[[LCSSAPHI]] -; CHECK-NEXT: ret i32 %tmp.6.le -} - -; Should delete, not sink, dead instructions. -define void @test11() { - br label %Loop -Loop: - %dead1 = getelementptr %Ty, %Ty* @X2, i64 0, i32 0 - %dead2 = getelementptr %Ty, %Ty* @X2, i64 0, i32 1 - br i1 false, label %Loop, label %Out -Out: - ret void -; CHECK-LABEL: @test11( -; CHECK: Out: -; CHECK-NEXT: ret void - -; The GEP in dead1 is adding a zero offset, so the DIExpression can be kept as -; a "register location". -; The GEP in dead2 is adding a 4 bytes to the pointer, so the DIExpression is -; turned into an "implicit location" using DW_OP_stack_value. -; -; DEBUGIFY-LABEL: @test11( -; DEBUGIFY: call void @llvm.dbg.value(metadata %Ty* @X2, metadata {{.*}}, metadata !DIExpression()) -; DEBUGIFY: call void @llvm.dbg.value(metadata %Ty* @X2, metadata {{.*}}, metadata !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value)) -} - -@c = common global [1 x i32] zeroinitializer, align 4 - -; Test a *many* way nested loop with multiple exit blocks both of which exit -; multiple loop nests. This exercises LCSSA corner cases. -define i32 @PR18753(i1* %a, i1* %b, i1* %c, i1* %d) { -entry: - br label %l1.header - -l1.header: - %iv = phi i64 [ %iv.next, %l1.latch ], [ 0, %entry ] - %arrayidx.i = getelementptr inbounds [1 x i32], [1 x i32]* @c, i64 0, i64 %iv - br label %l2.header - -l2.header: - %x0 = load i1, i1* %c, align 4 - br i1 %x0, label %l1.latch, label %l3.preheader - -l3.preheader: - br label %l3.header - -l3.header: - %x1 = load i1, i1* %d, align 4 - br i1 %x1, label %l2.latch, label %l4.preheader - -l4.preheader: - br label %l4.header - -l4.header: - %x2 = load i1, i1* %a - br i1 %x2, label %l3.latch, label %l4.body - -l4.body: - call void @f(i32* %arrayidx.i) - %x3 = load i1, i1* %b - %l = trunc i64 %iv to i32 - br i1 %x3, label %l4.latch, label %exit - -l4.latch: - call void @g() - %x4 = load i1, i1* %b, align 4 - br i1 %x4, label %l4.header, label %exit - -l3.latch: - br label %l3.header - -l2.latch: - br label %l2.header - -l1.latch: - %iv.next = add nsw i64 %iv, 1 - br label %l1.header - -exit: - %lcssa = phi i32 [ %l, %l4.latch ], [ %l, %l4.body ] -; CHECK-LABEL: @PR18753( -; CHECK: exit: -; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i64 [ %iv, %l4.latch ], [ %iv, %l4.body ] -; CHECK-NEXT: %l.le = trunc i64 %[[LCSSAPHI]] to i32 -; CHECK-NEXT: ret i32 %l.le - - ret i32 %lcssa -} - -; @test12 moved to sink-promote.ll, as it tests sinking and promotion. - -; Test that we don't crash when trying to sink stores and there's no preheader -; available (which is used for creating loads that may be used by the SSA -; updater) -define void @test13() { -; CHECK-LABEL: @test13 - br label %lab59 - -lab19: - br i1 undef, label %lab20, label %lab38 - -lab20: - br label %lab60 - -lab21: - br i1 undef, label %lab22, label %lab38 - -lab22: - br label %lab38 - -lab38: - ret void - -lab59: - indirectbr i8* undef, [label %lab60, label %lab38] - -lab60: -; CHECK: lab60: -; CHECK: store -; CHECK-NEXT: indirectbr - store i32 2145244101, i32* undef, align 4 - indirectbr i8* undef, [label %lab21, label %lab19] -} - -; Check if LICM can sink a sinkable instruction the exit blocks through -; a non-trivially replacable PHI node. -; -; CHECK-LABEL: @test14 -; CHECK-LABEL: Loop: -; CHECK-NOT: mul -; CHECK-NOT: sub -; -; CHECK-LABEL: Out12.split.loop.exit: -; CHECK: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn, %ContLoop ] -; CHECK: %[[MUL:.*]] = mul i32 %N, %[[LCSSAPHI]] -; CHECK: br label %Out12 -; -; CHECK-LABEL: Out12.split.loop.exit1: -; CHECK: %[[LCSSAPHI2:.*]] = phi i32 [ %N_addr.0.pn, %Loop ] -; CHECK: %[[MUL2:.*]] = mul i32 %N, %[[LCSSAPHI2]] -; CHECK: %[[SUB:.*]] = sub i32 %[[MUL2]], %N -; CHECK: br label %Out12 -; -; CHECK-LABEL: Out12: -; CHECK: phi i32 [ %[[MUL]], %Out12.split.loop.exit ], [ %[[SUB]], %Out12.split.loop.exit1 ] -define i32 @test14(i32 %N, i32 %N2, i1 %C) { -Entry: - br label %Loop -Loop: - %N_addr.0.pn = phi i32 [ %dec, %ContLoop ], [ %N, %Entry ] - %sink.mul = mul i32 %N, %N_addr.0.pn - %sink.sub = sub i32 %sink.mul, %N - %dec = add i32 %N_addr.0.pn, -1 - br i1 %C, label %ContLoop, label %Out12 -ContLoop: - %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 - br i1 %tmp.1, label %Loop, label %Out12 -Out12: - %tmp = phi i32 [%sink.mul, %ContLoop], [%sink.sub, %Loop] - ret i32 %tmp -} - -; In this test, splitting predecessors is not really required because the -; operations of sinkable instructions (sub and mul) are same. In this case, we -; can sink the same sinkable operations and modify the PHI to pass the operands -; to the shared operations. As of now, we split predecessors of non-trivially -; replicalbe PHIs by default in LICM because all incoming edges of a -; non-trivially replacable PHI in LCSSA is critical. -; -; CHECK-LABEL: @test15 -; CHECK-LABEL: Loop: -; CHECK-NOT: mul -; CHECK-NOT: sub -; -; CHECK-LABEL: Out12.split.loop.exit: -; CHECK: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn, %ContLoop ] -; CHECK: %[[MUL:.*]] = mul i32 %N, %[[LCSSAPHI]] -; CHECK: %[[SUB:.*]] = sub i32 %[[MUL]], %N2 -; CHECK: br label %Out12 -; -; CHECK-LABEL: Out12.split.loop.exit1: -; CHECK: %[[LCSSAPHI2:.*]] = phi i32 [ %N_addr.0.pn, %Loop ] -; CHECK: %[[MUL2:.*]] = mul i32 %N, %[[LCSSAPHI2]] -; CHECK: %[[SUB2:.*]] = sub i32 %[[MUL2]], %N -; CHECK: br label %Out12 -; -; CHECK-LABEL: Out12: -; CHECK: phi i32 [ %[[SUB]], %Out12.split.loop.exit ], [ %[[SUB2]], %Out12.split.loop.exit1 ] -define i32 @test15(i32 %N, i32 %N2, i1 %C) { -Entry: - br label %Loop -Loop: - %N_addr.0.pn = phi i32 [ %dec, %ContLoop ], [ %N, %Entry ] - %sink.mul = mul i32 %N, %N_addr.0.pn - %sink.sub = sub i32 %sink.mul, %N - %sink.sub2 = sub i32 %sink.mul, %N2 - %dec = add i32 %N_addr.0.pn, -1 - br i1 %C, label %ContLoop, label %Out12 -ContLoop: - %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 - br i1 %tmp.1, label %Loop, label %Out12 -Out12: - %tmp = phi i32 [%sink.sub2, %ContLoop], [%sink.sub, %Loop] - ret i32 %tmp -} - -; Sink through a non-trivially replacable PHI node which use the same sinkable -; instruction multiple times. -; -; CHECK-LABEL: @test16 -; CHECK-LABEL: Loop: -; CHECK-NOT: mul -; -; CHECK-LABEL: Out.split.loop.exit: -; CHECK: %[[PHI:.*]] = phi i32 [ %l2, %ContLoop ] -; CHECK: br label %Out -; -; CHECK-LABEL: Out.split.loop.exit1: -; CHECK: %[[SINKABLE:.*]] = mul i32 %l2.lcssa, %t.le -; CHECK: br label %Out -; -; CHECK-LABEL: Out: -; CHECK: %idx = phi i32 [ %[[PHI]], %Out.split.loop.exit ], [ %[[SINKABLE]], %Out.split.loop.exit1 ] -define i32 @test16(i1 %c, i8** %P, i32* %P2, i64 %V) { -entry: - br label %loop.ph -loop.ph: - br label %Loop -Loop: - %iv = phi i64 [ 0, %loop.ph ], [ %next, %ContLoop ] - %l2 = call i32 @getv() - %t = trunc i64 %iv to i32 - %sinkable = mul i32 %l2, %t - switch i32 %l2, label %ContLoop [ - i32 32, label %Out - i32 46, label %Out - i32 95, label %Out - ] -ContLoop: - %next = add nuw i64 %iv, 1 - %c1 = call i1 @getc() - br i1 %c1, label %Loop, label %Out -Out: - %idx = phi i32 [ %l2, %ContLoop ], [ %sinkable, %Loop ], [ %sinkable, %Loop ], [ %sinkable, %Loop ] - ret i32 %idx -} - -; Sink a sinkable instruction through multiple non-trivially replacable PHIs in -; differect exit blocks. -; -; CHECK-LABEL: @test17 -; CHECK-LABEL: Loop: -; CHECK-NOT: mul -; -; CHECK-LABEL:OutA.split.loop.exit{{.*}}: -; CHECK: %[[OP1:.*]] = phi i32 [ %N_addr.0.pn, %ContLoop1 ] -; CHECK: %[[SINKABLE:.*]] = mul i32 %N, %[[OP1]] -; CHECK: br label %OutA -; -; CHECK-LABEL:OutA: -; CHECK: phi i32{{.*}}[ %[[SINKABLE]], %OutA.split.loop.exit{{.*}} ] -; -; CHECK-LABEL:OutB.split.loop.exit{{.*}}: -; CHECK: %[[OP2:.*]] = phi i32 [ %N_addr.0.pn, %ContLoop2 ] -; CHECK: %[[SINKABLE2:.*]] = mul i32 %N, %[[OP2]] -; CHECK: br label %OutB -; -; CHECK-LABEL:OutB: -; CHECK: phi i32 {{.*}}[ %[[SINKABLE2]], %OutB.split.loop.exit{{.*}} ] -define i32 @test17(i32 %N, i32 %N2) { -Entry: - br label %Loop -Loop: - %N_addr.0.pn = phi i32 [ %dec, %ContLoop3 ], [ %N, %Entry ] - %sink.mul = mul i32 %N, %N_addr.0.pn - %c0 = call i1 @getc() - br i1 %c0 , label %ContLoop1, label %OutA -ContLoop1: - %c1 = call i1 @getc() - br i1 %c1, label %ContLoop2, label %OutA - -ContLoop2: - %c2 = call i1 @getc() - br i1 %c2, label %ContLoop3, label %OutB -ContLoop3: - %c3 = call i1 @getc() - %dec = add i32 %N_addr.0.pn, -1 - br i1 %c3, label %Loop, label %OutB -OutA: - %tmp1 = phi i32 [%sink.mul, %ContLoop1], [%N2, %Loop] - br label %Out12 -OutB: - %tmp2 = phi i32 [%sink.mul, %ContLoop2], [%dec, %ContLoop3] - br label %Out12 -Out12: - %tmp = phi i32 [%tmp1, %OutA], [%tmp2, %OutB] - ret i32 %tmp -} - - -; Sink a sinkable instruction through both trivially and non-trivially replacable PHIs. -; -; CHECK-LABEL: @test18 -; CHECK-LABEL: Loop: -; CHECK-NOT: mul -; CHECK-NOT: sub -; -; CHECK-LABEL:Out12.split.loop.exit: -; CHECK: %[[OP:.*]] = phi i32 [ %iv, %ContLoop ] -; CHECK: %[[DEC:.*]] = phi i32 [ %dec, %ContLoop ] -; CHECK: %[[SINKMUL:.*]] = mul i32 %N, %[[OP]] -; CHECK: %[[SINKSUB:.*]] = sub i32 %[[SINKMUL]], %N2 -; CHECK: br label %Out12 -; -; CHECK-LABEL:Out12.split.loop.exit1: -; CHECK: %[[OP2:.*]] = phi i32 [ %iv, %Loop ] -; CHECK: %[[SINKMUL2:.*]] = mul i32 %N, %[[OP2]] -; CHECK: %[[SINKSUB2:.*]] = sub i32 %[[SINKMUL2]], %N2 -; CHECK: br label %Out12 -; -; CHECK-LABEL:Out12: -; CHECK: %tmp1 = phi i32 [ %[[SINKSUB]], %Out12.split.loop.exit ], [ %[[SINKSUB2]], %Out12.split.loop.exit1 ] -; CHECK: %tmp2 = phi i32 [ %[[DEC]], %Out12.split.loop.exit ], [ %[[SINKSUB2]], %Out12.split.loop.exit1 ] -; CHECK: %add = add i32 %tmp1, %tmp2 -define i32 @test18(i32 %N, i32 %N2) { -Entry: - br label %Loop -Loop: - %iv = phi i32 [ %dec, %ContLoop ], [ %N, %Entry ] - %sink.mul = mul i32 %N, %iv - %sink.sub = sub i32 %sink.mul, %N2 - %c0 = call i1 @getc() - br i1 %c0, label %ContLoop, label %Out12 -ContLoop: - %dec = add i32 %iv, -1 - %c1 = call i1 @getc() - br i1 %c1, label %Loop, label %Out12 -Out12: - %tmp1 = phi i32 [%sink.sub, %ContLoop], [%sink.sub, %Loop] - %tmp2 = phi i32 [%dec, %ContLoop], [%sink.sub, %Loop] - %add = add i32 %tmp1, %tmp2 - ret i32 %add -} - -; Do not sink an instruction through a non-trivially replacable PHI, to avoid -; assert while splitting predecessors, if the terminator of predecessor is an -; indirectbr. -; CHECK-LABEL: @test19 -; CHECK-LABEL: L0: -; CHECK: %sinkable = mul -; CHECK: %sinkable2 = add - -define i32 @test19(i1 %cond, i1 %cond2, i8* %address, i32 %v1) nounwind { -entry: - br label %L0 -L0: - %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test19, %exit), i8* %address - %v2 = call i32 @getv() - %sinkable = mul i32 %v1, %v2 - %sinkable2 = add i32 %v1, %v2 - indirectbr i8* %indirect.goto.dest, [label %L1, label %exit] - -L1: - %indirect.goto.dest2 = select i1 %cond2, i8* blockaddress(@test19, %exit), i8* %address - indirectbr i8* %indirect.goto.dest2, [label %L0, label %exit] - -exit: - %r = phi i32 [%sinkable, %L0], [%sinkable2, %L1] - ret i32 %r -} - - -; Do not sink through a non-trivially replacable PHI if splitting predecessors -; not allowed in SplitBlockPredecessors(). -; -; CHECK-LABEL: @test20 -; CHECK-LABEL: while.cond -; CHECK: %sinkable = mul -; CHECK: %sinkable2 = add -define void @test20(i32* %s, i1 %b, i32 %v1, i32 %v2) personality i32 (...)* @__CxxFrameHandler3 { -entry: - br label %while.cond -while.cond: - %v = call i32 @getv() - %sinkable = mul i32 %v, %v2 - %sinkable2 = add i32 %v, %v2 - br i1 %b, label %try.cont, label %while.body -while.body: - invoke void @may_throw() - to label %while.body2 unwind label %catch.dispatch -while.body2: - invoke void @may_throw2() - to label %while.cond unwind label %catch.dispatch -catch.dispatch: - %.lcssa1 = phi i32 [ %sinkable, %while.body ], [ %sinkable2, %while.body2 ] - %cp = cleanuppad within none [] - store i32 %.lcssa1, i32* %s - cleanupret from %cp unwind to caller -try.cont: - ret void -} - -; The sinkable call should be sunk into an exit block split. After splitting -; the exit block, BlockColor for new blocks should be added properly so -; that we should be able to access valid ColorVector. -; -; CHECK-LABEL:@test21_pr36184 -; CHECK-LABEL: Loop -; CHECK-NOT: %sinkableCall -; CHECK-LABEL:Out.split.loop.exit -; CHECK: %sinkableCall -define i32 @test21_pr36184(i8* %P) personality i32 (...)* @__CxxFrameHandler3 { -entry: - br label %loop.ph - -loop.ph: - br label %Loop - -Loop: - %sinkableCall = call i32 @strlen( i8* %P ) readonly - br i1 undef, label %ContLoop, label %Out - -ContLoop: - br i1 undef, label %Loop, label %Out - -Out: - %idx = phi i32 [ %sinkableCall, %Loop ], [0, %ContLoop ] - ret i32 %idx -} - -; We do not support splitting a landingpad block if BlockColors is not empty. -; CHECK-LABEL: @test22 -; CHECK-LABEL: while.body2 -; CHECK-LABEL: %mul -; CHECK-NOT: lpadBB.split{{.*}} -define void @test22(i1 %b, i32 %v1, i32 %v2) personality i32 (...)* @__CxxFrameHandler3 { -entry: - br label %while.cond -while.cond: - br i1 %b, label %try.cont, label %while.body - -while.body: - invoke void @may_throw() - to label %while.body2 unwind label %lpadBB - -while.body2: - %v = call i32 @getv() - %mul = mul i32 %v, %v2 - invoke void @may_throw2() - to label %while.cond unwind label %lpadBB -lpadBB: - %.lcssa1 = phi i32 [ 0, %while.body ], [ %mul, %while.body2 ] - landingpad { i8*, i32 } - catch i8* null - br label %lpadBBSucc1 - -lpadBBSucc1: - ret void - -try.cont: - ret void -} - -declare void @may_throw() -declare void @may_throw2() -declare i32 @__CxxFrameHandler3(...) -declare i32 @getv() -declare i1 @getc() -declare void @f(i32*) -declare void @g() |