From b68703ce2e41469d784e435da4f8b0a8c895c901 Mon Sep 17 00:00:00 2001 From: Daniil Avdeev Date: Tue, 1 Oct 2024 17:15:03 +0300 Subject: [PATCH 1/2] [RISCV] fix SP recovery in the function epilogue This patch fixes SP register recovery in the function epilogue. --- llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 103 ++++++++++++------- llvm/lib/Target/RISCV/RISCVFrameLowering.h | 4 + 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index b0c525ea8c299..f388376c12c94 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -755,6 +755,19 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, } } +void RISCVFrameLowering::deallocateStack(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + const DebugLoc &DL, uint64_t StackSize, + int64_t CFAOffset) const { + const RISCVRegisterInfo *RI = STI.getRegisterInfo(); + + Register SPReg = getSPReg(STI); + + RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize), + MachineInstr::FrameDestroy, getStackAlign()); +} + void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { const RISCVRegisterInfo *RI = STI.getRegisterInfo(); @@ -786,20 +799,49 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, --MBBI; } - const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo()); + const auto &CSI = MFI.getCalleeSavedInfo(); // Skip to before the restores of scalar callee-saved registers // FIXME: assumes exactly one instruction is used to restore each // callee-saved register. - auto LastFrameDestroy = MBBI; - if (!CSI.empty()) - LastFrameDestroy = std::prev(MBBI, CSI.size()); + auto LastFrameDestroy = std::prev(MBBI, getUnmanagedCSI(MF, CSI).size()); - uint64_t RealStackSize = getStackSizeWithRVVPadding(MF); - uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize(); - uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize(); + uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); + uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount + : getStackSizeWithRVVPadding(MF); + uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount + : getStackSizeWithRVVPadding(MF) - + RVFI->getReservedSpillsSize(); + uint64_t FPOffset = FirstSPAdjustAmount ? FirstSPAdjustAmount + : getStackSizeWithRVVPadding(MF) - + RVFI->getVarArgsSaveSize(); uint64_t RVVStackSize = RVFI->getRVVStackSize(); + bool RestoreFP = RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || + !hasReservedCallFrame(MF); + + if (RVVStackSize) { + // If RestoreFP the stack pointer will be restored using the frame pointer + // value. + if (!RestoreFP) + adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize, + MachineInstr::FrameDestroy); + } + + if (FirstSPAdjustAmount) { + uint64_t SecondSPAdjustAmount = + getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount; + assert(SecondSPAdjustAmount > 0 && + "SecondSPAdjustAmount should be greater than zero"); + + // If RestoreFP the stack pointer will be restored using the frame pointer + // value. + if (!RestoreFP) + RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, + StackOffset::getFixed(SecondSPAdjustAmount), + MachineInstr::FrameDestroy, getStackAlign()); + } + // Restore the stack pointer using the value of the frame pointer. Only // necessary if the stack pointer was modified, meaning the stack size is // unknown. @@ -810,35 +852,17 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, // normally it's just checking the variable sized object is present or not // is enough, but we also don't preserve that at prologue/epilogue when // have vector objects in stack. - if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || - !hasReservedCallFrame(MF)) { + if (RestoreFP) { assert(hasFP(MF) && "frame pointer should not have been eliminated"); - RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, - StackOffset::getFixed(-FPOffset), - MachineInstr::FrameDestroy, getStackAlign()); - } else { - if (RVVStackSize) - adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize, - MachineInstr::FrameDestroy); - } - uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); - if (FirstSPAdjustAmount) { - uint64_t SecondSPAdjustAmount = - getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount; - assert(SecondSPAdjustAmount > 0 && - "SecondSPAdjustAmount should be greater than zero"); - - RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, - StackOffset::getFixed(SecondSPAdjustAmount), - MachineInstr::FrameDestroy, getStackAlign()); + RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, + StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy, + getStackAlign()); } - if (FirstSPAdjustAmount) - StackSize = FirstSPAdjustAmount; - - if (RVFI->isPushable(MF) && MBBI != MBB.end() && - MBBI->getOpcode() == RISCV::CM_POP) { + bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() && + MBBI->getOpcode() == RISCV::CM_POP; + if (ApplyPop) { // Use available stack adjustment in pop instruction to deallocate stack // space. Align the stack size down to a multiple of 16. This is needed for // RVE. @@ -846,14 +870,19 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48); MBBI->getOperand(1).setImm(Spimm); StackSize -= Spimm; - } - // Deallocate stack - if (StackSize != 0) { - RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize), - MachineInstr::FrameDestroy, getStackAlign()); + if (StackSize != 0) + deallocateStack(MF, MBB, MBBI, DL, StackSize, + /*stack_adj of cm.pop instr*/ RealStackSize - StackSize); + + ++MBBI; } + // Deallocate stack if we didn't already do it during cm.pop handling and + // StackSize isn't a zero + if (StackSize != 0 && !ApplyPop) + deallocateStack(MF, MBB, MBBI, DL, StackSize, 0); + // Emit epilogue for shadow call stack. emitSCSEpilogue(MF, MBB, MBBI, DL); } diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h index 28ab4aff3b9d5..d660f3ad67c96 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h @@ -91,6 +91,10 @@ class RISCVFrameLowering : public TargetFrameLowering { void emitCalleeSavedRVVPrologCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const; + void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, const DebugLoc &DL, + uint64_t StackSize, int64_t CFAOffset) const; + std::pair assignRVVStackObjectOffsets(MachineFunction &MF) const; }; From 536cbea83d8b8b9c3eb0ced95a117250008b4244 Mon Sep 17 00:00:00 2001 From: Daniil Avdeev Date: Tue, 1 Oct 2024 17:16:01 +0300 Subject: [PATCH 2/2] [RISCV] update tests --- llvm/test/CodeGen/RISCV/branch-relaxation.ll | 20 ++----- .../RISCV/out-of-reach-emergency-slot.mir | 5 +- .../RISCV/rvv/addi-scalable-offset.mir | 4 +- .../CodeGen/RISCV/rvv/callee-saved-regs.ll | 4 +- .../test/CodeGen/RISCV/rvv/emergency-slot.mir | 4 +- .../RISCV/rvv/large-rvv-stack-size.mir | 4 +- llvm/test/CodeGen/RISCV/stack-realignment.ll | 52 +++++-------------- 7 files changed, 21 insertions(+), 72 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/branch-relaxation.ll b/llvm/test/CodeGen/RISCV/branch-relaxation.ll index 3d48dc9637eae..ec77d54da116d 100644 --- a/llvm/test/CodeGen/RISCV/branch-relaxation.ll +++ b/llvm/test/CodeGen/RISCV/branch-relaxation.ll @@ -824,10 +824,7 @@ define void @relax_jal_spill_32_adjust_spill_slot() { ; CHECK-RV32-NEXT: #APP ; CHECK-RV32-NEXT: # reg use t6 ; CHECK-RV32-NEXT: #NO_APP -; CHECK-RV32-NEXT: lui a0, 2 -; CHECK-RV32-NEXT: sub sp, s0, a0 -; CHECK-RV32-NEXT: addi a0, a0, -2032 -; CHECK-RV32-NEXT: add sp, sp, a0 +; CHECK-RV32-NEXT: addi sp, s0, -2032 ; CHECK-RV32-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; CHECK-RV32-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; CHECK-RV32-NEXT: lw s1, 2020(sp) # 4-byte Folded Reload @@ -1073,10 +1070,7 @@ define void @relax_jal_spill_32_adjust_spill_slot() { ; CHECK-RV64-NEXT: #APP ; CHECK-RV64-NEXT: # reg use t6 ; CHECK-RV64-NEXT: #NO_APP -; CHECK-RV64-NEXT: lui a0, 2 -; CHECK-RV64-NEXT: sub sp, s0, a0 -; CHECK-RV64-NEXT: addiw a0, a0, -2032 -; CHECK-RV64-NEXT: add sp, sp, a0 +; CHECK-RV64-NEXT: addi sp, s0, -2032 ; CHECK-RV64-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; CHECK-RV64-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; CHECK-RV64-NEXT: ld s1, 2008(sp) # 8-byte Folded Reload @@ -2323,10 +2317,7 @@ define void @relax_jal_spill_64_adjust_spill_slot() { ; CHECK-RV32-NEXT: #APP ; CHECK-RV32-NEXT: # reg use t6 ; CHECK-RV32-NEXT: #NO_APP -; CHECK-RV32-NEXT: lui a0, 2 -; CHECK-RV32-NEXT: sub sp, s0, a0 -; CHECK-RV32-NEXT: addi a0, a0, -2032 -; CHECK-RV32-NEXT: add sp, sp, a0 +; CHECK-RV32-NEXT: addi sp, s0, -2032 ; CHECK-RV32-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; CHECK-RV32-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; CHECK-RV32-NEXT: lw s1, 2020(sp) # 4-byte Folded Reload @@ -2560,10 +2551,7 @@ define void @relax_jal_spill_64_adjust_spill_slot() { ; CHECK-RV64-NEXT: #APP ; CHECK-RV64-NEXT: # reg use t6 ; CHECK-RV64-NEXT: #NO_APP -; CHECK-RV64-NEXT: lui a0, 2 -; CHECK-RV64-NEXT: sub sp, s0, a0 -; CHECK-RV64-NEXT: addiw a0, a0, -2032 -; CHECK-RV64-NEXT: add sp, sp, a0 +; CHECK-RV64-NEXT: addi sp, s0, -2032 ; CHECK-RV64-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; CHECK-RV64-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; CHECK-RV64-NEXT: ld s1, 2008(sp) # 8-byte Folded Reload diff --git a/llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir b/llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir index 08716be713b0f..a3a1818993f0b 100644 --- a/llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir +++ b/llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir @@ -41,10 +41,7 @@ ; CHECK-NEXT: sd a0, -8(a1) ; CHECK-NEXT: ld a1, 0(sp) ; CHECK-NEXT: call foo - ; CHECK-NEXT: lui a0, 2 - ; CHECK-NEXT: sub sp, s0, a0 - ; CHECK-NEXT: addiw a0, a0, -2032 - ; CHECK-NEXT: add sp, sp, a0 + ; CHECK-NEXT: addi sp, s0, -2032 ; CHECK-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; CHECK-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; CHECK-NEXT: addi sp, sp, 2032 diff --git a/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir b/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir index 5f0e1a9b9aa24..43fb0c10ca46f 100644 --- a/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir +++ b/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir @@ -46,9 +46,7 @@ body: | ; CHECK-NEXT: $x10 = ADDI killed $x10, -2048 ; CHECK-NEXT: $x10 = ADDI killed $x10, -224 ; CHECK-NEXT: VS1R_V killed renamable $v8, killed renamable $x10 - ; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2048 - ; CHECK-NEXT: $x2 = frame-destroy ADDI killed $x2, -224 - ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 240 + ; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2032 ; CHECK-NEXT: $x1 = LD $x2, 2024 :: (load (s64) from %stack.3) ; CHECK-NEXT: $x8 = LD $x2, 2016 :: (load (s64) from %stack.4) ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 2032 diff --git a/llvm/test/CodeGen/RISCV/rvv/callee-saved-regs.ll b/llvm/test/CodeGen/RISCV/rvv/callee-saved-regs.ll index c1ce2e988fc51..c0b10be847d1f 100644 --- a/llvm/test/CodeGen/RISCV/rvv/callee-saved-regs.ll +++ b/llvm/test/CodeGen/RISCV/rvv/callee-saved-regs.ll @@ -109,9 +109,7 @@ define riscv_vector_cc void @local_stack_allocation_frame_pointer() "frame-point ; SPILL-O2-NEXT: addi sp, sp, -480 ; SPILL-O2-NEXT: lbu a0, -1912(s0) ; SPILL-O2-NEXT: sb a0, -1912(s0) -; SPILL-O2-NEXT: addi sp, s0, -2048 -; SPILL-O2-NEXT: addi sp, sp, -464 -; SPILL-O2-NEXT: addi sp, sp, 480 +; SPILL-O2-NEXT: addi sp, s0, -2032 ; SPILL-O2-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; SPILL-O2-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; SPILL-O2-NEXT: addi sp, sp, 2032 diff --git a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir index c4bc794b8aeb3..1b9ce12af01f9 100644 --- a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir +++ b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir @@ -150,9 +150,7 @@ body: | ; CHECK-NEXT: PseudoBR %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: - ; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2048 - ; CHECK-NEXT: $x2 = frame-destroy ADDI killed $x2, -256 - ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 272 + ; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2032 ; CHECK-NEXT: $x1 = LD $x2, 2024 :: (load (s64) from %stack.3) ; CHECK-NEXT: $x8 = LD $x2, 2016 :: (load (s64) from %stack.4) ; CHECK-NEXT: $x18 = LD $x2, 2008 :: (load (s64) from %stack.5) diff --git a/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir b/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir index b4d8805b65bd8..22a7425bf98b8 100644 --- a/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir +++ b/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir @@ -33,9 +33,7 @@ ; CHECK-NEXT: vs1r.v v25, (a0) # Unknown-size Folded Spill ; CHECK-NEXT: ld a0, 8(sp) ; CHECK-NEXT: call spillslot - ; CHECK-NEXT: addi sp, s0, -2048 - ; CHECK-NEXT: addi sp, sp, -256 - ; CHECK-NEXT: addi sp, sp, 272 + ; CHECK-NEXT: addi sp, s0, -2032 ; CHECK-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; CHECK-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; CHECK-NEXT: addi sp, sp, 2032 diff --git a/llvm/test/CodeGen/RISCV/stack-realignment.ll b/llvm/test/CodeGen/RISCV/stack-realignment.ll index 034ebadc76af2..58876e4888a91 100644 --- a/llvm/test/CodeGen/RISCV/stack-realignment.ll +++ b/llvm/test/CodeGen/RISCV/stack-realignment.ll @@ -815,8 +815,7 @@ define void @caller1024() { ; RV32I-NEXT: andi sp, sp, -1024 ; RV32I-NEXT: addi a0, sp, 1024 ; RV32I-NEXT: call callee -; RV32I-NEXT: addi sp, s0, -2048 -; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: addi sp, s0, -2032 ; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; RV32I-NEXT: addi sp, sp, 2032 @@ -836,8 +835,7 @@ define void @caller1024() { ; RV32I-ILP32E-NEXT: andi sp, sp, -1024 ; RV32I-ILP32E-NEXT: addi a0, sp, 1024 ; RV32I-ILP32E-NEXT: call callee -; RV32I-ILP32E-NEXT: addi sp, s0, -2048 -; RV32I-ILP32E-NEXT: addi sp, sp, 4 +; RV32I-ILP32E-NEXT: addi sp, s0, -2044 ; RV32I-ILP32E-NEXT: lw ra, 2040(sp) # 4-byte Folded Reload ; RV32I-ILP32E-NEXT: lw s0, 2036(sp) # 4-byte Folded Reload ; RV32I-ILP32E-NEXT: addi sp, sp, 2044 @@ -857,8 +855,7 @@ define void @caller1024() { ; RV64I-NEXT: andi sp, sp, -1024 ; RV64I-NEXT: addi a0, sp, 1024 ; RV64I-NEXT: call callee -; RV64I-NEXT: addi sp, s0, -2048 -; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: addi sp, s0, -2032 ; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 2032 @@ -878,8 +875,7 @@ define void @caller1024() { ; RV64I-LP64E-NEXT: andi sp, sp, -1024 ; RV64I-LP64E-NEXT: addi a0, sp, 1024 ; RV64I-LP64E-NEXT: call callee -; RV64I-LP64E-NEXT: addi sp, s0, -2048 -; RV64I-LP64E-NEXT: addi sp, sp, 8 +; RV64I-LP64E-NEXT: addi sp, s0, -2040 ; RV64I-LP64E-NEXT: ld ra, 2032(sp) # 8-byte Folded Reload ; RV64I-LP64E-NEXT: ld s0, 2024(sp) # 8-byte Folded Reload ; RV64I-LP64E-NEXT: addi sp, sp, 2040 @@ -959,10 +955,7 @@ define void @caller2048() { ; RV32I-NEXT: addi a0, sp, 2047 ; RV32I-NEXT: addi a0, a0, 1 ; RV32I-NEXT: call callee -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: sub sp, s0, a0 -; RV32I-NEXT: addi sp, sp, 2032 -; RV32I-NEXT: addi sp, sp, 32 +; RV32I-NEXT: addi sp, s0, -2032 ; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; RV32I-NEXT: addi sp, sp, 2032 @@ -984,10 +977,7 @@ define void @caller2048() { ; RV32I-ILP32E-NEXT: addi a0, sp, 2047 ; RV32I-ILP32E-NEXT: addi a0, a0, 1 ; RV32I-ILP32E-NEXT: call callee -; RV32I-ILP32E-NEXT: lui a0, 1 -; RV32I-ILP32E-NEXT: sub sp, s0, a0 -; RV32I-ILP32E-NEXT: addi sp, sp, 2044 -; RV32I-ILP32E-NEXT: addi sp, sp, 8 +; RV32I-ILP32E-NEXT: addi sp, s0, -2044 ; RV32I-ILP32E-NEXT: lw ra, 2040(sp) # 4-byte Folded Reload ; RV32I-ILP32E-NEXT: lw s0, 2036(sp) # 4-byte Folded Reload ; RV32I-ILP32E-NEXT: addi sp, sp, 2044 @@ -1009,10 +999,7 @@ define void @caller2048() { ; RV64I-NEXT: addi a0, sp, 2047 ; RV64I-NEXT: addi a0, a0, 1 ; RV64I-NEXT: call callee -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: sub sp, s0, a0 -; RV64I-NEXT: addi sp, sp, 2032 -; RV64I-NEXT: addi sp, sp, 32 +; RV64I-NEXT: addi sp, s0, -2032 ; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 2032 @@ -1034,10 +1021,7 @@ define void @caller2048() { ; RV64I-LP64E-NEXT: addi a0, sp, 2047 ; RV64I-LP64E-NEXT: addi a0, a0, 1 ; RV64I-LP64E-NEXT: call callee -; RV64I-LP64E-NEXT: lui a0, 1 -; RV64I-LP64E-NEXT: sub sp, s0, a0 -; RV64I-LP64E-NEXT: addi sp, sp, 2040 -; RV64I-LP64E-NEXT: addi sp, sp, 16 +; RV64I-LP64E-NEXT: addi sp, s0, -2040 ; RV64I-LP64E-NEXT: ld ra, 2032(sp) # 8-byte Folded Reload ; RV64I-LP64E-NEXT: ld s0, 2024(sp) # 8-byte Folded Reload ; RV64I-LP64E-NEXT: addi sp, sp, 2040 @@ -1119,10 +1103,7 @@ define void @caller4096() { ; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: call callee -; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: sub sp, s0, a0 -; RV32I-NEXT: addi a0, a0, -2032 -; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: addi sp, s0, -2032 ; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; RV32I-NEXT: addi sp, sp, 2032 @@ -1146,10 +1127,7 @@ define void @caller4096() { ; RV32I-ILP32E-NEXT: lui a0, 1 ; RV32I-ILP32E-NEXT: add a0, sp, a0 ; RV32I-ILP32E-NEXT: call callee -; RV32I-ILP32E-NEXT: lui a0, 2 -; RV32I-ILP32E-NEXT: sub sp, s0, a0 -; RV32I-ILP32E-NEXT: addi a0, a0, -2044 -; RV32I-ILP32E-NEXT: add sp, sp, a0 +; RV32I-ILP32E-NEXT: addi sp, s0, -2044 ; RV32I-ILP32E-NEXT: lw ra, 2040(sp) # 4-byte Folded Reload ; RV32I-ILP32E-NEXT: lw s0, 2036(sp) # 4-byte Folded Reload ; RV32I-ILP32E-NEXT: addi sp, sp, 2044 @@ -1173,10 +1151,7 @@ define void @caller4096() { ; RV64I-NEXT: lui a0, 1 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: call callee -; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: sub sp, s0, a0 -; RV64I-NEXT: addiw a0, a0, -2032 -; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: addi sp, s0, -2032 ; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 2032 @@ -1200,10 +1175,7 @@ define void @caller4096() { ; RV64I-LP64E-NEXT: lui a0, 1 ; RV64I-LP64E-NEXT: add a0, sp, a0 ; RV64I-LP64E-NEXT: call callee -; RV64I-LP64E-NEXT: lui a0, 2 -; RV64I-LP64E-NEXT: sub sp, s0, a0 -; RV64I-LP64E-NEXT: addiw a0, a0, -2040 -; RV64I-LP64E-NEXT: add sp, sp, a0 +; RV64I-LP64E-NEXT: addi sp, s0, -2040 ; RV64I-LP64E-NEXT: ld ra, 2032(sp) # 8-byte Folded Reload ; RV64I-LP64E-NEXT: ld s0, 2024(sp) # 8-byte Folded Reload ; RV64I-LP64E-NEXT: addi sp, sp, 2040