aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2016-08-31 10:46:16 +0000
committerJames Molloy <james.molloy@arm.com>2016-08-31 10:46:16 +0000
commit923e98c232fe8e06fa73fba29cd789e42499df5d (patch)
treebf6f0489186a188e12475d5a63fe761b5e784d22
parent7b09af193a221fb5382d1094c134e50b31bdf7e6 (diff)
downloadllvm-923e98c232fe8e06fa73fba29cd789e42499df5d.zip
llvm-923e98c232fe8e06fa73fba29cd789e42499df5d.tar.gz
llvm-923e98c232fe8e06fa73fba29cd789e42499df5d.tar.bz2
[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. llvm-svn: 280215
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp10
-rw-r--r--llvm/test/Transforms/SimplifyCFG/sink-common-code.ll25
2 files changed, 27 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 2868641..dc36a6e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1433,11 +1433,6 @@ static bool canSinkLastInstruction(ArrayRef<BasicBlock*> Blocks,
if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(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<StoreInst>(I) && !isa<LoadInst>(I) &&
- (I->mayHaveSideEffects() || I->mayHaveSideEffects()))
- return false;
// Everything must have only one use too, apart from stores which
// have no uses.
if (!isa<StoreInst>(I) && !I->hasOneUse())
@@ -1472,10 +1467,11 @@ static bool canSinkLastInstruction(ArrayRef<BasicBlock*> Blocks,
if (!canReplaceOperandWithVariable(I0, OI))
// We can't create a PHI from this GEP.
return false;
- if ((isa<CallInst>(I0) || isa<InvokeInst>(I0)) && OI != 0)
- // Don't create indirect calls!
+ // Don't create indirect calls! The called value is the final operand.
+ if ((isa<CallInst>(I0) || isa<InvokeInst>(I0)) && OI == OE - 1) {
// FIXME: if the call was *already* indirect, we should do this.
return false;
+ }
++NumPHIsRequired;
}
}
diff --git a/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll b/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll
index e3a86dc..fe501b9 100644
--- a/llvm/test/Transforms/SimplifyCFG/sink-common-code.ll
+++ b/llvm/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"}