Filter callbr insts from critical edge splitting
authorBill Wendling <isanbard@gmail.com>
Fri, 21 Feb 2020 00:22:35 +0000 (16:22 -0800)
committerBill Wendling <isanbard@gmail.com>
Fri, 21 Feb 2020 00:24:42 +0000 (16:24 -0800)
Similarly to how splitting predecessors with an indirectbr isn't handled
in the generic way, we also shouldn't split callbrs, for similar
reasons.

llvm/lib/Transforms/Scalar/LICM.cpp
llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
llvm/test/Transforms/LICM/callbr-crash.ll [new file with mode: 0644]

index 6e5870c184413792a50a0d6e1ef3a411acd4f6fc..15d40a50e60ab935f8b15aa045540c0ea0f48b8e 100644 (file)
@@ -1489,7 +1489,8 @@ static bool canSplitPredecessors(PHINode *PN, LoopSafetyInfo *SafetyInfo) {
     return false;
   for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
     BasicBlock *BBPred = *PI;
-    if (isa<IndirectBrInst>(BBPred->getTerminator()))
+    if (isa<IndirectBrInst>(BBPred->getTerminator()) ||
+        isa<CallBrInst>(BBPred->getTerminator()))
       return false;
   }
   return true;
index 19b926d7904986c00b339e6e8770aac176db5be8..4ae94cec3979a4b1acc130bf896c55d5eb9da113 100644 (file)
@@ -506,7 +506,8 @@ llvm::SplitAllCriticalEdges(Function &F,
   unsigned NumBroken = 0;
   for (BasicBlock &BB : F) {
     Instruction *TI = BB.getTerminator();
-    if (TI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(TI))
+    if (TI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(TI) &&
+        !isa<CallBrInst>(TI))
       for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
         if (SplitCriticalEdge(TI, i, Options))
           ++NumBroken;
diff --git a/llvm/test/Transforms/LICM/callbr-crash.ll b/llvm/test/Transforms/LICM/callbr-crash.ll
new file mode 100644 (file)
index 0000000..e5e7215
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: opt -licm -disable-output < %s
+
+define i32 @j() {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %cond.true.i, %entry
+  callbr void asm sideeffect "", "X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@j, %for.end))
+          to label %cond.true.i [label %for.end]
+
+cond.true.i:                                      ; preds = %for.cond
+  %asmresult1.i.i = extractvalue { i8, i32 } zeroinitializer, 1
+  br i1 undef, label %for.end, label %for.cond
+
+for.end:                                          ; preds = %cond.true.i, %for.cond
+  %asmresult1.i.i2 = phi i32 [ %asmresult1.i.i, %cond.true.i ], [ undef, %for.cond ]
+  ret i32 undef
+}