From 3bb1ce2319034831f48278261ea1cdf5e6bbdd50 Mon Sep 17 00:00:00 2001 From: ARCHIT SAXENA Date: Fri, 22 Jul 2022 15:02:16 -0700 Subject: [PATCH] Add a nop instruction if a section starts with landing pad for function splitter MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This change adds a nop instruction if section starts with landing pad. This change is like [D73739](https://reviews.llvm.org/D73739) which avoids zero offset landing pad in basic block sections. Detailed description: The current machine functions splitter can create ˜sections which start with a landing pad themselves. This places landing pad at offset zero from LPStart. ``` .section .text.split.foo10,"ax",@progbits foo10.cold: # %lpad .cfi_startproc .cfi_personality 3, __gxx_personality_v0 .cfi_lsda 3, .Lexception5 .cfi_def_cfa %rsp, 16 .Ltmp11: <--- This is a Landing pad and also LP Start as it is start of this section movq %rax, %rdi <--- first instruction is at offest 0 from LPStart callq _Unwind_Resume@PLT ``` This will cause landing pad entries to become zero (.Ltmp11-foo10.cold) ``` .Lcst_begin4: .uleb128 .Ltmp9-.Lfunc_begin2 # >> Call Site 1 << .uleb128 .Ltmp10-.Ltmp9 # Call between .Ltmp9 and .Ltmp10 .uleb128 .Ltmp11-foo10.cold <---This is zero # jumps to .Ltmp11 .byte 3 # On action: 2 .uleb128 .Ltmp10-.Lfunc_begin2 # >> Call Site 2 << .uleb128 .Lfunc_end9-.Ltmp10 # Call between .Ltmp10 and .Lfunc_end9 .byte 0 # has no landing pad .byte 0 # On action: cleanup .p2align 2 ``` The C++ ABI somehow assumes that no landing pads point directly to LPStart (which works in the normal case since the function begin is never a landing pad), and uses LP.offset = 0 to specify no landing pad. This change adds a nop instruction at start of such sections so that such a case could be avoided. Output: ``` .section .text.split.foo10,"ax",@progbits foo10.cold: # %lpad .cfi_startproc .cfi_personality 3, __gxx_personality_v0 .cfi_lsda 3, .Lexception5 .cfi_def_cfa %rsp, 16 nop <--- new instruction that is added .Ltmp11: movq %rax, %rdi callq _Unwind_Resume@PLT ``` Reviewed By: modimo, snehasish, rahmanl Differential Revision: https://reviews.llvm.org/D130133 --- llvm/include/llvm/CodeGen/BasicBlockSectionUtils.h | 2 ++ llvm/lib/CodeGen/BasicBlockSections.cpp | 6 ++---- llvm/lib/CodeGen/MachineFunctionSplitter.cpp | 2 +- llvm/test/CodeGen/X86/machine-function-splitter.ll | 22 ++++++++++++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/CodeGen/BasicBlockSectionUtils.h b/llvm/include/llvm/CodeGen/BasicBlockSectionUtils.h index d8da3be..d43f399 100644 --- a/llvm/include/llvm/CodeGen/BasicBlockSectionUtils.h +++ b/llvm/include/llvm/CodeGen/BasicBlockSectionUtils.h @@ -25,6 +25,8 @@ using MachineBasicBlockComparator = void sortBasicBlocksAndUpdateBranches(MachineFunction &MF, MachineBasicBlockComparator MBBCmp); +void avoidZeroOffsetLandingPad(MachineFunction &MF); + } // end namespace llvm #endif // LLVM_CODEGEN_BASICBLOCKSECTIONUTILS_H diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp index 0d26e34..958212a 100644 --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -268,8 +268,8 @@ void llvm::sortBasicBlocksAndUpdateBranches( // If the exception section begins with a landing pad, that landing pad will // assume a zero offset (relative to @LPStart) in the LSDA. However, a value of // zero implies "no landing pad." This function inserts a NOP just before the EH -// pad label to ensure a nonzero offset. Returns true if padding is not needed. -static bool avoidZeroOffsetLandingPad(MachineFunction &MF) { +// pad label to ensure a nonzero offset. +void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) { for (auto &MBB : MF) { if (MBB.isBeginSection() && MBB.isEHPad()) { MachineBasicBlock::iterator MI = MBB.begin(); @@ -278,10 +278,8 @@ static bool avoidZeroOffsetLandingPad(MachineFunction &MF) { MCInst Nop = MF.getSubtarget().getInstrInfo()->getNop(); BuildMI(MBB, MI, DebugLoc(), MF.getSubtarget().getInstrInfo()->get(Nop.getOpcode())); - return false; } } - return true; } // This checks if the source of this function has drifted since this binary was diff --git a/llvm/lib/CodeGen/MachineFunctionSplitter.cpp b/llvm/lib/CodeGen/MachineFunctionSplitter.cpp index 867a7ed..3e1aace 100644 --- a/llvm/lib/CodeGen/MachineFunctionSplitter.cpp +++ b/llvm/lib/CodeGen/MachineFunctionSplitter.cpp @@ -146,7 +146,7 @@ bool MachineFunctionSplitter::runOnMachineFunction(MachineFunction &MF) { return X.getSectionID().Type < Y.getSectionID().Type; }; llvm::sortBasicBlocksAndUpdateBranches(MF, Comparator); - + llvm::avoidZeroOffsetLandingPad(MF); return true; } diff --git a/llvm/test/CodeGen/X86/machine-function-splitter.ll b/llvm/test/CodeGen/X86/machine-function-splitter.ll index e4743e9..8e42851 100644 --- a/llvm/test/CodeGen/X86/machine-function-splitter.ll +++ b/llvm/test/CodeGen/X86/machine-function-splitter.ll @@ -242,6 +242,28 @@ define void @foo9(i1 zeroext %0) nounwind #0 !prof !14 { ret void } +define i32 @foo10(i1 zeroext %0) personality ptr @__gxx_personality_v0 !prof !14 { +;; Check that nop is inserted just before the EH pad if it's beginning a section. +; MFS-DEFAULTS-LABEL: foo10 +; MFS-DEFAULTS-LABEL: callq baz +; MFS-DEFAULTS: .section .text.split.foo10,"ax",@progbits +; MFS-DEFAULTS-NEXT: foo10.cold: +; MFS-DEFAULTS: nop +; MFS-DEFAULTS: callq _Unwind_Resume@PLT +entry: + invoke void @_Z1fv() + to label %try.cont unwind label %lpad, !prof !17 + +lpad: + %1 = landingpad { ptr, i32 } + cleanup + catch ptr @_ZTIi + resume { ptr, i32 } %1 + +try.cont: + %2 = call i32 @baz() + ret i32 %2 +} declare i32 @bar() declare i32 @baz() -- 2.7.4