[llvm] [CodeGen] Fix lpad padding at section start after empty block (PR #112595)

Fabian Parzefall via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 16 11:38:01 PDT 2024


https://github.com/pzfl created https://github.com/llvm/llvm-project/pull/112595

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.

>From d9c7203d04d9148510e2c9fe13182bc89d9742ee Mon Sep 17 00:00:00 2001
From: Fabian Parzefall <parzefall at meta.com>
Date: Wed, 9 Oct 2024 19:03:44 -0700
Subject: [PATCH] [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.
---
 llvm/include/llvm/CodeGen/MachineBasicBlock.h | 11 +++++++
 llvm/lib/CodeGen/BasicBlockSections.cpp       |  2 +-
 llvm/lib/CodeGen/MachineFunction.cpp          | 17 ++++++++++-
 .../Generic/machine-function-splitter.ll      | 30 +++++++++++++++++++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 6cf151c951b19f..d1ae1b037493bd 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -224,6 +224,10 @@ class MachineBasicBlock
   // Indicate that this basic block ends a section.
   bool IsEndSection = false;
 
+  // Indicate that this basic block contains the first instruction in the
+  // section.
+  bool IsFirstNonEmptyBBInSection = false;
+
   /// Indicate that this basic block is the indirect dest of an INLINEASM_BR.
   bool IsInlineAsmBrIndirectTarget = false;
 
@@ -673,10 +677,17 @@ class MachineBasicBlock
   /// Returns true if this block ends any section.
   bool isEndSection() const { return IsEndSection; }
 
+  /// Returns true if this block contains the first instruction of its section.
+  bool isFirstNonEmptyBBInSection() const { return IsFirstNonEmptyBBInSection; }
+
   void setIsBeginSection(bool V = true) { IsBeginSection = V; }
 
   void setIsEndSection(bool V = true) { IsEndSection = V; }
 
+  void setIsFirstNonEmptyBBInSection(bool V = true) {
+    IsFirstNonEmptyBBInSection = V;
+  }
+
   std::optional<UniqueBBID> getBBID() const { return BBID; }
 
   /// Returns the section ID of this basic block.
diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp
index 1eedfc4b259126..d04d05aa336de9 100644
--- a/llvm/lib/CodeGen/BasicBlockSections.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSections.cpp
@@ -266,7 +266,7 @@ void llvm::sortBasicBlocksAndUpdateBranches(
 // pad label to ensure a nonzero offset.
 void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) {
   for (auto &MBB : MF) {
-    if (MBB.isBeginSection() && MBB.isEHPad()) {
+    if (MBB.isFirstNonEmptyBBInSection() && MBB.isEHPad()) {
       MachineBasicBlock::iterator MI = MBB.begin();
       while (!MI->isEHLabel())
         ++MI;
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index b56888a0f71fe6..3dbd59fe1b0a14 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -383,13 +383,28 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) {
 /// and the SectionID's are assigned to MBBs.
 void MachineFunction::assignBeginEndSections() {
   front().setIsBeginSection();
+  front().setIsFirstNonEmptyBBInSection();
   auto CurrentSectionID = front().getSectionID();
+  bool FirstSectionFirstInstructionEmitted = true;
   for (auto MBBI = std::next(begin()), E = end(); MBBI != E; ++MBBI) {
-    if (MBBI->getSectionID() == CurrentSectionID)
+    if (MBBI->getSectionID() == CurrentSectionID) {
+      if (!FirstSectionFirstInstructionEmitted && !MBBI->empty()) {
+        MBBI->setIsFirstNonEmptyBBInSection();
+        FirstSectionFirstInstructionEmitted = true;
+      }
       continue;
+    }
+
     MBBI->setIsBeginSection();
     std::prev(MBBI)->setIsEndSection();
     CurrentSectionID = MBBI->getSectionID();
+
+    if (MBBI->empty()) {
+      FirstSectionFirstInstructionEmitted = false;
+    } else {
+      MBBI->setIsFirstNonEmptyBBInSection();
+      FirstSectionFirstInstructionEmitted = true;
+    }
   }
   back().setIsEndSection();
 }
diff --git a/llvm/test/CodeGen/Generic/machine-function-splitter.ll b/llvm/test/CodeGen/Generic/machine-function-splitter.ll
index 2097523a61c5f9..5028dbc53ce65c 100644
--- a/llvm/test/CodeGen/Generic/machine-function-splitter.ll
+++ b/llvm/test/CodeGen/Generic/machine-function-splitter.ll
@@ -610,6 +610,36 @@ cold_asm_target:
   ret void
 }
 
+define i32 @foo21(i1 zeroext %0) personality ptr @__gxx_personality_v0 !prof !14 {
+;; Check that nop is inserted just before the EH pad if it is the first
+;; instruction in a section (but is preceeded by another empty block).
+; MFS-DEFAULTS-LABEL:         foo21
+; MFS-DEFAULTS-X86-LABEL:     callq   baz
+; MFS-DEFAULTS-X86:           .section        .text.split.foo21,"ax", at progbits
+; MFS-DEFAULTS-X86-NEXT:      foo21.cold:
+; MFS-DEFAULTS-X86:           nop
+; MFS-DEFAULTS-X86:           callq   _Unwind_Resume at PLT
+entry:
+  br i1 %0, label %try, label %unreachable, !prof !17
+
+try:
+  invoke void @_Z1fv()
+          to label %try.cont unwind label %lpad, !prof !17
+
+try.cont:
+  %1 = call i32 @baz()
+  ret i32 %1
+
+unreachable:
+  unreachable
+
+lpad:
+  %2 = landingpad { ptr, i32 }
+          cleanup
+          catch ptr @_ZTIi
+  resume { ptr, i32 } %2
+}
+
 declare i32 @bar()
 declare i32 @baz()
 declare i32 @bam()



More information about the llvm-commits mailing list