[BasicBlockSections] Make sure that the labels for address-taken blocks are emitted after switching the seciton.

Currently, AsmPrinter code is organized in a way in which the labels of address-taken blocks are emitted in the previous section, which makes the relocation incorrect.
This patch reorganizes the code to switch to the basic block section before handling address-taken blocks.

Reviewed By: snehasish, MaskRay

Differential Revision: https://reviews.llvm.org/D88517
This commit is contained in:
Rahman Lavaee 2020-10-07 13:21:20 -07:00
parent 365ef499d6
commit 34cd06a9b3
2 changed files with 55 additions and 16 deletions

View File

@ -3047,6 +3047,16 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
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 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
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 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
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) {

View File

@ -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) ; <i8*> [#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()