summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2016-09-07 08:15:54 +0000
committerJames Molloy <james.molloy@arm.com>2016-09-07 08:15:54 +0000
commitbf1837d9c9791a1c4e5b1f90a29ecc0f6c9333dc (patch)
treeaeca4307b916966a2ac6565fde48864c0c07bf76
parent42c83f131eff4046ba166b88959ae29ebce0c925 (diff)
downloadbcm5719-llvm-bf1837d9c9791a1c4e5b1f90a29ecc0f6c9333dc.tar.gz
bcm5719-llvm-bf1837d9c9791a1c4e5b1f90a29ecc0f6c9333dc.zip
[SimplifyCFG] Check PHI uses more accurately
PR30292 showed a case where our PHI checking wasn't correct. We were checking that all values were used by the same PHI before deciding to sink, but we weren't checking that the incoming values for that PHI were what we expected. As a result, we had to bail out after block splitting which caused us to never reach a steady state in SimplifyCFG. Fixes PR30292. llvm-svn: 280790
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp4
-rw-r--r--llvm/test/Transforms/SimplifyCFG/sink-common-code.ll25
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 6fe00a71ea1..6252169b83a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1403,7 +1403,9 @@ static bool canSinkInstructions(
auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
if (!all_of(Insts, [&PNUse](const Instruction *I) -> bool {
auto *U = cast<Instruction>(*I->user_begin());
- return U == PNUse || U->getParent() == I->getParent();
+ return (PNUse &&
+ PNUse->getIncomingValueForBlock(I->getParent()) == I) ||
+ U->getParent() == I->getParent();
}))
return false;
}
diff --git a/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll b/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll
index 66dfeb8658d..57533fa1408 100644
--- a/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll
+++ b/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll
@@ -585,6 +585,31 @@ if.end:
; CHECK: store
; CHECK: store
+; The phi is confusing - both add instructions are used by it, but
+; not on their respective unconditional arcs. It should not be
+; optimized.
+define void @test_pr30292(i1 %cond, i1 %cond2, i32 %a, i32 %b) {
+entry:
+ %add1 = add i32 %a, 1
+ br label %succ
+
+one:
+ br i1 %cond, label %two, label %succ
+
+two:
+ call void @g()
+ %add2 = add i32 %a, 1
+ br label %succ
+
+succ:
+ %p = phi i32 [ 0, %entry ], [ %add1, %one ], [ %add2, %two ]
+ br label %one
+}
+declare void @g()
+
+; CHECK-LABEL: test_pr30292
+; CHECK: phi i32 [ 0, %entry ], [ %add1, %succ ], [ %add2, %two ]
+
; CHECK: !0 = !{!1, !1, i64 0}
; CHECK: !1 = !{!"float", !2}
; CHECK: !2 = !{!"an example type tree"}
OpenPOWER on IntegriCloud