Index: lld/test/ELF/lto/basic-block-sections-redundant-br.ll =================================================================== --- /dev/null +++ lld/test/ELF/lto/basic-block-sections-redundant-br.ll @@ -0,0 +1,53 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=all -O0 | FileCheck %s +; This test case is generated from code: +; int +; mapping (int len) +; { +; switch (len) +; { +; case 7: return 333; +; default: +; goto unknown; +; } +; unknown: +; return 0; +; } +; clang -O0 -fbasic-block-sections=all test.c + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @mapping(i32 noundef %len) { +; CHECK: mapping: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: # %bb.0: # %entry +; CHECK-NEXT: movl {{.*}} +; CHECK-NEXT: movl {{.*}} +; CHECK-NEXT: subl {{.*}} +; CHECK-NEXT: jne mapping.__part.2 +; CHECK-NEXT: jmp mapping.__part.1 +; CHECK-NOT: jmp {{.*}} +; CHECK: mapping.__part.1: +; CHECK: mapping.__part.2: +entry: + %retval = alloca i32, align 4 + %len.addr = alloca i32, align 4 + store i32 %len, ptr %len.addr, align 4 + %0 = load i32, ptr %len.addr, align 4 + switch i32 %0, label %sw.default [ + i32 7, label %sw.bb + ] + +sw.bb: ; preds = %entry + store i32 333, ptr %retval, align 4 + br label %return + +sw.default: ; preds = %entry + br label %unknown + +unknown: ; preds = %sw.default + store i32 0, ptr %retval, align 4 + br label %return + +return: ; preds = %unknown, %sw.bb + %1 = load i32, ptr %retval, align 4 + ret i32 %1 +} Index: llvm/lib/CodeGen/BasicBlockSections.cpp =================================================================== --- llvm/lib/CodeGen/BasicBlockSections.cpp +++ llvm/lib/CodeGen/BasicBlockSections.cpp @@ -122,6 +122,13 @@ } // end anonymous namespace +/// Basic blocks with an explicit unconditional branch to its fallthrough block +/// do not need an extra unconditional branch. +static bool hasUncoditionalBranch(const MachineBasicBlock &MBB) { + return !MBB.empty() && + std::prev(MBB.terminators().end())->isUnconditionalBranch(); +} + char BasicBlockSections::ID = 0; INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare", "Prepares for basic block sections, by splitting functions " @@ -143,8 +150,11 @@ // 1- the block ends a section, which means its next block may be // reorderd by the linker, or // 2- the fallthrough block is not adjacent to the block in the new - // order. - if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB)) + // order, or + // 3- the terminator of the block is an unconditional branch to its + // fallthrough. + if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB) && + !hasUncoditionalBranch(MBB)) TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc()); // We do not optimize branches for machine basic blocks ending sections, as