From 5ae34477c2f7be6334815641ad8c340d48537972 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Wed, 31 Aug 2016 10:46:16 +0000 Subject: [PATCH] [SimplifyCFG] Tail-merge calls with sideeffects This was deliberately disabled during my rewrite of SinkIfThenToEnd to keep behaviour at least vaguely consistent with the previous version and keep it as close to NFC as I could. There's no real reason not to merge sideeffect calls though, so let's do it! Small fixup along the way to ensure we don't create indirect calls. Should fix PR28964. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280215 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyCFG.cpp | 10 +++----- .../SimplifyCFG/sink-common-code.ll | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 28686418a4ca..dc36a6e1f0b6 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1433,11 +1433,6 @@ static bool canSinkLastInstruction(ArrayRef Blocks, if (isa(I) || I->isEHPad() || isa(I) || I->getType()->isTokenTy()) return false; - // Apart from loads and stores, we won't move anything that could - // change memory or have sideeffects. - if (!isa(I) && !isa(I) && - (I->mayHaveSideEffects() || I->mayHaveSideEffects())) - return false; // Everything must have only one use too, apart from stores which // have no uses. if (!isa(I) && !I->hasOneUse()) @@ -1472,10 +1467,11 @@ static bool canSinkLastInstruction(ArrayRef Blocks, if (!canReplaceOperandWithVariable(I0, OI)) // We can't create a PHI from this GEP. return false; - if ((isa(I0) || isa(I0)) && OI != 0) - // Don't create indirect calls! + // Don't create indirect calls! The called value is the final operand. + if ((isa(I0) || isa(I0)) && OI == OE - 1) { // FIXME: if the call was *already* indirect, we should do this. return false; + } ++NumPHIsRequired; } } diff --git a/test/Transforms/SimplifyCFG/sink-common-code.ll b/test/Transforms/SimplifyCFG/sink-common-code.ll index e3a86dc9385c..fe501b980aac 100644 --- a/test/Transforms/SimplifyCFG/sink-common-code.ll +++ b/test/Transforms/SimplifyCFG/sink-common-code.ll @@ -344,6 +344,29 @@ if.end: ; CHECK-NOT: load ; CHECK-NOT: store +; The call should be commoned. +define i32 @test13a(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) { +entry: + br i1 %flag, label %if.then, label %if.else + +if.then: + %sv1 = call i32 @bar(i32 %x) + br label %if.end + +if.else: + %sv2 = call i32 @bar(i32 %y) + br label %if.end + +if.end: + %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ] + ret i32 1 +} +declare i32 @bar(i32) + +; CHECK-LABEL: test13a +; CHECK: %[[x:.*]] = select i1 %flag +; CHECK: call i32 @bar(i32 %[[x]]) + ; CHECK: !0 = !{!1, !1, i64 0} ; CHECK: !1 = !{!"float", !2} -; CHECK: !2 = !{!"an example type tree"} \ No newline at end of file +; CHECK: !2 = !{!"an example type tree"}