Index: llvm/include/llvm/Analysis/SparsePropagation.h =================================================================== --- llvm/include/llvm/Analysis/SparsePropagation.h +++ llvm/include/llvm/Analysis/SparsePropagation.h @@ -331,8 +331,8 @@ return; } - if (TI.isExceptionalTerminator() || - TI.isIndirectTerminator()) { + if (!isa(TI)) { + // Unknown termintor, assume all successors are feasible. Succs.assign(Succs.size(), true); return; } Index: llvm/include/llvm/IR/Instruction.h =================================================================== --- llvm/include/llvm/IR/Instruction.h +++ llvm/include/llvm/IR/Instruction.h @@ -172,10 +172,6 @@ /// its operands. bool isOnlyUserOfAnyOperand(); - bool isIndirectTerminator() const { - return isIndirectTerminator(getOpcode()); - } - static const char* getOpcodeName(unsigned OpCode); static inline bool isTerminator(unsigned OpCode) { @@ -242,17 +238,6 @@ } } - /// Returns true if the OpCode is a terminator with indirect targets. - static inline bool isIndirectTerminator(unsigned OpCode) { - switch (OpCode) { - case Instruction::IndirectBr: - case Instruction::CallBr: - return true; - default: - return false; - } - } - //===--------------------------------------------------------------------===// // Metadata manipulation. //===--------------------------------------------------------------------===// Index: llvm/lib/Transforms/Utils/LoopRotationUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -622,7 +622,7 @@ // We only need to split loop exit edges. Loop *PredLoop = LI->getLoopFor(ExitPred); if (!PredLoop || PredLoop->contains(Exit) || - ExitPred->getTerminator()->isIndirectTerminator()) + isa(ExitPred->getTerminator())) continue; SplitLatchEdge |= L->getLoopLatch() == ExitPred; BasicBlock *ExitSplit = SplitCriticalEdge( Index: llvm/lib/Transforms/Utils/LoopSimplify.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopSimplify.cpp +++ llvm/lib/Transforms/Utils/LoopSimplify.cpp @@ -127,7 +127,7 @@ // If the loop is branched to from an indirect terminator, we won't // be able to fully transform the loop, because it prohibits // edge splitting. - if (P->getTerminator()->isIndirectTerminator()) + if (isa(P->getTerminator())) return nullptr; // Keep track of it. @@ -256,7 +256,7 @@ if (PN->getIncomingValue(i) != PN || !L->contains(PN->getIncomingBlock(i))) { // We can't split indirect control flow edges. - if (PN->getIncomingBlock(i)->getTerminator()->isIndirectTerminator()) + if (isa(PN->getIncomingBlock(i)->getTerminator())) return nullptr; OuterLoopPreds.push_back(PN->getIncomingBlock(i)); } @@ -375,7 +375,7 @@ std::vector BackedgeBlocks; for (BasicBlock *P : predecessors(Header)) { // Indirect edges cannot be split, so we must fail if we find one. - if (P->getTerminator()->isIndirectTerminator()) + if (isa(P->getTerminator())) return nullptr; if (P != Preheader) BackedgeBlocks.push_back(P); Index: llvm/test/Transforms/LoopDeletion/two-predecessors.ll =================================================================== --- llvm/test/Transforms/LoopDeletion/two-predecessors.ll +++ llvm/test/Transforms/LoopDeletion/two-predecessors.ll @@ -8,11 +8,13 @@ ; CHECK-LABEL: @hoge( ; CHECK-NEXT: bb: ; CHECK-NEXT: callbr void asm sideeffect "", "!i"() -; CHECK-NEXT: to label [[BB1:%.*]] [label %bb2] +; CHECK-NEXT: to label [[BB1:%.*]] [label %bb2.preheader] ; CHECK: bb1: +; CHECK-NEXT: br label [[BB2_PREHEADER:%.*]] +; CHECK: bb2.preheader: ; CHECK-NEXT: br label [[BB2:%.*]] ; CHECK: bb2: -; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ undef, [[BB1]] ], [ [[TMP3:%.*]], [[BB2]] ], [ undef, [[BB:%.*]] ] +; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ [[TMP3:%.*]], [[BB2]] ], [ undef, [[BB2_PREHEADER]] ] ; CHECK-NEXT: [[TMP3]] = tail call i32 bitcast (i32 (...)* @widget to i32 (i32)*)(i32 [[TMP]]) ; CHECK-NEXT: br label [[BB2]] ; Index: llvm/test/Transforms/LoopRotate/callbr.ll =================================================================== --- llvm/test/Transforms/LoopRotate/callbr.ll +++ llvm/test/Transforms/LoopRotate/callbr.ll @@ -13,10 +13,11 @@ ; CHECK-NEXT: [[TMP2:%.*]] = load i8*, i8** bitcast (i64* @d to i8**), align 8 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* @f, align 4 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: br i1 [[TMP4]], label [[TMP17:%.*]], label [[DOTLR_PH2:%.*]] -; CHECK: .lr.ph2: +; CHECK-NEXT: br i1 [[TMP4]], label [[TMP17:%.*]], label [[DOTLR_PH4:%.*]] +; CHECK: .lr.ph4: ; CHECK-NEXT: br label [[TMP5:%.*]] -; CHECK: [[TMP6:%.*]] = phi i32 [ [[TMP3]], [[DOTLR_PH2]] ], [ [[TMP15:%.*]], [[M_EXIT:%.*]] ] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP3]], [[DOTLR_PH4]] ], [ [[TMP15:%.*]], [[M_EXIT:%.*]] ] ; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 [[TMP6]], 4 ; CHECK-NEXT: [[TMP8:%.*]] = zext i1 [[TMP7]] to i32 ; CHECK-NEXT: store i32 [[TMP8]], i32* @g, align 4 @@ -30,26 +31,31 @@ ; CHECK-NEXT: br i1 [[TMP12]], label [[M_EXIT]], label [[DOTLR_PH:%.*]] ; CHECK: .lr.ph: ; CHECK-NEXT: br label [[TMP13:%.*]] -; CHECK: [[DOT11:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP14:%.*]], [[J_EXIT_I:%.*]] ] -; CHECK-NEXT: callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() #1 -; CHECK-NEXT: to label [[J_EXIT_I]] [label %m.exit] +; CHECK: 13: +; CHECK-NEXT: [[DOT11:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP14:%.*]], [[J_EXIT_I:%.*]] ] +; CHECK-NEXT: callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1:[0-9]+]] +; CHECK-NEXT: to label [[J_EXIT_I]] [label %.m.exit_crit_edge] ; CHECK: j.exit.i: -; CHECK-NEXT: [[TMP14]] = tail call i32 asm "", "={ax},~{dirflag},~{fpsr},~{flags}"() #2 -; CHECK-NEXT: br i1 [[TMP12]], label [[DOTM_EXIT_CRIT_EDGE:%.*]], label [[TMP13]] +; CHECK-NEXT: [[TMP14]] = tail call i32 asm "", "={ax},~{dirflag},~{fpsr},~{flags}"() #[[ATTR2:[0-9]+]] +; CHECK-NEXT: br i1 [[TMP12]], label [[DOTM_EXIT_CRIT_EDGE2:%.*]], label [[TMP13]] ; CHECK: .m.exit_crit_edge: -; CHECK-NEXT: [[SPLIT:%.*]] = phi i32 [ [[TMP14]], [[J_EXIT_I]] ] +; CHECK-NEXT: [[SPLIT:%.*]] = phi i32 [ [[DOT11]], [[TMP13]] ] +; CHECK-NEXT: br label [[M_EXIT]] +; CHECK: .m.exit_crit_edge2: +; CHECK-NEXT: [[SPLIT3:%.*]] = phi i32 [ [[TMP14]], [[J_EXIT_I]] ] ; CHECK-NEXT: br label [[M_EXIT]] ; CHECK: m.exit: -; CHECK-NEXT: [[DOT1_LCSSA:%.*]] = phi i32 [ [[DOT11]], [[TMP13]] ], [ [[SPLIT]], [[DOTM_EXIT_CRIT_EDGE]] ], [ undef, [[THREAD_PRE_SPLIT]] ] +; CHECK-NEXT: [[DOT1_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[DOTM_EXIT_CRIT_EDGE:%.*]] ], [ [[SPLIT3]], [[DOTM_EXIT_CRIT_EDGE2]] ], [ undef, [[THREAD_PRE_SPLIT]] ] ; CHECK-NEXT: store i32 [[DOT1_LCSSA]], i32* @h, align 4 ; CHECK-NEXT: [[TMP15]] = load i32, i32* @f, align 4 ; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 -; CHECK-NEXT: br i1 [[TMP16]], label [[DOT_CRIT_EDGE3:%.*]], label [[TMP5]] +; CHECK-NEXT: br i1 [[TMP16]], label [[DOT_CRIT_EDGE5:%.*]], label [[TMP5]] ; CHECK: ._crit_edge: ; CHECK-NEXT: br label [[TMP17]] -; CHECK: ._crit_edge3: +; CHECK: ._crit_edge5: ; CHECK-NEXT: br label [[TMP17]] -; CHECK: ret i32 undef +; CHECK: 17: +; CHECK-NEXT: ret i32 undef ; %1 = alloca [1 x i32], align 4 %2 = load i8*, i8** bitcast (i64* @d to i8**), align 8