[llvm] [ARM] Do not emit unwind tables when saving LR around outlined call (PR #69611)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 19 09:16:58 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: None (ostannard)

<details>
<summary>Changes</summary>

In some cases, the machine outliner needs to preserve LR across an
outlined call by pushing it onto the stack. Previously, this also
generated unwind table instructions, which is incorrect because EHABI
unwind tables cannot represent different stack frames a different points
in the function, so the extra unwind info applied to the entire
function.

The outliner code already avoided generating CFI instructions, but EHABI
unwind data is generated later from the actual instructions, so we need
to avoid using the FrameSetup and FrameDestroy flags to prevent unwind
data being generated.

This is my first multi-commit change done through github, it it OK to do this as one PR, or should I raise separate PRs for the two preparatory commits?

---

Patch is 40.22 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/69611.diff


6 Files Affected:

- (modified) llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp (+7-5) 
- (modified) llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp (+12) 
- (modified) llvm/lib/Target/ARM/ARMMachineFunctionInfo.h (+26) 
- (modified) llvm/lib/Target/ARM/ARMTargetMachine.cpp (+21) 
- (modified) llvm/lib/Target/ARM/ARMTargetMachine.h (+8) 
- (added) llvm/test/CodeGen/ARM/machine-outliner-noreturn.mir (+645) 


``````````diff
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 1ffdde0360cf623..bc94b4cd2079caa 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -6450,20 +6450,21 @@ void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
                                      MachineBasicBlock::iterator It, bool CFI,
                                      bool Auth) const {
   int Align = std::max(Subtarget.getStackAlignment().value(), uint64_t(8));
+  unsigned MIFlags = CFI ? MachineInstr::FrameSetup : 0;
   assert(Align >= 8 && Align <= 256);
   if (Auth) {
     assert(Subtarget.isThumb2());
     // Compute PAC in R12. Outlining ensures R12 is dead across the outlined
     // sequence.
     BuildMI(MBB, It, DebugLoc(), get(ARM::t2PAC))
-        .setMIFlags(MachineInstr::FrameSetup);
+        .setMIFlags(MIFlags);
     BuildMI(MBB, It, DebugLoc(), get(ARM::t2STRD_PRE), ARM::SP)
         .addReg(ARM::R12, RegState::Kill)
         .addReg(ARM::LR, RegState::Kill)
         .addReg(ARM::SP)
         .addImm(-Align)
         .add(predOps(ARMCC::AL))
-        .setMIFlags(MachineInstr::FrameSetup);
+        .setMIFlags(MIFlags);
   } else {
     unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
     BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
@@ -6471,7 +6472,7 @@ void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
         .addReg(ARM::SP)
         .addImm(-Align)
         .add(predOps(ARMCC::AL))
-        .setMIFlags(MachineInstr::FrameSetup);
+        .setMIFlags(MIFlags);
   }
 
   if (!CFI)
@@ -6526,6 +6527,7 @@ void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator It,
                                           bool CFI, bool Auth) const {
   int Align = Subtarget.getStackAlignment().value();
+  unsigned MIFlags = CFI ? MachineInstr::FrameDestroy : 0;
   if (Auth) {
     assert(Subtarget.isThumb2());
     // Restore return address PAC and LR.
@@ -6536,7 +6538,7 @@ void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
         .addReg(ARM::SP)
         .addImm(Align)
         .add(predOps(ARMCC::AL))
-        .setMIFlags(MachineInstr::FrameDestroy);
+        .setMIFlags(MIFlags);
     // LR authentication is after the CFI instructions, below.
   } else {
     unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
@@ -6547,7 +6549,7 @@ void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
       MIB.addReg(0);
     MIB.addImm(Subtarget.getStackAlignment().value())
         .add(predOps(ARMCC::AL))
-        .setMIFlags(MachineInstr::FrameDestroy);
+        .setMIFlags(MIFlags);
   }
 
   if (CFI) {
diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
index aa9d8b54d963607..e842715445124c5 100644
--- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
@@ -13,6 +13,18 @@ using namespace llvm;
 
 void ARMFunctionInfo::anchor() {}
 
+yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI)
+    : LRSpilled(MFI.isLRSpilled()) {}
+
+void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
+  MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this);
+}
+
+void ARMFunctionInfo::initializeBaseYamlFields(
+    const yaml::ARMFunctionInfo &YamlMFI) {
+  LRSpilled = YamlMFI.LRSpilled;
+}
+
 static bool GetBranchTargetEnforcement(const Function &F,
                                        const ARMSubtarget *Subtarget) {
   if (!Subtarget->isMClass() || !Subtarget->hasV7Ops())
diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
index f7531ce78ccae4e..eea12a7d3f56874 100644
--- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
+++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
@@ -16,12 +16,17 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MIRYamlMapping.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <utility>
 
 namespace llvm {
 
+namespace yaml {
+struct ARMFunctionInfo;
+} // end namespace yaml
+
 class ARMSubtarget;
 
 /// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
@@ -293,8 +298,29 @@ class ARMFunctionInfo : public MachineFunctionInfo {
   }
 
   bool branchTargetEnforcement() const { return BranchTargetEnforcement; }
+
+  void initializeBaseYamlFields(const yaml::ARMFunctionInfo &YamlMFI);
 };
 
+namespace yaml {
+struct ARMFunctionInfo final : public yaml::MachineFunctionInfo {
+  bool LRSpilled;
+
+  ARMFunctionInfo() = default;
+  ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI);
+
+  void mappingImpl(yaml::IO &YamlIO) override;
+  ~ARMFunctionInfo() = default;
+};
+
+template <> struct MappingTraits<ARMFunctionInfo> {
+  static void mapping(IO &YamlIO, ARMFunctionInfo &MFI) {
+    YamlIO.mapOptional("isLRSpilled", MFI.LRSpilled);
+  }
+};
+
+} // end namespace yaml
+
 } // end namespace llvm
 
 #endif // LLVM_LIB_TARGET_ARM_ARMMACHINEFUNCTIONINFO_H
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index a80d485e750beba..0348ae20fbf1eb5 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -30,6 +30,7 @@
 #include "llvm/CodeGen/GlobalISel/Legalizer.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
+#include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineScheduler.h"
 #include "llvm/CodeGen/Passes.h"
@@ -619,3 +620,23 @@ void ARMPassConfig::addPreEmitPass2() {
     addPass(createEHContGuardCatchretPass());
   }
 }
+
+yaml::MachineFunctionInfo *
+ARMBaseTargetMachine::createDefaultFuncInfoYAML() const {
+  return new yaml::ARMFunctionInfo();
+}
+
+yaml::MachineFunctionInfo *
+ARMBaseTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const {
+  const auto *MFI = MF.getInfo<ARMFunctionInfo>();
+  return new yaml::ARMFunctionInfo(*MFI);
+}
+
+bool ARMBaseTargetMachine::parseMachineFunctionInfo(
+    const yaml::MachineFunctionInfo &MFI, PerFunctionMIParsingState &PFS,
+    SMDiagnostic &Error, SMRange &SourceRange) const {
+  const auto &YamlMFI = static_cast<const yaml::ARMFunctionInfo &>(MFI);
+  MachineFunction &MF = PFS.MF;
+  MF.getInfo<ARMFunctionInfo>()->initializeBaseYamlFields(YamlMFI);
+  return false;
+}
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.h b/llvm/lib/Target/ARM/ARMTargetMachine.h
index 1754382692baadb..69d8fa8ada64983 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.h
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.h
@@ -83,6 +83,14 @@ class ARMBaseTargetMachine : public LLVMTargetMachine {
     // Addrspacecasts are always noops.
     return true;
   }
+
+  yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override;
+  yaml::MachineFunctionInfo *
+  convertFuncInfoToYAML(const MachineFunction &MF) const override;
+  bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &,
+                                PerFunctionMIParsingState &PFS,
+                                SMDiagnostic &Error,
+                                SMRange &SourceRange) const override;
 };
 
 /// ARM/Thumb little endian target machine.
diff --git a/llvm/test/CodeGen/ARM/machine-outliner-noreturn.mir b/llvm/test/CodeGen/ARM/machine-outliner-noreturn.mir
new file mode 100644
index 000000000000000..922b3e77b42a785
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/machine-outliner-noreturn.mir
@@ -0,0 +1,645 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=machine-outliner %s -o - | FileCheck %s
+
+--- |
+  source_filename = "test.cpp"
+  target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+  target triple = "thumbv8.1m.main-arm-none-eabi"
+
+  @__stack_chk_guard = external dso_local global ptr
+
+  define hidden void @_Z2F3v() #0 {
+  entry:
+    %StackGuardSlot = alloca ptr, align 4
+    %i1 = alloca i8, i32 undef, align 8
+    ret void
+  }
+
+  declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) #1
+
+  define hidden void @_Z3F38i(i32 noundef %P0) #0 {
+  entry:
+    %StackGuardSlot = alloca ptr, align 4
+    unreachable
+
+  cond.false:                                       ; preds = %entry
+    ret void
+
+  cond.end:                                         ; preds = %entry
+    ret void
+  }
+
+  declare void @__aeabi_assert(ptr, ptr, i32)
+
+  define hidden void @_Z3F63v(ptr %agg.result) #0 {
+  entry:
+    %StackGuardSlot = alloca ptr, align 4
+    ret void
+  }
+
+  define hidden void @_Z3F94iiz(i32 %P0, i32 %P1, ...) #0 {
+  entry:
+    %StackGuardSlot = alloca ptr, align 4
+    unreachable
+
+  cond.false:                                       ; preds = %entry
+    unreachable
+
+  cond.end:                                         ; preds = %cond.false, %entry
+    unreachable
+
+  cond.false3:                                      ; preds = %cond.end
+    unreachable
+
+  cond.end4:                                        ; preds = %cond.false3, %cond.end
+    unreachable
+  }
+
+  declare ptr @llvm.returnaddress(i32 immarg) #2
+
+  declare void @llvm.va_start(ptr) #3
+
+  declare void @__cxa_throw(ptr, ptr, ptr)
+
+  declare ptr @llvm.stackguard() #3
+
+  declare void @llvm.stackprotector(ptr, ptr) #3
+
+  attributes #0 = { minsize sspreq }
+  attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: write) }
+  attributes #2 = { nocallback nofree nosync nounwind willreturn memory(none) }
+  attributes #3 = { nocallback nofree nosync nounwind willreturn }
+  attributes #4 = { noreturn }
+
+...
+---
+name:            _Z2F3v
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   false
+failsVerification: false
+tracksDebugUserValues: true
+registers:       []
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       24
+  offsetAdjustment: -16
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  '%stack.0.StackGuardSlot'
+  functionContext: ''
+  maxCallFrameSize: 0
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  4
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: StackGuardSlot, type: default, offset: -20, size: 4,
+      alignment: 4, stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      local-offset: -4, debug-info-variable: '', debug-info-expression: '',
+      debug-info-location: '' }
+  - { id: 1, name: i1, type: variable-sized, offset: -20, alignment: 1,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      local-offset: -4, debug-info-variable: '', debug-info-expression: '',
+      debug-info-location: '' }
+  - { id: 2, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 3, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 4, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '$r6', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 5, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '$r4', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:
+  - id:              0
+    value:           i32 -23388
+    alignment:       4
+    isTargetSpecific: false
+machineFunctionInfo:
+  isLRSpilled:     true
+body:             |
+  ; CHECK-LABEL: name: _Z2F3v
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $r4, $r6, $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   frame-setup tPUSH 14 /* CC::al */, $noreg, undef $r2, undef $r3, killed $r4, killed $r6, $r7, killed $lr, implicit-def $sp, implicit $sp
+  ; CHECK-NEXT:   frame-setup CFI_INSTRUCTION def_cfa_offset 24
+  ; CHECK-NEXT:   frame-setup CFI_INSTRUCTION offset $lr, -4
+  ; CHECK-NEXT:   frame-setup CFI_INSTRUCTION offset $r7, -8
+  ; CHECK-NEXT:   frame-setup CFI_INSTRUCTION offset $r6, -12
+  ; CHECK-NEXT:   frame-setup CFI_INSTRUCTION offset $r4, -16
+  ; CHECK-NEXT:   $r7 = frame-setup tADDrSPi $sp, 4, 14 /* CC::al */, $noreg
+  ; CHECK-NEXT:   frame-setup CFI_INSTRUCTION def_cfa $r7, 8
+  ; CHECK-NEXT:   $r0 = t2MOVi16 target-flags(arm-lo16) @__stack_chk_guard, 14 /* CC::al */, $noreg
+  ; CHECK-NEXT:   renamable $r1 = t2MVNi 91, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK-NEXT:   $r0 = t2MOVTi16 killed $r0, target-flags(arm-hi16) @__stack_chk_guard, 14 /* CC::al */, $noreg
+  ; CHECK-NEXT:   $r0 = tLDRi killed $r0, 0, 14 /* CC::al */, $noreg :: (dereferenceable invariant load (s32) from @__stack_chk_guard)
+  ; CHECK-NEXT:   t2STRi8 killed renamable $r0, $r7, -12, 14 /* CC::al */, $noreg :: (volatile store (s32) into %stack.0.StackGuardSlot)
+  ; CHECK-NEXT:   $r0 = tMOVr $sp, 14 /* CC::al */, $noreg
+  ; CHECK-NEXT:   tSTRBi killed renamable $r1, renamable $r0, 2, 14 /* CC::al */, $noreg :: (store (s8) into %ir.i1 + 2, align 2, basealign 8)
+  ; CHECK-NEXT:   renamable $r1 = tLDRpci %const.0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool)
+  ; CHECK-NEXT:   tSTRHi killed renamable $r1, killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (store (s16) into %ir.i1, align 8)
+  ; CHECK-NEXT:   tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1, implicit-def $lr, implicit $sp, implicit-def $r1, implicit-def $lr, implicit $noreg, implicit $sp
+  ; CHECK-NEXT:   renamable $r0 = t2LDRi8 $r7, -12, 14 /* CC::al */, $noreg :: (volatile load (s32) from %stack.0.StackGuardSlot)
+  ; CHECK-NEXT:   $r1 = tLDRi killed $r1, 0, 14 /* CC::al */, $noreg :: (dereferenceable invariant load (s32) from @__stack_chk_guard)
+  ; CHECK-NEXT:   tCMPr killed renamable $r1, killed renamable $r0, 14 /* CC::al */, $noreg, implicit-def $cpsr
+  ; CHECK-NEXT:   t2IT 0, 2, implicit-def $itstate
+  ; CHECK-NEXT:   $r4 = frame-destroy t2SUBri $r7, 8, 0 /* CC::eq */, $cpsr, $noreg, implicit $itstate
+  ; CHECK-NEXT:   $sp = frame-destroy tMOVr $r4, 0 /* CC::eq */, $cpsr, implicit $itstate
+  ; CHECK-NEXT:   frame-destroy tPOP_RET 0 /* CC::eq */, killed $cpsr, def $r4, def $r6, def $r7, def $pc, implicit killed $r4, implicit killed $itstate
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.entry:
+  ; CHECK-NEXT:   tBL 14 /* CC::al */, $noreg, &__stack_chk_fail, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+  bb.0.entry:
+    successors: %bb.1(0x00000800)
+    liveins: $r4, $r6, $lr
+
+    frame-setup tPUSH 14 /* CC::al */, $noreg, undef $r2, undef $r3, killed $r4, killed $r6, $r7, killed $lr, implicit-def $sp, implicit $sp
+    frame-setup CFI_INSTRUCTION def_cfa_offset 24
+    frame-setup CFI_INSTRUCTION offset $lr, -4
+    frame-setup CFI_INSTRUCTION offset $r7, -8
+    frame-setup CFI_INSTRUCTION offset $r6, -12
+    frame-setup CFI_INSTRUCTION offset $r4, -16
+    $r7 = frame-setup tADDrSPi $sp, 4, 14 /* CC::al */, $noreg
+    frame-setup CFI_INSTRUCTION def_cfa $r7, 8
+    $r0 = t2MOVi16 target-flags(arm-lo16) @__stack_chk_guard, 14 /* CC::al */, $noreg
+    renamable $r1 = t2MVNi 91, 14 /* CC::al */, $noreg, $noreg
+    $r0 = t2MOVTi16 killed $r0, target-flags(arm-hi16) @__stack_chk_guard, 14 /* CC::al */, $noreg
+    $r0 = tLDRi killed $r0, 0, 14 /* CC::al */, $noreg :: (dereferenceable invariant load (s32) from @__stack_chk_guard)
+    t2STRi8 killed renamable $r0, $r7, -12, 14 /* CC::al */, $noreg :: (volatile store (s32) into %stack.0.StackGuardSlot)
+    $r0 = tMOVr $sp, 14 /* CC::al */, $noreg
+    tSTRBi killed renamable $r1, renamable $r0, 2, 14 /* CC::al */, $noreg :: (store (s8) into %ir.i1 + 2, align 2, basealign 8)
+    renamable $r1 = tLDRpci %const.0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool)
+    tSTRHi killed renamable $r1, killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (store (s16) into %ir.i1, align 8)
+    $r1 = t2MOVi16 target-flags(arm-lo16) @__stack_chk_guard, 14 /* CC::al */, $noreg
+    $r1 = t2MOVTi16 killed $r1, target-flags(arm-hi16) @__stack_chk_guard, 14 /* CC::al */, $noreg
+    renamable $r0 = t2LDRi8 $r7, -12, 14 /* CC::al */, $noreg :: (volatile load (s32) from %stack.0.StackGuardSlot)
+    $r1 = tLDRi killed $r1, 0, 14 /* CC::al */, $noreg :: (dereferenceable invariant load (s32) from @__stack_chk_guard)
+    tCMPr killed renamable $r1, killed renamable $r0, 14 /* CC::al */, $noreg, implicit-def $cpsr
+    t2IT 0, 2, implicit-def $itstate
+    $r4 = frame-destroy t2SUBri $r7, 8, 0 /* CC::eq */, $cpsr, $noreg, implicit $itstate
+    $sp = frame-destroy tMOVr $r4, 0 /* CC::eq */, $cpsr, implicit $itstate
+    frame-destroy tPOP_RET 0 /* CC::eq */, killed $cpsr, def $r4, def $r6, def $r7, def $pc, implicit killed $r4, implicit killed $itstate
+
+  bb.1.entry:
+    tBL 14 /* CC::al */, $noreg, &__stack_chk_fail, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+
+...
+---
+name:            _Z3F38i
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   false
+failsVerification: false
+tracksDebugUserValues: true
+registers:       []
+liveins:
+  - { reg: '$r0', virtual-reg: '' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       16
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  stackProtector:  '%stack.0.StackGuardSlot'
+  functionContext: ''
+  maxCallFrameSize: 0
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     true
+  localFrameSize:  4
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: StackGuardSlot, type: default, offset: -12, size: 4,
+      alignment: 4, stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      local-offset: -4, debug-info-variable: '', debug-info-expression: '',
+      debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 2, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo:
+  isLRSpilled:     true
+body:             |
+  ; CHECK-LABEL: name: _Z3F38i
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.3(0x40000000)
+  ; CHECK-NEXT:   liveins: $r0, $r7, $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   frame-setup tPUSH 14 /* CC::al */, $noreg, undef $r5, und...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/69611


More information about the llvm-commits mailing list