Skip to content

Commit 0b2f4cd

Browse files
committed
Explicitly check for entry basic block, rather than relying on MachineBasicBlock::pred_empty.
Sometimes in unoptimized code, we have dangling unreachable basic blocks with no predecessors. Basic block sections should be emitted for those as well. Without this patch, the included test fails with a fatal error in `AsmPrinter::emitBasicBlockEnd`. Reviewed By: tmsriram Differential Revision: https://reviews.llvm.org/D89423
1 parent d176e13 commit 0b2f4cd

File tree

5 files changed

+51
-14
lines changed

5 files changed

+51
-14
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,9 @@ class AsmPrinter : public MachineFunctionPass {
778778
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &S);
779779
/// Emit GlobalAlias or GlobalIFunc.
780780
void emitGlobalIndirectSymbol(Module &M, const GlobalIndirectSymbol &GIS);
781+
782+
/// This method decides whether the specified basic block requires a label.
783+
bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
781784
};
782785

783786
} // end namespace llvm

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ class MachineBasicBlock
434434

435435
bool hasEHPadSuccessor() const;
436436

437+
/// Returns true if this is the entry block of the function.
438+
bool isEntryBlock() const;
439+
437440
/// Returns true if this is the entry block of an EH scope, i.e., the block
438441
/// that used to have a catchpad or cleanuppad instruction in the LLVM IR.
439442
bool isEHScopeEntry() const { return IsEHScopeEntry; }

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
10531053
// Emit BB Information for each basic block in the funciton.
10541054
for (const MachineBasicBlock &MBB : MF) {
10551055
const MCSymbol *MBBSymbol =
1056-
MBB.pred_empty() ? FunctionSymbol : MBB.getSymbol();
1056+
MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
10571057
// Emit the basic block offset.
10581058
emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol);
10591059
// Emit the basic block size. When BBs have alignments, their size cannot
@@ -3088,7 +3088,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
30883088
// Switch to a new section if this basic block must begin a section. The
30893089
// entry block is always placed in the function section and is handled
30903090
// separately.
3091-
if (MBB.isBeginSection() && !MBB.pred_empty()) {
3091+
if (MBB.isBeginSection() && !MBB.isEntryBlock()) {
30923092
OutStreamer->SwitchSection(
30933093
getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
30943094
MBB, TM));
@@ -3126,24 +3126,22 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
31263126
}
31273127

31283128
// Print the main label for the block.
3129-
if (MBB.pred_empty() ||
3130-
(!MF->hasBBLabels() && isBlockOnlyReachableByFallthrough(&MBB) &&
3131-
!MBB.isEHFuncletEntry() && !MBB.hasLabelMustBeEmitted())) {
3129+
if (shouldEmitLabelForBasicBlock(MBB)) {
3130+
if (isVerbose() && MBB.hasLabelMustBeEmitted())
3131+
OutStreamer->AddComment("Label of block must be emitted");
3132+
OutStreamer->emitLabel(MBB.getSymbol());
3133+
} else {
31323134
if (isVerbose()) {
31333135
// NOTE: Want this comment at start of line, don't emit with AddComment.
31343136
OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
31353137
false);
31363138
}
3137-
} else {
3138-
if (isVerbose() && MBB.hasLabelMustBeEmitted())
3139-
OutStreamer->AddComment("Label of block must be emitted");
3140-
OutStreamer->emitLabel(MBB.getSymbol());
31413139
}
31423140

31433141
// With BB sections, each basic block must handle CFI information on its own
31443142
// if it begins a section (Entry block is handled separately by
31453143
// AsmPrinterHandler::beginFunction).
3146-
if (MBB.isBeginSection() && !MBB.pred_empty())
3144+
if (MBB.isBeginSection() && !MBB.isEntryBlock())
31473145
for (const HandlerInfo &HI : Handlers)
31483146
HI.Handler->beginBasicBlock(MBB);
31493147
}
@@ -3177,15 +3175,26 @@ void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility,
31773175
OutStreamer->emitSymbolAttribute(Sym, Attr);
31783176
}
31793177

3178+
bool AsmPrinter::shouldEmitLabelForBasicBlock(
3179+
const MachineBasicBlock &MBB) const {
3180+
// With `-fbasic-block-sections=`, a label is needed for every non-entry block
3181+
// in the labels mode (option `=labels`) and every section beginning in the
3182+
// sections mode (`=all` and `=list=`).
3183+
if ((MF->hasBBLabels() || MBB.isBeginSection()) && !MBB.isEntryBlock())
3184+
return true;
3185+
// A label is needed for any block with at least one predecessor (when that
3186+
// predecessor is not the fallthrough predecessor, or if it is an EH funclet
3187+
// entry, or if a label is forced).
3188+
return !MBB.pred_empty() &&
3189+
(!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() ||
3190+
MBB.hasLabelMustBeEmitted());
3191+
}
3192+
31803193
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
31813194
/// exactly one predecessor and the control transfer mechanism between
31823195
/// the predecessor and this block is a fall-through.
31833196
bool AsmPrinter::
31843197
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
3185-
// With BasicBlock Sections, beginning of the section is not a fallthrough.
3186-
if (MBB->isBeginSection())
3187-
return false;
3188-
31893198
// If this is a landing pad, it isn't a fall through. If it has no preds,
31903199
// then nothing falls through to it.
31913200
if (MBB->isEHPad() || MBB->pred_empty())

llvm/lib/CodeGen/MachineBasicBlock.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ bool MachineBasicBlock::hasEHPadSuccessor() const {
266266
return false;
267267
}
268268

269+
bool MachineBasicBlock::isEntryBlock() const {
270+
return getParent()->begin() == getIterator();
271+
}
272+
269273
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
270274
LLVM_DUMP_METHOD void MachineBasicBlock::dump() const {
271275
print(dbgs());
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; Check that basic block section is emitted when a non-entry block has no predecessors.
2+
; RUN: llc < %s -mtriple=x86_64 -O0 -basic-block-sections=all | FileCheck %s --check-prefix=CHECK-SECTIONS
3+
; RUN: llc < %s -mtriple=x86_64 -O0 | FileCheck %s --check-prefix=CHECK-NOSECTIONS
4+
define void @foo(i32* %bar) {
5+
%v = load i32, i32* %bar
6+
switch i32 %v, label %default [
7+
i32 0, label %target
8+
]
9+
target:
10+
ret void
11+
;; This is the block which will not have any predecessors. If the block is not garbage collected, it must
12+
;; be placed in a basic block section with a corresponding symbol.
13+
default:
14+
unreachable
15+
; CHECK-NOSECTIONS: # %bb.2: # %default
16+
; CHECK-SECTIONS: .section .text,"ax",@progbits,unique,2
17+
; CHECK-SECTIONS-NEXT: foo.2: # %default
18+
}

0 commit comments

Comments
 (0)