[RISCV] Force a frame pointer when the max reserved call frame exceeds simm12. (#182124)

We need to be able to address emergency spill slots without requiring a
register scavenging. This requires the emergency spill slot to be near
the SP or the FP to keep the offset small enough. If there is a large
reserved call frame, we can't keep the emergency spill slot near SP. But
we might not have a frame pointer.

This patch forces the use of a frame pointer when the max reserved call
frame is large so we can keep the emergency spill slot near it. This
idea is borrowed from AArch64.

Multiple MIR tests had to be updated to set the max call frame size as
the reserved registers are frozen before mirFileLoaded is called. I
copied mirFileLoaded from AArch64, but it appears the register freezing
moved after the AArch64 code was written.

Fixes #180199.
This commit is contained in:
Craig Topper 2026-02-18 16:42:40 -08:00 committed by GitHub
parent 7772a45b1a
commit e246d1615e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 261 additions and 28 deletions

View File

@ -486,9 +486,26 @@ bool RISCVFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
MFI.isFrameAddressTaken();
if (MF.getTarget().Options.DisableFramePointerElim(MF) ||
RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
MFI.isFrameAddressTaken())
return true;
// With large callframes around we may need to use FP to access the scavenging
// emergency spillslot.
//
// We calculate the MaxCallFrameSize at the end of isel so this value should
// be stable for the whole post-isel MIR pipeline.
//
// NOTE: The idea of forcing a frame pointer is copied from AArch64, but they
// conservatively return true when the call frame size hasd not been
// computed yet. On RISC-V that caused MachineOutliner tests to fail the
// MachineVerifier due to outlined functions not computing max call frame
// size thus the frame pointer would always be reserved.
if (MFI.isMaxCallFrameSizeComputed() && MFI.getMaxCallFrameSize() > 2047)
return true;
return false;
}
bool RISCVFrameLowering::hasBP(const MachineFunction &MF) const {

View File

@ -17,6 +17,7 @@
#include "RISCVFrameLowering.h"
#include "RISCVSelectionDAGInfo.h"
#include "RISCVTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
@ -237,6 +238,16 @@ bool RISCVSubtarget::enableMachinePipeliner() const {
return getSchedModel().hasInstrSchedModel();
}
void RISCVSubtarget::mirFileLoaded(MachineFunction &MF) const {
// We usually compute max call frame size after ISel. Do the computation now
// if the .mir file didn't specify it. Note that this will probably give you
// bogus values after PEI has eliminated the callframe setup/destroy pseudo
// instructions, specify explicitly if you need it to be correct.
MachineFrameInfo &MFI = MF.getFrameInfo();
if (!MFI.isMaxCallFrameSizeComputed())
MFI.computeMaxCallFrameSize(MF);
}
/// Enable use of alias analysis during code generation (during MI
/// scheduling, DAGCombine, etc.).
bool RISCVSubtarget::useAA() const { return UseAA; }

View File

@ -147,6 +147,8 @@ public:
return &TLInfo;
}
void mirFileLoaded(MachineFunction &MF) const override;
bool enableMachineScheduler() const override { return true; }
bool enablePostRAScheduler() const override { return UsePostRAScheduler; }

View File

@ -3,6 +3,8 @@
---
name: mov-merge
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0.entry:
liveins: $x8, $x9

View File

@ -1,7 +1,7 @@
# RUN: not --crash llc -mtriple=riscv32 -run-pass=prologepilog -verify-machineinstrs -filetype=null %s 2>&1 | FileCheck %s
# CHECK: LLVM ERROR: Incomplete scavenging after 2nd pass
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
# RUN: llc -mtriple=riscv32 -run-pass=prologepilog -verify-machineinstrs %s -o - | FileCheck %s
---
name: main
alignment: 2
tracksRegLiveness: true
@ -9,6 +9,7 @@ frameInfo:
maxAlignment: 4
adjustsStack: true
hasCalls: true
maxCallFrameSize: 2276
stack:
- { id: 0, name: '', type: default, offset: 0, size: 2304, alignment: 4,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
@ -25,6 +26,134 @@ stack:
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
bb.0:
; CHECK-LABEL: name: main
; CHECK: liveins: $x1, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -2032
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 2032
; CHECK-NEXT: frame-setup SW killed $x1, $x2, 2028 :: (store (s32) into %stack.4)
; CHECK-NEXT: frame-setup SW killed $x8, $x2, 2024 :: (store (s32) into %stack.5)
; CHECK-NEXT: frame-setup SW killed $x9, $x2, 2020 :: (store (s32) into %stack.6)
; CHECK-NEXT: frame-setup SW killed $x18, $x2, 2016 :: (store (s32) into %stack.7)
; CHECK-NEXT: frame-setup SW killed $x19, $x2, 2012 :: (store (s32) into %stack.8)
; CHECK-NEXT: frame-setup SW killed $x20, $x2, 2008 :: (store (s32) into %stack.9)
; CHECK-NEXT: frame-setup SW killed $x21, $x2, 2004 :: (store (s32) into %stack.10)
; CHECK-NEXT: frame-setup SW killed $x22, $x2, 2000 :: (store (s32) into %stack.11)
; CHECK-NEXT: frame-setup SW killed $x23, $x2, 1996 :: (store (s32) into %stack.12)
; CHECK-NEXT: frame-setup SW killed $x24, $x2, 1992 :: (store (s32) into %stack.13)
; CHECK-NEXT: frame-setup SW killed $x25, $x2, 1988 :: (store (s32) into %stack.14)
; CHECK-NEXT: frame-setup SW killed $x26, $x2, 1984 :: (store (s32) into %stack.15)
; CHECK-NEXT: frame-setup SW killed $x27, $x2, 1980 :: (store (s32) into %stack.16)
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x1, -4
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x8, -8
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x9, -12
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x18, -16
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x19, -20
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x20, -24
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x21, -28
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x22, -32
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x23, -36
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x24, -40
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x25, -44
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x26, -48
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x27, -52
; CHECK-NEXT: $x8 = frame-setup ADDI $x2, 2032
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa $x8, 0
; CHECK-NEXT: $x10 = frame-setup LUI 2
; CHECK-NEXT: $x10 = frame-setup ADDI killed $x10, -1168
; CHECK-NEXT: $x2 = frame-setup SUB $x2, killed $x10
; CHECK-NEXT: renamable $x10 = ADDI $x8, -440
; CHECK-NEXT: $x11 = LUI 2
; CHECK-NEXT: $x11 = SUB $x8, killed $x11
; CHECK-NEXT: $x11 = LW killed $x11, 1420
; CHECK-NEXT: renamable $x12 = LW undef renamable $x10, 1
; CHECK-NEXT: renamable $x13 = LW undef renamable $x10, 9
; CHECK-NEXT: renamable $x14 = LW undef renamable $x10, 13
; CHECK-NEXT: renamable $x15 = LW undef renamable $x10, 17
; CHECK-NEXT: renamable $x16 = LW undef renamable $x10, 21
; CHECK-NEXT: renamable $x17 = LW undef renamable $x10, 25
; CHECK-NEXT: renamable $x5 = LW undef renamable $x10, 29
; CHECK-NEXT: renamable $x6 = LW undef renamable $x10, 33
; CHECK-NEXT: renamable $x7 = LW undef renamable $x10, 37
; CHECK-NEXT: renamable $x28 = LW undef renamable $x10, 41
; CHECK-NEXT: renamable $x29 = LW undef renamable $x10, 45
; CHECK-NEXT: renamable $x30 = LW undef renamable $x10, 49
; CHECK-NEXT: renamable $x31 = LW undef renamable $x10, 53
; CHECK-NEXT: renamable $x9 = LW undef renamable $x10, 61
; CHECK-NEXT: renamable $x18 = LW undef renamable $x10, 65
; CHECK-NEXT: renamable $x19 = LW undef renamable $x10, 69
; CHECK-NEXT: renamable $x20 = LW undef renamable $x10, 73
; CHECK-NEXT: renamable $x21 = LW undef renamable $x10, 77
; CHECK-NEXT: renamable $x22 = LW undef renamable $x10, 81
; CHECK-NEXT: renamable $x23 = LW undef renamable $x10, 85
; CHECK-NEXT: renamable $x24 = LW undef renamable $x10, 89
; CHECK-NEXT: renamable $x25 = LW undef renamable $x10, 93
; CHECK-NEXT: renamable $x26 = LW undef renamable $x10, 97
; CHECK-NEXT: renamable $x27 = LW undef renamable $x10, 101
; CHECK-NEXT: renamable $x1 = LW undef renamable $x10, 105
; CHECK-NEXT: SW killed $x11, $x8, -56 :: (store (s32) into %stack.17)
; CHECK-NEXT: $x11 = LUI 1
; CHECK-NEXT: $x11 = SUB $x8, killed $x11
; CHECK-NEXT: SW $x10, killed $x11, -472
; CHECK-NEXT: $x11 = LW $x8, -56 :: (load (s32) from %stack.17)
; CHECK-NEXT: SW killed renamable $x1, undef renamable $x11, 105
; CHECK-NEXT: SW killed renamable $x27, undef renamable $x11, 101
; CHECK-NEXT: SW killed renamable $x26, renamable $x11, 97
; CHECK-NEXT: SW killed renamable $x25, undef renamable $x11, 93
; CHECK-NEXT: SW killed renamable $x24, undef renamable $x11, 89
; CHECK-NEXT: SW killed renamable $x23, undef renamable $x11, 85
; CHECK-NEXT: SW killed renamable $x22, undef renamable $x11, 81
; CHECK-NEXT: SW killed renamable $x21, undef renamable $x11, 77
; CHECK-NEXT: SW killed renamable $x20, undef renamable $x11, 73
; CHECK-NEXT: SW killed renamable $x19, undef renamable $x11, 69
; CHECK-NEXT: SW killed renamable $x18, undef renamable $x11, 65
; CHECK-NEXT: SW killed renamable $x9, undef renamable $x11, 61
; CHECK-NEXT: SW killed renamable $x31, undef renamable $x11, 53
; CHECK-NEXT: SW killed renamable $x30, undef renamable $x11, 49
; CHECK-NEXT: SW killed renamable $x29, undef renamable $x11, 45
; CHECK-NEXT: SW killed renamable $x28, undef renamable $x11, 41
; CHECK-NEXT: SW killed renamable $x7, undef renamable $x11, 37
; CHECK-NEXT: SW killed renamable $x6, undef renamable $x11, 33
; CHECK-NEXT: SW killed renamable $x5, undef renamable $x11, 29
; CHECK-NEXT: SW killed renamable $x17, undef renamable $x11, 25
; CHECK-NEXT: SW killed renamable $x16, undef renamable $x11, 21
; CHECK-NEXT: SW killed renamable $x15, undef renamable $x11, 17
; CHECK-NEXT: SW killed renamable $x14, undef renamable $x11, 13
; CHECK-NEXT: SW killed renamable $x13, undef renamable $x11, 9
; CHECK-NEXT: SW killed renamable $x12, undef renamable $x11, 5
; CHECK-NEXT: $x10 = frame-destroy LUI 2
; CHECK-NEXT: $x10 = frame-destroy ADDI killed $x10, -1168
; CHECK-NEXT: $x2 = frame-destroy ADD $x2, killed $x10
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa $x2, 2032
; CHECK-NEXT: $x1 = frame-destroy LW $x2, 2028 :: (load (s32) from %stack.4)
; CHECK-NEXT: $x8 = frame-destroy LW $x2, 2024 :: (load (s32) from %stack.5)
; CHECK-NEXT: $x9 = frame-destroy LW $x2, 2020 :: (load (s32) from %stack.6)
; CHECK-NEXT: $x18 = frame-destroy LW $x2, 2016 :: (load (s32) from %stack.7)
; CHECK-NEXT: $x19 = frame-destroy LW $x2, 2012 :: (load (s32) from %stack.8)
; CHECK-NEXT: $x20 = frame-destroy LW $x2, 2008 :: (load (s32) from %stack.9)
; CHECK-NEXT: $x21 = frame-destroy LW $x2, 2004 :: (load (s32) from %stack.10)
; CHECK-NEXT: $x22 = frame-destroy LW $x2, 2000 :: (load (s32) from %stack.11)
; CHECK-NEXT: $x23 = frame-destroy LW $x2, 1996 :: (load (s32) from %stack.12)
; CHECK-NEXT: $x24 = frame-destroy LW $x2, 1992 :: (load (s32) from %stack.13)
; CHECK-NEXT: $x25 = frame-destroy LW $x2, 1988 :: (load (s32) from %stack.14)
; CHECK-NEXT: $x26 = frame-destroy LW $x2, 1984 :: (load (s32) from %stack.15)
; CHECK-NEXT: $x27 = frame-destroy LW $x2, 1980 :: (load (s32) from %stack.16)
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x1
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x8
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x9
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x18
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x19
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x20
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x21
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x22
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x23
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x24
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x25
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x26
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x27
; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 2032
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
; CHECK-NEXT: PseudoRET
renamable $x10 = ADDI %stack.0, 1920
ADJCALLSTACKDOWN 2276, 0, implicit-def dead $x2, implicit $x2
$x11 = LW %stack.3, 0
@ -42,7 +171,6 @@ body: |
renamable $x29 = LW undef renamable $x10, 45
renamable $x30 = LW undef renamable $x10, 49
renamable $x31 = LW undef renamable $x10, 53
renamable $x8 = LW undef renamable $x10, 57
renamable $x9 = LW undef renamable $x10, 61
renamable $x18 = LW undef renamable $x10, 65
renamable $x19 = LW undef renamable $x10, 69
@ -68,7 +196,6 @@ body: |
SW killed renamable $x19, undef renamable $x11, 69
SW killed renamable $x18, undef renamable $x11, 65
SW killed renamable $x9, undef renamable $x11, 61
SW killed renamable $x8, undef renamable $x11, 57
SW killed renamable $x31, undef renamable $x11, 53
SW killed renamable $x30, undef renamable $x11, 49
SW killed renamable $x29, undef renamable $x11, 45

View File

@ -1,7 +1,7 @@
# RUN: not --crash llc -mtriple=riscv64 -run-pass=prologepilog -verify-machineinstrs -filetype=null %s 2>&1 | FileCheck %s
# CHECK: LLVM ERROR: Incomplete scavenging after 2nd pass
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
# RUN: llc -mtriple=riscv64 -run-pass=prologepilog -verify-machineinstrs %s -o - | FileCheck %s
---
name: test
alignment: 4
tracksRegLiveness: true
@ -12,11 +12,65 @@ frameInfo:
maxAlignment: 8
adjustsStack: true
hasCalls: true
maxCallFrameSize: 4808
stack:
- { id: 0, name: '', type: spill-slot, offset: 0, size: 104, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
; CHECK-LABEL: name: test
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.5(0x40000000)
; CHECK-NEXT: liveins: $x10, $x11, $x12, $x1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -2032
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 2032
; CHECK-NEXT: frame-setup SD killed $x1, $x2, 2024 :: (store (s64) into %stack.1)
; CHECK-NEXT: frame-setup SD killed $x8, $x2, 2016 :: (store (s64) into %stack.2)
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x1, -8
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x8, -16
; CHECK-NEXT: $x8 = frame-setup ADDI $x2, 2032
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa $x8, 0
; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -2048
; CHECK-NEXT: $x2 = frame-setup ADDI killed $x2, -864
; CHECK-NEXT: BEQ undef renamable $x10, $x0, %bb.5
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: liveins: $x11, $x30
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3:
; CHECK-NEXT: successors: %bb.4(0x04000000), %bb.3(0x7c000000)
; CHECK-NEXT: liveins: $x6, $x8, $x9, $x10, $x11, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x28, $x31, $x30
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: SD undef renamable $x23, $x8, -128
; CHECK-NEXT: BEQ undef renamable $x30, $x0, %bb.3
; CHECK-NEXT: PseudoBR %bb.4
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: liveins: $x1, $x5, $x7, $x11, $x12, $x13, $x14, $x15, $x16, $x25, $x26, $x27, $x29, $x30
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: PseudoBR %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.5:
; CHECK-NEXT: liveins: $x10
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 2032
; CHECK-NEXT: $x2 = frame-destroy ADDI killed $x2, 880
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa $x2, 2032
; CHECK-NEXT: $x1 = frame-destroy LD $x2, 2024 :: (load (s64) from %stack.1)
; CHECK-NEXT: $x8 = frame-destroy LD $x2, 2016 :: (load (s64) from %stack.2)
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x1
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x8
; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 2032
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
; CHECK-NEXT: PseudoRET
bb.0:
successors: %bb.1(0x40000000), %bb.5(0x40000000)
liveins: $x10, $x11, $x12

View File

@ -456,22 +456,25 @@ define void @reserved_call_frame(i64 %n) #0 {
; RV64I-NEXT: addi sp, sp, -2032
; RV64I-NEXT: .cfi_def_cfa_offset 2032
; RV64I-NEXT: sd ra, 2024(sp) # 8-byte Folded Spill
; RV64I-NEXT: sd s0, 2016(sp) # 8-byte Folded Spill
; RV64I-NEXT: .cfi_offset ra, -8
; RV64I-NEXT: .cfi_offset s0, -16
; RV64I-NEXT: addi s0, sp, 2032
; RV64I-NEXT: .cfi_def_cfa s0, 0
; RV64I-NEXT: addi sp, sp, -64
; RV64I-NEXT: lui a0, 1
; RV64I-NEXT: sub sp, sp, a0
; RV64I-NEXT: sd zero, 0(sp)
; RV64I-NEXT: .cfi_def_cfa_offset 6128
; RV64I-NEXT: addi sp, sp, -48
; RV64I-NEXT: .cfi_def_cfa_offset 6176
; RV64I-NEXT: lui a0, 1
; RV64I-NEXT: add a0, sp, a0
; RV64I-NEXT: addi a0, s0, -2048
; RV64I-NEXT: addi a0, a0, -48
; RV64I-NEXT: call callee_stack_args
; RV64I-NEXT: lui a0, 1
; RV64I-NEXT: addi a0, a0, 48
; RV64I-NEXT: add sp, sp, a0
; RV64I-NEXT: .cfi_def_cfa_offset 2032
; RV64I-NEXT: addi sp, s0, -2032
; RV64I-NEXT: .cfi_def_cfa sp, 2032
; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload
; RV64I-NEXT: .cfi_restore ra
; RV64I-NEXT: .cfi_restore s0
; RV64I-NEXT: addi sp, sp, 2032
; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
@ -481,23 +484,28 @@ define void @reserved_call_frame(i64 %n) #0 {
; RV32I-NEXT: addi sp, sp, -2032
; RV32I-NEXT: .cfi_def_cfa_offset 2032
; RV32I-NEXT: sw ra, 2028(sp) # 4-byte Folded Spill
; RV32I-NEXT: sw s0, 2024(sp) # 4-byte Folded Spill
; RV32I-NEXT: .cfi_offset ra, -4
; RV32I-NEXT: .cfi_offset s0, -8
; RV32I-NEXT: addi s0, sp, 2032
; RV32I-NEXT: .cfi_def_cfa s0, 0
; RV32I-NEXT: addi sp, sp, -64
; RV32I-NEXT: lui a0, 1
; RV32I-NEXT: sub sp, sp, a0
; RV32I-NEXT: sw zero, 0(sp)
; RV32I-NEXT: .cfi_def_cfa_offset 6128
; RV32I-NEXT: addi sp, sp, -80
; RV32I-NEXT: .cfi_def_cfa_offset 6208
; RV32I-NEXT: lui a0, 1
; RV32I-NEXT: addi a0, a0, 36
; RV32I-NEXT: add a0, sp, a0
; RV32I-NEXT: addi sp, sp, -32
; RV32I-NEXT: addi a0, s0, -2048
; RV32I-NEXT: addi a0, a0, -36
; RV32I-NEXT: call callee_stack_args
; RV32I-NEXT: lui a0, 1
; RV32I-NEXT: addi a0, a0, 80
; RV32I-NEXT: addi a0, a0, 32
; RV32I-NEXT: add sp, sp, a0
; RV32I-NEXT: .cfi_def_cfa_offset 2032
; RV32I-NEXT: addi sp, s0, -2032
; RV32I-NEXT: .cfi_def_cfa sp, 2032
; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload
; RV32I-NEXT: .cfi_restore ra
; RV32I-NEXT: .cfi_restore s0
; RV32I-NEXT: addi sp, sp, 2032
; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret

View File

@ -86,7 +86,7 @@ frameInfo:
adjustsStack: true
hasCalls: true
stackProtector: ''
maxCallFrameSize: 4294967295
maxCallFrameSize: 0
cvBytesOfCalleeSavedRegisters: 0
hasOpaqueSPAdjustment: false
hasVAStart: false

View File

@ -6,6 +6,8 @@
---
name: popret_rvlist5
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0:
; CHECK-XQCCMP32-LABEL: name: popret_rvlist5
@ -36,6 +38,8 @@ body: |
---
name: popretz_rvlist5
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0:
; CHECK-XQCCMP32-LABEL: name: popretz_rvlist5

View File

@ -6,6 +6,8 @@
---
name: push_rvlist15
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0:
; CHECK-XQCCMP32-LABEL: name: push_rvlist15

View File

@ -14,6 +14,8 @@
---
name: popret_rvlist5
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0:
; CHECK-ZCMP32-LABEL: name: popret_rvlist5
@ -104,6 +106,8 @@ body: |
---
name: popretz_rvlist5
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0:
; CHECK-ZCMP32-LABEL: name: popretz_rvlist5

View File

@ -14,6 +14,8 @@
---
name: push_rvlist15
tracksRegLiveness: true
frameInfo:
maxCallFrameSize: 0
body: |
bb.0:
; CHECK-ZCMP32-LABEL: name: push_rvlist15