Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1459,9 +1459,7 @@ // Add all the unavailable predecessors to the PredsToSplit list. for (BasicBlock *P : predecessors(LoadBB)) { // If the predecessor is an indirect goto, we can't split the edge. - // Same for CallBr. - if (isa(P->getTerminator()) || - isa(P->getTerminator())) + if (isa(P->getTerminator())) return false; if (!AvailablePredSet.count(P)) @@ -1685,9 +1683,8 @@ } // If the predecessor ends with an indirect goto, we can't change its - // destination. Same for CallBr. - if (isa(Pred->getTerminator()) || - isa(Pred->getTerminator())) + // destination. + if (isa(Pred->getTerminator())) continue; PredToDestList.emplace_back(Pred, DestBB); Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -1508,8 +1508,7 @@ if (!SafetyInfo->getBlockColors().empty() && BB->getFirstNonPHI()->isEHPad()) return false; for (BasicBlock *BBPred : predecessors(BB)) { - if (isa(BBPred->getTerminator()) || - isa(BBPred->getTerminator())) + if (isa(BBPred->getTerminator())) return false; } return true; Index: llvm/lib/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -1132,9 +1132,7 @@ // all BlockAddress uses would need to be updated. assert(!isa(Preds[i]->getTerminator()) && "Cannot split an edge from an IndirectBrInst"); - assert(!isa(Preds[i]->getTerminator()) && - "Cannot split an edge from a CallBrInst"); - Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB); + Preds[i]->getTerminator()->replaceSuccessorWith(BB, NewBB); } // Insert a new PHI node into NewBB for every PHI node in BB and that new PHI Index: llvm/lib/Transforms/Utils/LoopUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopUtils.cpp +++ llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -75,9 +75,6 @@ if (isa(PredBB->getTerminator())) // We cannot rewrite exiting edges from an indirectbr. return false; - if (isa(PredBB->getTerminator())) - // We cannot rewrite exiting edges from a callbr. - return false; InLoopPredecessors.push_back(PredBB); } else { Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3033,8 +3033,7 @@ // Skip if the predecessor's terminator is an indirect branch. if (any_of(PredBBs, [](BasicBlock *PredBB) { - return isa(PredBB->getTerminator()) || - isa(PredBB->getTerminator()); + return isa(PredBB->getTerminator()); })) continue; Index: llvm/test/Transforms/JumpThreading/callbr-edge-split.ll =================================================================== --- llvm/test/Transforms/JumpThreading/callbr-edge-split.ll +++ llvm/test/Transforms/JumpThreading/callbr-edge-split.ll @@ -8,18 +8,18 @@ define i32 @c() { ; CHECK-LABEL: @c( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[CALL:%.*]] = call i32 @b() -; CHECK-NEXT: [[PHITMP:%.*]] = icmp ne i32 [[CALL]], 0 -; CHECK-NEXT: br i1 [[PHITMP]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]] +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]] ; CHECK: if.else: -; CHECK-NEXT: callbr void asm sideeffect "", "i"(i8* blockaddress(@c, [[IF_THEN2]])) -; CHECK-NEXT: to label [[IF_END_THREAD:%.*]] [label %if.then2] -; CHECK: if.end.thread: +; CHECK-NEXT: callbr void asm sideeffect "", "i"(i8* blockaddress(@c, [[IF_THEN2:%.*]])) +; CHECK-NEXT: to label [[NORMAL:%.*]] [label %if.then2] +; CHECK: normal: ; CHECK-NEXT: br label [[IF_THEN2]] +; CHECK: if.end: +; CHECK-NEXT: [[CALL:%.*]] = call i32 @b() +; CHECK-NEXT: [[PHITMP:%.*]] = icmp ne i32 [[CALL]], 0 +; CHECK-NEXT: br i1 [[PHITMP]], label [[IF_THEN2]], label [[IF_END4:%.*]] ; CHECK: if.then2: ; CHECK-NEXT: [[CALL3:%.*]] = call i32 @b() ; CHECK-NEXT: br label [[IF_END4]] Index: llvm/test/Transforms/LICM/callbr-crash.ll =================================================================== --- llvm/test/Transforms/LICM/callbr-crash.ll +++ llvm/test/Transforms/LICM/callbr-crash.ll @@ -6,12 +6,18 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[FOR_COND:%.*]] ; CHECK: for.cond: -; CHECK-NEXT: callbr void asm sideeffect "", "i,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@j, [[FOR_END:%.*]])) -; CHECK-NEXT: to label [[COND_TRUE_I:%.*]] [label %for.end] +; CHECK-NEXT: callbr void asm sideeffect "", "i,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@j, [[FOR_END_SPLIT_LOOP_EXIT1:%.*]])) +; CHECK-NEXT: to label [[COND_TRUE_I:%.*]] [label %for.end.split.loop.exit1] ; CHECK: cond.true.i: -; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[FOR_COND]] +; CHECK-NEXT: br i1 true, label [[FOR_END_SPLIT_LOOP_EXIT:%.*]], label [[FOR_COND]] +; CHECK: for.end.split.loop.exit: +; CHECK-NEXT: [[ASMRESULT1_I_I_LE:%.*]] = extractvalue { i8, i32 } zeroinitializer, 1 +; CHECK-NEXT: br label [[FOR_END:%.*]] +; CHECK: for.end.split.loop.exit1: +; CHECK-NEXT: [[PHI_PH2:%.*]] = phi i32 [ undef, [[FOR_COND]] ] +; CHECK-NEXT: br label [[FOR_END]] ; CHECK: for.end: -; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[COND_TRUE_I]] ], [ undef, [[FOR_COND]] ] +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ASMRESULT1_I_I_LE]], [[FOR_END_SPLIT_LOOP_EXIT]] ], [ [[PHI_PH2]], [[FOR_END_SPLIT_LOOP_EXIT1]] ] ; CHECK-NEXT: ret i32 [[PHI]] ; entry: Index: llvm/test/Transforms/SimplifyCFG/jump-threading.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/jump-threading.ll +++ llvm/test/Transforms/SimplifyCFG/jump-threading.ll @@ -425,14 +425,8 @@ ; CHECK-LABEL: @callbr( ; CHECK-NEXT: entry: ; CHECK-NEXT: callbr void asm sideeffect "", "i,~{dirflag},~{fpsr},~{flags}"(ptr blockaddress(@callbr, [[TARGET:%.*]])) -; CHECK-NEXT: to label [[JOIN:%.*]] [label %target] +; CHECK-NEXT: to label [[IF_END:%.*]] [label %target] ; CHECK: target: -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[TARGET]] ], [ false, [[ENTRY:%.*]] ] -; CHECK-NEXT: br i1 [[PHI]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: ret void