Skip to content

Commit 9ab0175

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 checks not whether a block is the first in section, but instead whether it is the first *non-empty* block in the section.
1 parent e241964 commit 9ab0175

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

llvm/lib/CodeGen/BasicBlockSections.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,29 @@ void llvm::sortBasicBlocksAndUpdateBranches(
265265
// zero implies "no landing pad." This function inserts a NOP just before the EH
266266
// pad label to ensure a nonzero offset.
267267
void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) {
268+
llvm::SmallDenseMap<MBBSectionID, bool> EmptySections;
269+
auto IsFirstNonEmptyBBInSection = [&](const MachineBasicBlock &MBB) {
270+
auto It = EmptySections.end();
271+
if (MBB.isBeginSection()) {
272+
auto Insert = EmptySections.insert({MBB.getSectionID(), true});
273+
It = Insert.first;
274+
assert(Insert.second && "Section's begin block is encountered before any "
275+
"of its other blocks");
276+
} else {
277+
It = EmptySections.find(MBB.getSectionID());
278+
assert(It != EmptySections.end() &&
279+
"Non-begin MBB found in section before its begin MBB");
280+
}
281+
bool *IsSectionEmpty = &It->second;
282+
if (*IsSectionEmpty && !MBB.empty()) {
283+
*IsSectionEmpty = false;
284+
return true;
285+
}
286+
return false;
287+
};
288+
268289
for (auto &MBB : MF) {
269-
if (MBB.isBeginSection() && MBB.isEHPad()) {
290+
if (IsFirstNonEmptyBBInSection(MBB) && MBB.isEHPad()) {
270291
MachineBasicBlock::iterator MI = MBB.begin();
271292
while (!MI->isEHLabel())
272293
++MI;

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)