diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/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); @@ -1924,10 +1921,9 @@ } // If any of predecessors end with an indirect goto, we can't change its - // destination. Same for CallBr. + // destination. if (any_of(BlocksToFoldInto, [](BasicBlock *Pred) { - return isa(Pred->getTerminator()) || - isa(Pred->getTerminator()); + return isa(Pred->getTerminator()); })) return false; diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/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; diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/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 diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/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 { diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/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; diff --git a/llvm/test/Transforms/JumpThreading/callbr-edge-split.ll b/llvm/test/Transforms/JumpThreading/callbr-edge-split.ll --- a/llvm/test/Transforms/JumpThreading/callbr-edge-split.ll +++ b/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]] diff --git a/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll b/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll --- a/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll +++ b/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll @@ -6,21 +6,22 @@ define i1 @func(i1 %arg, i32 %arg1, i1 %arg2) { ; CHECK-LABEL: @func( ; CHECK-NEXT: bb: -; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] -; CHECK: bb3: -; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[ARG1:%.*]], 0 -; CHECK-NEXT: br label [[BB7:%.*]] +; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB7:%.*]], label [[BB4:%.*]] ; CHECK: bb4: -; CHECK-NEXT: callbr void asm sideeffect "", "i"(i8* blockaddress(@func, [[BB7]])) -; CHECK-NEXT: to label [[BB5:%.*]] [label %bb7] +; CHECK-NEXT: callbr void asm sideeffect "", "i"(i8* blockaddress(@func, [[BB7_THR_COMM:%.*]])) +; CHECK-NEXT: to label [[BB5:%.*]] [label %bb7.thr_comm] ; CHECK: bb5: -; CHECK-NEXT: br label [[BB7]] +; CHECK-NEXT: br label [[BB7_THR_COMM]] +; CHECK: bb7.thr_comm: +; CHECK-NEXT: [[I91:%.*]] = xor i1 [[ARG2:%.*]], [[ARG]] +; CHECK-NEXT: br i1 [[I91]], label [[BB11:%.*]], label [[BB11]] ; CHECK: bb7: -; CHECK-NEXT: [[I8:%.*]] = phi i1 [ [[I]], [[BB3]] ], [ [[ARG2:%.*]], [[BB5]] ], [ [[ARG2]], [[BB4]] ] -; CHECK-NEXT: [[I9:%.*]] = xor i1 [[I8]], [[ARG]] -; CHECK-NEXT: br i1 [[I9]], label [[BB11:%.*]], label [[BB11]] +; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[ARG1:%.*]], 0 +; CHECK-NEXT: [[I9:%.*]] = xor i1 [[I]], [[ARG]] +; CHECK-NEXT: br i1 [[I9]], label [[BB11]], label [[BB11]] ; CHECK: bb11: -; CHECK-NEXT: ret i1 [[I9]] +; CHECK-NEXT: [[I93:%.*]] = phi i1 [ [[I91]], [[BB7_THR_COMM]] ], [ [[I9]], [[BB7]] ], [ [[I91]], [[BB7_THR_COMM]] ], [ [[I9]], [[BB7]] ] +; CHECK-NEXT: ret i1 [[I93]] ; bb: br i1 %arg, label %bb3, label %bb4 diff --git a/llvm/test/Transforms/LICM/callbr-crash.ll b/llvm/test/Transforms/LICM/callbr-crash.ll --- a/llvm/test/Transforms/LICM/callbr-crash.ll +++ b/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: diff --git a/llvm/test/Transforms/SimplifyCFG/jump-threading.ll b/llvm/test/Transforms/SimplifyCFG/jump-threading.ll --- a/llvm/test/Transforms/SimplifyCFG/jump-threading.ll +++ b/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