Filter callbr insts from critical edge splitting

Similarly to how splitting predecessors with an indirectbr isn't handled
in the generic way, we also shouldn't split callbrs, for similar
reasons.
This commit is contained in:
Bill Wendling
2020-02-20 16:24:42 -08:00
parent d4ded05ba8
commit 2fe457690d
3 changed files with 22 additions and 2 deletions
+2 -1
View 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;
@@ -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;
+18
View File
@@ -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
}