Index: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp @@ -470,17 +470,27 @@ FallthroughBB = *SI; } - if (!FallthroughBB && canFallThrough()) { - // We fallthrough to the same basic block as the conditional jump targets. - // Remove the conditional jump, leaving unconditional fallthrough. - // FIXME: This does not seem like a reasonable pattern to support, but it - // has been seen in the wild coming out of degenerate ARM test cases. - TII->RemoveBranch(*this); + if (!FallthroughBB) { + if (canFallThrough()) { + // We fallthrough to the same basic block as the conditional jump targets. + // Remove the conditional jump, leaving unconditional fallthrough. + // FIXME: This does not seem like a reasonable pattern to support, but it + // has been seen in the wild coming out of degenerate ARM test cases. + TII->RemoveBranch(*this); + + // Finally update the unconditional successor to be reached via a branch if + // it would not be reached by fallthrough. + if (!isLayoutSuccessor(TBB)) + TII->InsertBranch(*this, TBB, nullptr, Cond, DL); + return; + } - // Finally update the unconditional successor to be reached via a branch if - // it would not be reached by fallthrough. - if (!isLayoutSuccessor(TBB)) - TII->InsertBranch(*this, TBB, nullptr, Cond, DL); + // We enter here iff exactly one successor is TBB which cannot fallthrough + // and the rest successors if any are EHPads. In this case, we need to + // change the conditional branch into unconditional branch. + TII->RemoveBranch(*this); + Cond.clear(); + TII->InsertBranch(*this, TBB, nullptr, Cond, DL); return; } Index: llvm/trunk/test/CodeGen/X86/update-terminator.mir =================================================================== --- llvm/trunk/test/CodeGen/X86/update-terminator.mir +++ llvm/trunk/test/CodeGen/X86/update-terminator.mir @@ -0,0 +1,57 @@ +# RUN: llc -march=x86-64 -verify-machineinstrs -run-pass block-placement -o /dev/null %s 2>&1 | FileCheck %s +# Check the conditional jump in bb.1 is changed to unconditional after block placement swaps bb.2 and bb.3. + +--- | + @a = external global i16 + @b = external global i32 + + ; Function Attrs: nounwind + define void @f2() { + br i1 undef, label %bb1, label %bb3 + + bb1: + br i1 undef, label %bb2, label %bb2 + + bb2: + br label %bb4 + + bb3: + br label %bb2 + + bb4: + ret void + } + + +... +--- +# CHECK-LABEL: name: f2 +# CHECK: bb.1: +# CHECK: JMP_1 %bb.2 +# CHECK: bb.3: +# CHECK: bb.2: +name: f2 +body: | + bb.0 (%ir-block.0): + successors: %bb.1(50), %bb.3(50) + + JNE_1 %bb.1, implicit %eflags + JMP_1 %bb.3 + bb.1: + successors: %bb.2(100) + + JNE_1 %bb.2, implicit %eflags + + bb.2: + successors: %bb.4(100) + + JMP_1 %bb.4 + + bb.3: + successors: %bb.2(100) + JMP_1 %bb.2 + + bb.4: + RETQ + +...