Skip to content

Commit d9c7203

Browse files
committed
[CodeGen] Fix lpad padding at section start after empty block
If a landing pad is at the very start of a split section, it has to be padded by a nop instruction. Otherwise its offset is marked as zero in the LSDA, which means no landing pad (leading it to be skipped). LLVM already handles this. If a landing pad is the first machine block in a section, a nop is inserted to ensure a non-zero offset. However, if the landing pad is preceeded by an empty block, the nop would be omitted. To fix this, this patch adds a field to machine blocks indicating whether this block contains the first instruction in its section. This variable is then used to determine whether to emit the padding.
1 parent ae778ae commit d9c7203

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ class MachineBasicBlock
224224
// Indicate that this basic block ends a section.
225225
bool IsEndSection = false;
226226

227+
// Indicate that this basic block contains the first instruction in the
228+
// section.
229+
bool IsFirstNonEmptyBBInSection = false;
230+
227231
/// Indicate that this basic block is the indirect dest of an INLINEASM_BR.
228232
bool IsInlineAsmBrIndirectTarget = false;
229233

@@ -673,10 +677,17 @@ class MachineBasicBlock
673677
/// Returns true if this block ends any section.
674678
bool isEndSection() const { return IsEndSection; }
675679

680+
/// Returns true if this block contains the first instruction of its section.
681+
bool isFirstNonEmptyBBInSection() const { return IsFirstNonEmptyBBInSection; }
682+
676683
void setIsBeginSection(bool V = true) { IsBeginSection = V; }
677684

678685
void setIsEndSection(bool V = true) { IsEndSection = V; }
679686

687+
void setIsFirstNonEmptyBBInSection(bool V = true) {
688+
IsFirstNonEmptyBBInSection = V;
689+
}
690+
680691
std::optional<UniqueBBID> getBBID() const { return BBID; }
681692

682693
/// Returns the section ID of this basic block.

llvm/lib/CodeGen/BasicBlockSections.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ void llvm::sortBasicBlocksAndUpdateBranches(
266266
// pad label to ensure a nonzero offset.
267267
void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) {
268268
for (auto &MBB : MF) {
269-
if (MBB.isBeginSection() && MBB.isEHPad()) {
269+
if (MBB.isFirstNonEmptyBBInSection() && MBB.isEHPad()) {
270270
MachineBasicBlock::iterator MI = MBB.begin();
271271
while (!MI->isEHLabel())
272272
++MI;

llvm/lib/CodeGen/MachineFunction.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,28 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) {
383383
/// and the SectionID's are assigned to MBBs.
384384
void MachineFunction::assignBeginEndSections() {
385385
front().setIsBeginSection();
386+
front().setIsFirstNonEmptyBBInSection();
386387
auto CurrentSectionID = front().getSectionID();
388+
bool FirstSectionFirstInstructionEmitted = true;
387389
for (auto MBBI = std::next(begin()), E = end(); MBBI != E; ++MBBI) {
388-
if (MBBI->getSectionID() == CurrentSectionID)
390+
if (MBBI->getSectionID() == CurrentSectionID) {
391+
if (!FirstSectionFirstInstructionEmitted && !MBBI->empty()) {
392+
MBBI->setIsFirstNonEmptyBBInSection();
393+
FirstSectionFirstInstructionEmitted = true;
394+
}
389395
continue;
396+
}
397+
390398
MBBI->setIsBeginSection();
391399
std::prev(MBBI)->setIsEndSection();
392400
CurrentSectionID = MBBI->getSectionID();
401+
402+
if (MBBI->empty()) {
403+
FirstSectionFirstInstructionEmitted = false;
404+
} else {
405+
MBBI->setIsFirstNonEmptyBBInSection();
406+
FirstSectionFirstInstructionEmitted = true;
407+
}
393408
}
394409
back().setIsEndSection();
395410
}

llvm/test/CodeGen/Generic/machine-function-splitter.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,36 @@ cold_asm_target:
610610
ret void
611611
}
612612

613+
define i32 @foo21(i1 zeroext %0) personality ptr @__gxx_personality_v0 !prof !14 {
614+
;; Check that nop is inserted just before the EH pad if it is the first
615+
;; instruction in a section (but is preceeded by another empty block).
616+
; MFS-DEFAULTS-LABEL: foo21
617+
; MFS-DEFAULTS-X86-LABEL: callq baz
618+
; MFS-DEFAULTS-X86: .section .text.split.foo21,"ax",@progbits
619+
; MFS-DEFAULTS-X86-NEXT: foo21.cold:
620+
; MFS-DEFAULTS-X86: nop
621+
; MFS-DEFAULTS-X86: callq _Unwind_Resume@PLT
622+
entry:
623+
br i1 %0, label %try, label %unreachable, !prof !17
624+
625+
try:
626+
invoke void @_Z1fv()
627+
to label %try.cont unwind label %lpad, !prof !17
628+
629+
try.cont:
630+
%1 = call i32 @baz()
631+
ret i32 %1
632+
633+
unreachable:
634+
unreachable
635+
636+
lpad:
637+
%2 = landingpad { ptr, i32 }
638+
cleanup
639+
catch ptr @_ZTIi
640+
resume { ptr, i32 } %2
641+
}
642+
613643
declare i32 @bar()
614644
declare i32 @baz()
615645
declare i32 @bam()

0 commit comments

Comments
 (0)