[SimplifyCFG] Tail-merge calls with sideeffects
authorJames Molloy <james.molloy@arm.com>
Wed, 31 Aug 2016 10:46:16 +0000 (10:46 +0000)
committerJames Molloy <james.molloy@arm.com>
Wed, 31 Aug 2016 10:46:16 +0000 (10:46 +0000)
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

llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/SimplifyCFG/sink-common-code.ll

index 2868641..dc36a6e 100644 (file)
@@ -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;
     }
   }
index e3a86dc..fe501b9 100644 (file)
@@ -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"}