summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/LICM/sinking.ll
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2019-04-17 02:12:23 +0000
committerEric Christopher <echristo@gmail.com>2019-04-17 02:12:23 +0000
commita86343512845c9c1fdbac865fea88aa5fce7142a (patch)
tree666fc6353de19ad8b00e56b67edd33f24104e4a7 /llvm/test/Transforms/LICM/sinking.ll
parent7f8ca6e3679b3af951cb7a4b1377edfaa3244b93 (diff)
downloadbcm5719-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.ll743
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()
OpenPOWER on IntegriCloud