Index: lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- lib/Transforms/Utils/CloneFunction.cpp +++ lib/Transforms/Utils/CloneFunction.cpp @@ -636,6 +636,22 @@ Function::iterator Begin = cast(VMap[StartingBB])->getIterator(); Function::iterator I = Begin; while (I != NewFunc->end()) { + // We need to simplify conditional branches and switches with a constant + // operand. We try to prune these out when cloning, but if the + // simplification required looking through PHI nodes, those are only + // available after forming the full basic block. That may leave some here, + // and we still want to prune the dead code as early as possible. + // + // Do the folding before we check if the block is dead since we want code + // like + // bb: + // br i1 undef, label %bb, label %bb + // to be simplified to + // bb: + // br label %bb + // before we call I->getSinglePredecessor(). + ConstantFoldTerminator(&*I); + // Check if this block has become dead during inlining or other // simplifications. Note that the first block will appear dead, as it has // not yet been wired up properly. @@ -646,13 +662,6 @@ continue; } - // We need to simplify conditional branches and switches with a constant - // operand. We try to prune these out when cloning, but if the - // simplification required looking through PHI nodes, those are only - // available after forming the full basic block. That may leave some here, - // and we still want to prune the dead code as early as possible. - ConstantFoldTerminator(&*I); - BranchInst *BI = dyn_cast(I->getTerminator()); if (!BI || BI->isConditional()) { ++I; continue; } Index: test/Transforms/Inline/infinite-loop-two-predecessors.ll =================================================================== --- /dev/null +++ test/Transforms/Inline/infinite-loop-two-predecessors.ll @@ -0,0 +1,39 @@ +; RUN: opt -S -o - %s -inline | FileCheck %s + +define void @f1() { +bb.0: + br i1 false, label %bb.2, label %bb.1 + +bb.1: ; preds = %bb.0 + br label %bb.2 + +bb.2: ; preds = %bb.0, %bb.1 + %tmp0 = phi i16 [ 1, %bb.1 ], [ 0, %bb.0 ] + %tmp1 = icmp eq i16 %tmp0, 0 + br i1 %tmp1, label %bb.3, label %bb.6 + +bb.3: ; preds = %bb.2 + br label %bb.5 + +bb.4: ; preds = %bb.5, %bb.5 + br label %bb.5 + +bb.5: ; preds = %bb.4, %bb.3 + br i1 undef, label %bb.4, label %bb.4 + +bb.6: ; preds = %bb.2 + ret void +} + +define void @f2() { +bb.0: + call void @f1() + ret void +} + +; f1 should be inlined into f2 and simplified/collapsed to nothing. + +; CHECK: define void @f2() { +; CHECK-NEXT: bb.0: +; CHECK-NEXT: ret void +; CHECK-NEXT: }