diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -3047,6 +3047,16 @@ if (Alignment != Align(1)) emitAlignment(Alignment); + // Switch to a new section if this basic block must begin a section. The + // entry block is always placed in the function section and is handled + // separately. + if (MBB.isBeginSection() && !MBB.pred_empty()) { + OutStreamer->SwitchSection( + getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(), + MBB, TM)); + CurrentSectionBeginSym = MBB.getSymbol(); + } + // If the block has its address taken, emit any labels that were used to // reference the block. It is possible that there is more than one label // here, because multiple LLVM BB's may have been RAUW'd to this block after @@ -3077,6 +3087,7 @@ emitBasicBlockLoopComments(MBB, MLI, *this); } + // Print the main label for the block. if (MBB.pred_empty() || (!MF->hasBBLabels() && isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry() && !MBB.hasLabelMustBeEmitted())) { @@ -3086,24 +3097,17 @@ false); } } else { - if (isVerbose() && MBB.hasLabelMustBeEmitted()) { + if (isVerbose() && MBB.hasLabelMustBeEmitted()) OutStreamer->AddComment("Label of block must be emitted"); - } - auto *BBSymbol = MBB.getSymbol(); - // Switch to a new section if this basic block must begin a section. - if (MBB.isBeginSection()) { - OutStreamer->SwitchSection( - getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(), - MBB, TM)); - CurrentSectionBeginSym = BBSymbol; - } - OutStreamer->emitLabel(BBSymbol); - // With BB sections, each basic block must handle CFI information on its own - // if it begins a section. - if (MBB.isBeginSection()) - for (const HandlerInfo &HI : Handlers) - HI.Handler->beginBasicBlock(MBB); + OutStreamer->emitLabel(MBB.getSymbol()); } + + // With BB sections, each basic block must handle CFI information on its own + // if it begins a section (Entry block is handled separately by + // AsmPrinterHandler::beginFunction). + if (MBB.isBeginSection() && !MBB.pred_empty()) + for (const HandlerInfo &HI : Handlers) + HI.Handler->beginBasicBlock(MBB); } void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) { diff --git a/llvm/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll b/llvm/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll @@ -0,0 +1,35 @@ +;; This test verifies that basic-block-sections works with address-taken basic blocks. +; RUN: llc < %s -mtriple=x86_64 -basic-block-sections=all | FileCheck %s + +define void @foo(i1 zeroext %0) nounwind { +entry: + %1 = select i1 %0, i8* blockaddress(@foo, %bb1), i8* blockaddress(@foo, %bb2) ; [#uses=1] + indirectbr i8* %1, [label %bb1, label %bb2] + +; CHECK: .text +; CHECK-LABEL: foo: +; CHECK: movl $.Ltmp0, %eax +; CHECK-NEXT: movl $.Ltmp1, %ecx +; CHECK-NEXT: cmovneq %rax, %rcx +; CHECK-NEXT: jmpq *%rcx + +bb1: ; preds = %entry + %2 = call i32 @bar() + ret void +; CHECK: .section .text,"ax",@progbits,unique,1 +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: foo.1 +; CHECK-NEXT: callq bar +; + +bb2: ; preds = %entry + %3 = call i32 @baz() + ret void +; CHECK: .section .text,"ax",@progbits,unique,2 +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: foo.2 +; CHECK-NEXT: callq baz +} + +declare i32 @bar() +declare i32 @baz()