[llvm] [llvm][RISCV] Use zilsd for callee-saved register spill/restore on RV32 (PR #184794)

Brandon Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 5 09:17:15 PST 2026


https://github.com/4vtomat updated https://github.com/llvm/llvm-project/pull/184794

>From cb0ec842052b165bc896c5b096327099b17db0c9 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 5 Mar 2026 05:22:35 -0800
Subject: [PATCH 1/3] [llvm][RISCV] Use zilsd for callee-saved register
 spill/restore on RV32

When the Zilsd extension is enabled on RV32, use SD_RV32/LD_RV32
instructions to spill and restore pairs of callee-saved GPRs instead of
saving 2 separate 32 bit data.
Note that we need to ensure stack slot to be aligned.
---
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp  | 100 ++-
 llvm/test/CodeGen/RISCV/callee-saved-gprs.ll  | 646 ++++++++++++++++++
 llvm/test/CodeGen/RISCV/double-mem.ll         |   6 +-
 .../RISCV/fold-addi-loadstore-zilsd.ll        |  16 +-
 llvm/test/CodeGen/RISCV/zdinx-spill.ll        | 114 ++--
 llvm/test/CodeGen/RISCV/zilsd-spill.ll        | 114 ++--
 6 files changed, 819 insertions(+), 177 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 92fd7283dc2cd..93a49ed8d23d4 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1092,10 +1092,22 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
 
   // Iterate over list of callee-saved registers and emit .cfi_offset
   // directives.
-  if (NeedsDwarfCFI)
-    for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
-      CFIBuilder.buildOffset(CS.getReg(),
-                             MFI.getObjectOffset(CS.getFrameIdx()));
+  if (NeedsDwarfCFI) {
+    for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI)) {
+      MCRegister Reg = CS.getReg();
+      int64_t Offset = MFI.getObjectOffset(CS.getFrameIdx());
+      // Emit CFI for both sub-registers. The even register is at the base
+      // offset and odd at base+4.
+      if (RISCV::GPRPairRegClass.contains(Reg)) {
+        MCRegister EvenReg = RI->getSubReg(Reg, RISCV::sub_gpr_even);
+        MCRegister OddReg = RI->getSubReg(Reg, RISCV::sub_gpr_odd);
+        CFIBuilder.buildOffset(EvenReg, Offset);
+        CFIBuilder.buildOffset(OddReg, Offset + 4);
+      } else {
+        CFIBuilder.buildOffset(Reg, Offset);
+      }
+    }
+  }
 
   // Generate new FP.
   if (hasFP(MF)) {
@@ -1347,9 +1359,20 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
   }
 
   // Recover callee-saved registers.
-  if (NeedsDwarfCFI)
-    for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
-      CFIBuilder.buildRestore(CS.getReg());
+  if (NeedsDwarfCFI) {
+    for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI)) {
+      MCRegister Reg = CS.getReg();
+      // Emit CFI for both sub-registers.
+      if (RISCV::GPRPairRegClass.contains(Reg)) {
+        MCRegister EvenReg = RI->getSubReg(Reg, RISCV::sub_gpr_even);
+        MCRegister OddReg = RI->getSubReg(Reg, RISCV::sub_gpr_odd);
+        CFIBuilder.buildRestore(EvenReg);
+        CFIBuilder.buildRestore(OddReg);
+      } else {
+        CFIBuilder.buildRestore(Reg);
+      }
+    }
+  }
 
   if (RVFI->isPushable(MF) && MBBI != MBB.end() && isPop(MBBI->getOpcode())) {
     // Use available stack adjustment in pop instruction to deallocate stack
@@ -1592,7 +1615,7 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
   // For example:
   // Original behavior: If v24 is marked, v24m2, v24m4, v24m8 are also marked.
   // Correct behavior: v24m2 is marked only if v24 and v25 are marked.
-  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
   const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
   const RISCVRegisterInfo &TRI = *STI.getRegisterInfo();
   for (unsigned i = 0; CSRegs[i]; ++i) {
@@ -1611,11 +1634,6 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
         SavedRegs.set(Reg);
     }
 
-    // Combine to super register if all of its subregisters are marked.
-    if (!SubRegs.empty() && llvm::all_of(SubRegs, [&](unsigned Reg) {
-          return SavedRegs.test(Reg);
-        }))
-      SavedRegs.set(CSReg);
   }
 
   // Unconditionally spill RA and FP only if the function uses a frame
@@ -1633,6 +1651,52 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
   if (RVFI->isPushable(MF) && SavedRegs.test(RISCV::X26))
     SavedRegs.set(RISCV::X27);
 
+  // For Zilsd on RV32, append GPRPair registers to the CSR list. This prevents
+  // the need to create register sets for each abi which is a lot more complex.
+  bool UseZilsd = !STI.is64Bit() && STI.hasStdExtZilsd();
+  if (UseZilsd) {
+    SmallVector<MCPhysReg, 32> NewCSRs;
+    SmallSet<MCPhysReg, 16> CSRSet;
+    for (unsigned i = 0; CSRegs[i]; ++i) {
+      NewCSRs.push_back(CSRegs[i]);
+      CSRSet.insert(CSRegs[i]);
+    }
+
+    // Append GPRPair registers for pairs where both sub-registers are in CSR
+    // list. Iterate through all GPRPairs and check if both sub-regs are CSRs.
+    for (MCPhysReg Pair : RISCV::GPRPairRegClass) {
+      MCPhysReg EvenReg = TRI.getSubReg(Pair, RISCV::sub_gpr_even);
+      MCPhysReg OddReg = TRI.getSubReg(Pair, RISCV::sub_gpr_odd);
+      if (CSRSet.contains(EvenReg) && CSRSet.contains(OddReg))
+        NewCSRs.push_back(Pair);
+    }
+
+    MRI.setCalleeSavedRegs(NewCSRs);
+    CSRegs = MRI.getCalleeSavedRegs();
+  }
+
+  // Check if all subregisters are marked for saving. If so, set the super
+  // register bit. For GPRPair, only check sub_gpr_even and sub_gpr_odd, not
+  // aliases like X8_W or X8_H which are not set in SavedRegs.
+  for (unsigned i = 0; CSRegs[i]; ++i) {
+    unsigned CSReg = CSRegs[i];
+    bool AllSubRegsSaved;
+    if (RISCV::GPRPairRegClass.contains(CSReg)) {
+      MCPhysReg EvenReg = TRI.getSubReg(CSReg, RISCV::sub_gpr_even);
+      MCPhysReg OddReg = TRI.getSubReg(CSReg, RISCV::sub_gpr_odd);
+      AllSubRegsSaved = SavedRegs.test(EvenReg) && SavedRegs.test(OddReg);
+    } else {
+      auto SubRegs = TRI.subregs(CSReg);
+      AllSubRegsSaved =
+          !SubRegs.empty() && llvm::all_of(SubRegs, [&](unsigned Reg) {
+            return SavedRegs.test(Reg);
+          });
+    }
+
+    if (AllSubRegsSaved)
+      SavedRegs.set(CSReg);
+  }
+
   // SiFive Preemptible Interrupt Handlers need additional frame entries
   createSiFivePreemptibleInterruptFrameEntries(MF, *RVFI);
 }
@@ -2085,6 +2149,16 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
       }
     }
 
+    // For GPRPair registers, use 8-byte slots with required alignment by zilsd.
+    if (!STI.is64Bit() && STI.hasStdExtZilsd() &&
+        RISCV::GPRPairRegClass.contains(Reg)) {
+      Align PairAlign = STI.getZilsdAlign();
+      int FrameIdx = MFI.CreateStackObject(8, PairAlign, true);
+      MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
+      CS.setFrameIdx(FrameIdx);
+      continue;
+    }
+
     // Not a fixed slot.
     Align Alignment = RegInfo->getSpillAlign(*RC);
     // We may not be able to satisfy the desired alignment specification of
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
index 8db4c715c41ce..c3209493255c3 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -31,6 +31,10 @@
 ; RUN: | FileCheck %s -check-prefixes=RV64IZCMP
 ; RUN: llc -mtriple=riscv64 -mattr=+zcmp -verify-machineinstrs \
 ; RUN:  -frame-pointer=all < %s | FileCheck %s -check-prefixes=RV64IZCMP-WITH-FP
+; RUN: llc -mtriple=riscv32 -mattr=+zilsd -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I-ZILSD
+; RUN: llc -mtriple=riscv32 -mattr=+zilsd -verify-machineinstrs -frame-pointer=all < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I-ZILSD-WITH-FP
 
 @var = global [32 x i32] zeroinitializer
 
@@ -1255,6 +1259,237 @@ define void @callee() {
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, 160
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV64IZCMP-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-LABEL: callee:
+; RV32I-ZILSD:       # %bb.0:
+; RV32I-ZILSD-NEXT:    addi sp, sp, -80
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 80
+; RV32I-ZILSD-NEXT:    sw ra, 76(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s0, 64(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s2, 56(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s4, 48(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s6, 40(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s8, 32(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s10, 24(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-NEXT:    .cfi_offset s0, -16
+; RV32I-ZILSD-NEXT:    .cfi_offset s1, -12
+; RV32I-ZILSD-NEXT:    .cfi_offset s2, -24
+; RV32I-ZILSD-NEXT:    .cfi_offset s3, -20
+; RV32I-ZILSD-NEXT:    .cfi_offset s4, -32
+; RV32I-ZILSD-NEXT:    .cfi_offset s5, -28
+; RV32I-ZILSD-NEXT:    .cfi_offset s6, -40
+; RV32I-ZILSD-NEXT:    .cfi_offset s7, -36
+; RV32I-ZILSD-NEXT:    .cfi_offset s8, -48
+; RV32I-ZILSD-NEXT:    .cfi_offset s9, -44
+; RV32I-ZILSD-NEXT:    .cfi_offset s10, -56
+; RV32I-ZILSD-NEXT:    .cfi_offset s11, -52
+; RV32I-ZILSD-NEXT:    lui a0, %hi(var)
+; RV32I-ZILSD-NEXT:    addi a0, a0, %lo(var)
+; RV32I-ZILSD-NEXT:    lw a1, 0(a0)
+; RV32I-ZILSD-NEXT:    lw a2, 4(a0)
+; RV32I-ZILSD-NEXT:    sw a2, 16(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a1, 20(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    lw a1, 8(a0)
+; RV32I-ZILSD-NEXT:    lw a2, 12(a0)
+; RV32I-ZILSD-NEXT:    sw a2, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a1, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    lw a1, 16(a0)
+; RV32I-ZILSD-NEXT:    lw a6, 20(a0)
+; RV32I-ZILSD-NEXT:    sw a1, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld t1, 24(a0)
+; RV32I-ZILSD-NEXT:    ld t3, 32(a0)
+; RV32I-ZILSD-NEXT:    ld t5, 40(a0)
+; RV32I-ZILSD-NEXT:    ld s0, 48(a0)
+; RV32I-ZILSD-NEXT:    ld s2, 56(a0)
+; RV32I-ZILSD-NEXT:    ld s4, 64(a0)
+; RV32I-ZILSD-NEXT:    ld s6, 72(a0)
+; RV32I-ZILSD-NEXT:    ld s8, 80(a0)
+; RV32I-ZILSD-NEXT:    ld s10, 88(a0)
+; RV32I-ZILSD-NEXT:    lw a1, 120(a0)
+; RV32I-ZILSD-NEXT:    lw t0, 124(a0)
+; RV32I-ZILSD-NEXT:    lw ra, 96(a0)
+; RV32I-ZILSD-NEXT:    lw a7, 100(a0)
+; RV32I-ZILSD-NEXT:    ld a2, 112(a0)
+; RV32I-ZILSD-NEXT:    ld a4, 104(a0)
+; RV32I-ZILSD-NEXT:    sw t0, 124(a0)
+; RV32I-ZILSD-NEXT:    sw a1, 120(a0)
+; RV32I-ZILSD-NEXT:    sw a3, 116(a0)
+; RV32I-ZILSD-NEXT:    sw a2, 112(a0)
+; RV32I-ZILSD-NEXT:    sw a5, 108(a0)
+; RV32I-ZILSD-NEXT:    sw a4, 104(a0)
+; RV32I-ZILSD-NEXT:    sw a7, 100(a0)
+; RV32I-ZILSD-NEXT:    sw ra, 96(a0)
+; RV32I-ZILSD-NEXT:    sw s11, 92(a0)
+; RV32I-ZILSD-NEXT:    sw s10, 88(a0)
+; RV32I-ZILSD-NEXT:    sw s9, 84(a0)
+; RV32I-ZILSD-NEXT:    sw s8, 80(a0)
+; RV32I-ZILSD-NEXT:    sw s7, 76(a0)
+; RV32I-ZILSD-NEXT:    sw s6, 72(a0)
+; RV32I-ZILSD-NEXT:    sw s5, 68(a0)
+; RV32I-ZILSD-NEXT:    sw s4, 64(a0)
+; RV32I-ZILSD-NEXT:    sw s3, 60(a0)
+; RV32I-ZILSD-NEXT:    sw s2, 56(a0)
+; RV32I-ZILSD-NEXT:    sw s1, 52(a0)
+; RV32I-ZILSD-NEXT:    sw s0, 48(a0)
+; RV32I-ZILSD-NEXT:    sw t6, 44(a0)
+; RV32I-ZILSD-NEXT:    sw t5, 40(a0)
+; RV32I-ZILSD-NEXT:    sw t4, 36(a0)
+; RV32I-ZILSD-NEXT:    sw t3, 32(a0)
+; RV32I-ZILSD-NEXT:    sw t2, 28(a0)
+; RV32I-ZILSD-NEXT:    sw t1, 24(a0)
+; RV32I-ZILSD-NEXT:    sw a6, 20(a0)
+; RV32I-ZILSD-NEXT:    lw a1, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a1, 16(a0)
+; RV32I-ZILSD-NEXT:    lw a1, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a1, 12(a0)
+; RV32I-ZILSD-NEXT:    lw a1, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a1, 8(a0)
+; RV32I-ZILSD-NEXT:    lw a1, 16(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a1, 4(a0)
+; RV32I-ZILSD-NEXT:    lw a1, 20(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a1, 0(a0)
+; RV32I-ZILSD-NEXT:    lw ra, 76(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s0, 64(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s2, 56(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s4, 48(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s6, 40(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s8, 32(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s10, 24(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-NEXT:    .cfi_restore s2
+; RV32I-ZILSD-NEXT:    .cfi_restore s3
+; RV32I-ZILSD-NEXT:    .cfi_restore s4
+; RV32I-ZILSD-NEXT:    .cfi_restore s5
+; RV32I-ZILSD-NEXT:    .cfi_restore s6
+; RV32I-ZILSD-NEXT:    .cfi_restore s7
+; RV32I-ZILSD-NEXT:    .cfi_restore s8
+; RV32I-ZILSD-NEXT:    .cfi_restore s9
+; RV32I-ZILSD-NEXT:    .cfi_restore s10
+; RV32I-ZILSD-NEXT:    .cfi_restore s11
+; RV32I-ZILSD-NEXT:    addi sp, sp, 80
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-NEXT:    ret
+;
+; RV32I-ZILSD-WITH-FP-LABEL: callee:
+; RV32I-ZILSD-WITH-FP:       # %bb.0:
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -80
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 80
+; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 76(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s0, 64(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s2, 56(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s4, 48(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s6, 40(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s8, 32(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s10, 24(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s1, -12
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s2, -24
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s3, -20
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s4, -32
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s5, -28
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s6, -40
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s7, -36
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s8, -48
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s9, -44
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s10, -56
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s11, -52
+; RV32I-ZILSD-WITH-FP-NEXT:    addi s0, sp, 80
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
+; RV32I-ZILSD-WITH-FP-NEXT:    lui a0, %hi(var)
+; RV32I-ZILSD-WITH-FP-NEXT:    addi a0, a0, %lo(var)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, 0(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a2, 4(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a2, -64(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -60(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, 8(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a2, 12(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a2, -72(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -68(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, 16(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a2, 20(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a2, -80(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -76(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld t1, 24(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld t3, 32(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld t5, 40(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s2, 48(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s4, 56(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s6, 64(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s8, 72(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s10, 80(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, 88(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw t0, 92(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s1, 120(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 124(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a6, 96(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a2, 112(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a4, 104(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 124(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s1, 120(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a3, 116(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a2, 112(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a5, 108(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a4, 104(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a7, 100(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a6, 96(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t0, 92(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 88(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s11, 84(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s10, 80(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s9, 76(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s8, 72(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s7, 68(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s6, 64(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s5, 60(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s4, 56(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s3, 52(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s2, 48(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t6, 44(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t5, 40(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t4, 36(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t3, 32(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t2, 28(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw t1, 24(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, -80(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 20(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, -76(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 16(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, -72(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 12(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, -68(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 8(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, -64(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 4(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a1, -60(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 0(a0)
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 80
+; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 76(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s0, 64(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s2, 56(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s4, 48(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s6, 40(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s8, 32(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s10, 24(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s2
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s3
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s4
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s5
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s6
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s7
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s8
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s9
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s10
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s11
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 80
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-WITH-FP-NEXT:    ret
   %val = load [32 x i32], ptr @var
   store volatile [32 x i32] %val, ptr @var
   ret void
@@ -2859,6 +3094,294 @@ define void @caller() {
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, 288
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV64IZCMP-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-LABEL: caller:
+; RV32I-ZILSD:       # %bb.0:
+; RV32I-ZILSD-NEXT:    addi sp, sp, -144
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 144
+; RV32I-ZILSD-NEXT:    sw ra, 140(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s0, 128(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s2, 120(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s4, 112(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s6, 104(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s8, 96(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sd s10, 88(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-NEXT:    .cfi_offset s0, -16
+; RV32I-ZILSD-NEXT:    .cfi_offset s1, -12
+; RV32I-ZILSD-NEXT:    .cfi_offset s2, -24
+; RV32I-ZILSD-NEXT:    .cfi_offset s3, -20
+; RV32I-ZILSD-NEXT:    .cfi_offset s4, -32
+; RV32I-ZILSD-NEXT:    .cfi_offset s5, -28
+; RV32I-ZILSD-NEXT:    .cfi_offset s6, -40
+; RV32I-ZILSD-NEXT:    .cfi_offset s7, -36
+; RV32I-ZILSD-NEXT:    .cfi_offset s8, -48
+; RV32I-ZILSD-NEXT:    .cfi_offset s9, -44
+; RV32I-ZILSD-NEXT:    .cfi_offset s10, -56
+; RV32I-ZILSD-NEXT:    .cfi_offset s11, -52
+; RV32I-ZILSD-NEXT:    lui s0, %hi(var)
+; RV32I-ZILSD-NEXT:    addi s0, s0, %lo(var)
+; RV32I-ZILSD-NEXT:    ld a0, 0(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 80(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 84(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 8(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 72(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 76(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 16(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 64(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 68(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 24(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 56(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 60(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 32(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 48(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 52(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 40(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 40(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 44(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 48(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 32(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 36(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 56(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 24(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 28(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 64(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 16(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 20(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld a0, 72(s0)
+; RV32I-ZILSD-NEXT:    sw a1, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    sw a0, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    lw a0, 80(s0)
+; RV32I-ZILSD-NEXT:    lw s1, 84(s0)
+; RV32I-ZILSD-NEXT:    sw a0, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    ld s10, 88(s0)
+; RV32I-ZILSD-NEXT:    ld s8, 96(s0)
+; RV32I-ZILSD-NEXT:    ld s6, 104(s0)
+; RV32I-ZILSD-NEXT:    ld s4, 112(s0)
+; RV32I-ZILSD-NEXT:    ld s2, 120(s0)
+; RV32I-ZILSD-NEXT:    call callee
+; RV32I-ZILSD-NEXT:    sw s3, 124(s0)
+; RV32I-ZILSD-NEXT:    sw s2, 120(s0)
+; RV32I-ZILSD-NEXT:    sw s5, 116(s0)
+; RV32I-ZILSD-NEXT:    sw s4, 112(s0)
+; RV32I-ZILSD-NEXT:    sw s7, 108(s0)
+; RV32I-ZILSD-NEXT:    sw s6, 104(s0)
+; RV32I-ZILSD-NEXT:    sw s9, 100(s0)
+; RV32I-ZILSD-NEXT:    sw s8, 96(s0)
+; RV32I-ZILSD-NEXT:    sw s11, 92(s0)
+; RV32I-ZILSD-NEXT:    sw s10, 88(s0)
+; RV32I-ZILSD-NEXT:    sw s1, 84(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 80(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 76(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 72(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 16(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 68(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 20(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 64(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 24(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 60(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 28(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 56(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 32(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 52(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 36(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 48(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 40(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 44(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 44(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 40(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 48(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 36(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 52(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 32(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 56(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 28(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 60(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 24(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 64(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 20(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 68(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 16(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 72(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 12(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 76(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 8(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 80(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 4(s0)
+; RV32I-ZILSD-NEXT:    lw a0, 84(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    sw a0, 0(s0)
+; RV32I-ZILSD-NEXT:    lw ra, 140(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s0, 128(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s2, 120(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s4, 112(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s6, 104(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s8, 96(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    ld s10, 88(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-NEXT:    .cfi_restore s2
+; RV32I-ZILSD-NEXT:    .cfi_restore s3
+; RV32I-ZILSD-NEXT:    .cfi_restore s4
+; RV32I-ZILSD-NEXT:    .cfi_restore s5
+; RV32I-ZILSD-NEXT:    .cfi_restore s6
+; RV32I-ZILSD-NEXT:    .cfi_restore s7
+; RV32I-ZILSD-NEXT:    .cfi_restore s8
+; RV32I-ZILSD-NEXT:    .cfi_restore s9
+; RV32I-ZILSD-NEXT:    .cfi_restore s10
+; RV32I-ZILSD-NEXT:    .cfi_restore s11
+; RV32I-ZILSD-NEXT:    addi sp, sp, 144
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-NEXT:    ret
+;
+; RV32I-ZILSD-WITH-FP-LABEL: caller:
+; RV32I-ZILSD-WITH-FP:       # %bb.0:
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -144
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 144
+; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 140(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s0, 128(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s2, 120(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s4, 112(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s6, 104(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s8, 96(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sd s10, 88(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s1, -12
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s2, -24
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s3, -20
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s4, -32
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s5, -28
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s6, -40
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s7, -36
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s8, -48
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s9, -44
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s10, -56
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s11, -52
+; RV32I-ZILSD-WITH-FP-NEXT:    addi s0, sp, 144
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
+; RV32I-ZILSD-WITH-FP-NEXT:    lui s1, %hi(var)
+; RV32I-ZILSD-WITH-FP-NEXT:    addi s1, s1, %lo(var)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 0(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -64(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -60(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 8(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -72(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -68(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 16(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -80(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -76(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 24(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -88(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -84(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 32(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -96(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -92(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 40(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -104(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -100(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 48(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -112(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -108(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 56(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -120(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -116(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 64(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -128(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -124(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 72(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -136(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -132(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld a0, 80(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, -144(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, -140(s0) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s10, 88(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s8, 96(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s6, 104(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s4, 112(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s2, 120(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    call callee
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s3, 124(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s2, 120(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s5, 116(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s4, 112(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s7, 108(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s6, 104(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s9, 100(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s8, 96(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s11, 92(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s10, 88(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -144(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 84(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -140(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 80(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -136(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 76(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -132(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 72(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -128(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 68(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -124(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 64(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -120(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 60(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -116(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 56(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -112(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 52(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -108(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 48(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -104(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 44(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -100(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 40(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -96(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 36(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -92(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 32(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -88(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 28(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -84(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 24(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -80(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 20(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -76(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 16(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -72(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 12(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -68(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 8(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -64(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 4(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    lw a0, -60(s0) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 0(s1)
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 144
+; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 140(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s0, 128(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s2, 120(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s4, 112(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s6, 104(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s8, 96(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    ld s10, 88(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s2
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s3
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s4
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s5
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s6
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s7
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s8
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s9
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s10
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s11
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 144
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-WITH-FP-NEXT:    ret
   %val = load [32 x i32], ptr @var
   call void @callee()
   store volatile [32 x i32] %val, ptr @var
@@ -3035,6 +3558,47 @@ define void @foo() {
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, 32
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV64IZCMP-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-LABEL: foo:
+; RV32I-ZILSD:       # %bb.0: # %entry
+; RV32I-ZILSD-NEXT:    addi sp, sp, -16
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-ZILSD-NEXT:    sw s4, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    .cfi_offset s4, -4
+; RV32I-ZILSD-NEXT:    #APP
+; RV32I-ZILSD-NEXT:    li s4, 0
+; RV32I-ZILSD-NEXT:    #NO_APP
+; RV32I-ZILSD-NEXT:    lw s4, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    .cfi_restore s4
+; RV32I-ZILSD-NEXT:    addi sp, sp, 16
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-NEXT:    ret
+;
+; RV32I-ZILSD-WITH-FP-LABEL: foo:
+; RV32I-ZILSD-WITH-FP:       # %bb.0: # %entry
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s4, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -8
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s4, -12
+; RV32I-ZILSD-WITH-FP-NEXT:    addi s0, sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
+; RV32I-ZILSD-WITH-FP-NEXT:    #APP
+; RV32I-ZILSD-WITH-FP-NEXT:    li s4, 0
+; RV32I-ZILSD-WITH-FP-NEXT:    #NO_APP
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s4, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s4
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-WITH-FP-NEXT:    ret
 entry:
   tail call void asm sideeffect "li s4, 0", "~{s4}"()
   ret void
@@ -3209,6 +3773,47 @@ define void @bar() {
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, 32
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV64IZCMP-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-LABEL: bar:
+; RV32I-ZILSD:       # %bb.0: # %entry
+; RV32I-ZILSD-NEXT:    addi sp, sp, -16
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-ZILSD-NEXT:    sw s11, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    .cfi_offset s11, -4
+; RV32I-ZILSD-NEXT:    #APP
+; RV32I-ZILSD-NEXT:    li s11, 0
+; RV32I-ZILSD-NEXT:    #NO_APP
+; RV32I-ZILSD-NEXT:    lw s11, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    .cfi_restore s11
+; RV32I-ZILSD-NEXT:    addi sp, sp, 16
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-NEXT:    ret
+;
+; RV32I-ZILSD-WITH-FP-LABEL: bar:
+; RV32I-ZILSD-WITH-FP:       # %bb.0: # %entry
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s11, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -8
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s11, -12
+; RV32I-ZILSD-WITH-FP-NEXT:    addi s0, sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
+; RV32I-ZILSD-WITH-FP-NEXT:    #APP
+; RV32I-ZILSD-WITH-FP-NEXT:    li s11, 0
+; RV32I-ZILSD-WITH-FP-NEXT:    #NO_APP
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s11, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s11
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-WITH-FP-NEXT:    ret
 entry:
   tail call void asm sideeffect "li s11, 0", "~{s11}"()
   ret void
@@ -3448,6 +4053,47 @@ define void @varargs(...) {
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, 80
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV64IZCMP-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-LABEL: varargs:
+; RV32I-ZILSD:       # %bb.0:
+; RV32I-ZILSD-NEXT:    addi sp, sp, -48
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 48
+; RV32I-ZILSD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-NEXT:    .cfi_offset ra, -36
+; RV32I-ZILSD-NEXT:    sd a6, 40(sp)
+; RV32I-ZILSD-NEXT:    sd a4, 32(sp)
+; RV32I-ZILSD-NEXT:    sd a2, 24(sp)
+; RV32I-ZILSD-NEXT:    sd a0, 16(sp)
+; RV32I-ZILSD-NEXT:    call callee
+; RV32I-ZILSD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-NEXT:    addi sp, sp, 48
+; RV32I-ZILSD-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-NEXT:    ret
+;
+; RV32I-ZILSD-WITH-FP-LABEL: varargs:
+; RV32I-ZILSD-WITH-FP:       # %bb.0:
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -48
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 48
+; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -36
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -40
+; RV32I-ZILSD-WITH-FP-NEXT:    addi s0, sp, 16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa s0, 32
+; RV32I-ZILSD-WITH-FP-NEXT:    sd a6, 24(s0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sd a4, 16(s0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sd a2, 8(s0)
+; RV32I-ZILSD-WITH-FP-NEXT:    sd a0, 0(s0)
+; RV32I-ZILSD-WITH-FP-NEXT:    call callee
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 48
+; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 48
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-WITH-FP-NEXT:    ret
   call void @callee()
   ret void
 }
diff --git a/llvm/test/CodeGen/RISCV/double-mem.ll b/llvm/test/CodeGen/RISCV/double-mem.ll
index 053688f79fe1c..ee11ca8c115f7 100644
--- a/llvm/test/CodeGen/RISCV/double-mem.ll
+++ b/llvm/test/CodeGen/RISCV/double-mem.ll
@@ -281,8 +281,7 @@ define dso_local double @fld_stack(double %a) nounwind {
 ; RV32IZFINXZDINXZILSD:       # %bb.0:
 ; RV32IZFINXZDINXZILSD-NEXT:    addi sp, sp, -32
 ; RV32IZFINXZDINXZILSD-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
-; RV32IZFINXZDINXZILSD-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
-; RV32IZFINXZDINXZILSD-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINXZILSD-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
 ; RV32IZFINXZDINXZILSD-NEXT:    mv s1, a1
 ; RV32IZFINXZDINXZILSD-NEXT:    mv s0, a0
 ; RV32IZFINXZDINXZILSD-NEXT:    addi a0, sp, 8
@@ -290,8 +289,7 @@ define dso_local double @fld_stack(double %a) nounwind {
 ; RV32IZFINXZDINXZILSD-NEXT:    ld a0, 8(sp)
 ; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a0, a0, s0
 ; RV32IZFINXZDINXZILSD-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
-; RV32IZFINXZDINXZILSD-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
-; RV32IZFINXZDINXZILSD-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINXZILSD-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
 ; RV32IZFINXZDINXZILSD-NEXT:    addi sp, sp, 32
 ; RV32IZFINXZDINXZILSD-NEXT:    ret
   %1 = alloca double, align 8
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll
index d1cf8a13a9a88..7ad24b1be9fbc 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll
@@ -35,11 +35,9 @@ define double @fold_addi_from_different_bb(i32 %k, i32 %n, ptr %a) nounwind {
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    addi sp, sp, -32
 ; CHECK-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
-; CHECK-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
-; CHECK-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
-; CHECK-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
-; CHECK-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
-; CHECK-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
+; CHECK-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
+; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT:    sd s2, 8(sp) # 8-byte Folded Spill
 ; CHECK-NEXT:    blez a1, .LBB2_3
 ; CHECK-NEXT:  # %bb.1: # %for.body.lr.ph
 ; CHECK-NEXT:    mv s2, a2
@@ -61,11 +59,9 @@ define double @fold_addi_from_different_bb(i32 %k, i32 %n, ptr %a) nounwind {
 ; CHECK-NEXT:  .LBB2_4: # %for.cond.cleanup
 ; CHECK-NEXT:    fmv.d a0, s0
 ; CHECK-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
-; CHECK-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
-; CHECK-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
-; CHECK-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
-; CHECK-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
-; CHECK-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
+; CHECK-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
+; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
+; CHECK-NEXT:    ld s2, 8(sp) # 8-byte Folded Reload
 ; CHECK-NEXT:    addi sp, sp, 32
 ; CHECK-NEXT:    ret
 entry:
diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
index fc1199cd239f2..0a0c30157ecfc 100644
--- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll
@@ -45,109 +45,73 @@ define double @foo(double %x) nounwind {
   ;
   ; ZDINX-ZILSD-LABEL: name: foo
   ; ZDINX-ZILSD: bb.0 (%ir-block.0):
-  ; ZDINX-ZILSD-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-ZILSD-NEXT:   liveins: $x10, $x11, $x8_x9, $x18_x19, $x20_x21, $x22_x23, $x24_x25, $x26_x27
   ; ZDINX-ZILSD-NEXT: {{  $}}
   ; ZDINX-ZILSD-NEXT:   $x2 = frame-setup ADDI $x2, -64
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
-  ; ZDINX-ZILSD-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SD_RV32 killed $x8_x9, $x2, 56 :: (store (s64) into %stack.1)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SD_RV32 killed $x18_x19, $x2, 48 :: (store (s64) into %stack.2)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SD_RV32 killed $x20_x21, $x2, 40 :: (store (s64) into %stack.3)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SD_RV32 killed $x22_x23, $x2, 32 :: (store (s64) into %stack.4)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SD_RV32 killed $x24_x25, $x2, 24 :: (store (s64) into %stack.5)
+  ; ZDINX-ZILSD-NEXT:   frame-setup SD_RV32 killed $x26_x27, $x2, 16 :: (store (s64) into %stack.6)
   ; ZDINX-ZILSD-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
   ; ZDINX-ZILSD-NEXT:   PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
   ; ZDINX-ZILSD-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $x6, 12 /* clobber */, implicit-def dead early-clobber $x7, 12 /* clobber */, implicit-def dead early-clobber $x8, 12 /* clobber */, implicit-def dead early-clobber $x9, 12 /* clobber */, implicit-def dead early-clobber $x10, 12 /* clobber */, implicit-def dead early-clobber $x11, 12 /* clobber */, implicit-def dead early-clobber $x12, 12 /* clobber */, implicit-def dead early-clobber $x13, 12 /* clobber */, implicit-def dead early-clobber $x14, 12 /* clobber */, implicit-def dead early-clobber $x15, 12 /* clobber */, implicit-def dead early-clobber $x16, 12 /* clobber */, implicit-def dead early-clobber $x17, 12 /* clobber */, implicit-def dead early-clobber $x18, 12 /* clobber */, implicit-def dead early-clobber $x19, 12 /* clobber */, implicit-def dead early-clobber $x20, 12 /* clobber */, implicit-def dead early-clobber $x21, 12 /* clobber */, implicit-def dead early-clobber $x22, 12 /* clobber */, implicit-def dead early-clobber $x23, 12 /* clobber */, implicit-def dead early-clobber $x24, 12 /* clobber */, implicit-def dead early-clobber $x25, 12 /* clobber */, implicit-def dead early-clobber $x26, 12 /* clobber */, implicit-def dead early-clobber $x27, 12 /* clobber */, implicit-def dead early-clobber $x28, 12 /* clobber */, implicit-def dead early-clobber $x29, 12 /* clobber */, implicit-def dead early-clobber $x31
   ; ZDINX-ZILSD-NEXT:   renamable $x10_x11 = PseudoRV32ZdinxLD $x2, 8 :: (load (s64) from %stack.0, align 4)
-  ; ZDINX-ZILSD-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
-  ; ZDINX-ZILSD-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
-  ; ZDINX-ZILSD-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
-  ; ZDINX-ZILSD-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
-  ; ZDINX-ZILSD-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
-  ; ZDINX-ZILSD-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
-  ; ZDINX-ZILSD-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
-  ; ZDINX-ZILSD-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
-  ; ZDINX-ZILSD-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
-  ; ZDINX-ZILSD-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
-  ; ZDINX-ZILSD-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
-  ; ZDINX-ZILSD-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-ZILSD-NEXT:   $x8_x9 = frame-destroy LD_RV32 $x2, 56 :: (load (s64) from %stack.1)
+  ; ZDINX-ZILSD-NEXT:   $x18_x19 = frame-destroy LD_RV32 $x2, 48 :: (load (s64) from %stack.2)
+  ; ZDINX-ZILSD-NEXT:   $x20_x21 = frame-destroy LD_RV32 $x2, 40 :: (load (s64) from %stack.3)
+  ; ZDINX-ZILSD-NEXT:   $x22_x23 = frame-destroy LD_RV32 $x2, 32 :: (load (s64) from %stack.4)
+  ; ZDINX-ZILSD-NEXT:   $x24_x25 = frame-destroy LD_RV32 $x2, 24 :: (load (s64) from %stack.5)
+  ; ZDINX-ZILSD-NEXT:   $x26_x27 = frame-destroy LD_RV32 $x2, 16 :: (load (s64) from %stack.6)
   ; ZDINX-ZILSD-NEXT:   $x2 = frame-destroy ADDI $x2, 64
   ; ZDINX-ZILSD-NEXT:   PseudoRET implicit $x10, implicit $x11
   ;
   ; ZDINX-ZILSD-UNALIGNED-LABEL: name: foo
   ; ZDINX-ZILSD-UNALIGNED: bb.0 (%ir-block.0):
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   liveins: $x10, $x11, $x8_x9, $x18_x19, $x20_x21, $x22_x23, $x24_x25, $x26_x27
   ; ZDINX-ZILSD-UNALIGNED-NEXT: {{  $}}
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x2 = frame-setup ADDI $x2, -64
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x8_x9, $x2, 56 :: (store (s64) into %stack.1, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x18_x19, $x2, 48 :: (store (s64) into %stack.2, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x20_x21, $x2, 40 :: (store (s64) into %stack.3, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x22_x23, $x2, 32 :: (store (s64) into %stack.4, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x24_x25, $x2, 24 :: (store (s64) into %stack.5, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x26_x27, $x2, 16 :: (store (s64) into %stack.6, align 1)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $x6, 12 /* clobber */, implicit-def dead early-clobber $x7, 12 /* clobber */, implicit-def dead early-clobber $x8, 12 /* clobber */, implicit-def dead early-clobber $x9, 12 /* clobber */, implicit-def dead early-clobber $x10, 12 /* clobber */, implicit-def dead early-clobber $x11, 12 /* clobber */, implicit-def dead early-clobber $x12, 12 /* clobber */, implicit-def dead early-clobber $x13, 12 /* clobber */, implicit-def dead early-clobber $x14, 12 /* clobber */, implicit-def dead early-clobber $x15, 12 /* clobber */, implicit-def dead early-clobber $x16, 12 /* clobber */, implicit-def dead early-clobber $x17, 12 /* clobber */, implicit-def dead early-clobber $x18, 12 /* clobber */, implicit-def dead early-clobber $x19, 12 /* clobber */, implicit-def dead early-clobber $x20, 12 /* clobber */, implicit-def dead early-clobber $x21, 12 /* clobber */, implicit-def dead early-clobber $x22, 12 /* clobber */, implicit-def dead early-clobber $x23, 12 /* clobber */, implicit-def dead early-clobber $x24, 12 /* clobber */, implicit-def dead early-clobber $x25, 12 /* clobber */, implicit-def dead early-clobber $x26, 12 /* clobber */, implicit-def dead early-clobber $x27, 12 /* clobber */, implicit-def dead early-clobber $x28, 12 /* clobber */, implicit-def dead early-clobber $x29, 12 /* clobber */, implicit-def dead early-clobber $x31
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 8 :: (load (s64) from %stack.0, align 4)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
-  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x8_x9 = frame-destroy LD_RV32 $x2, 56 :: (load (s64) from %stack.1, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x18_x19 = frame-destroy LD_RV32 $x2, 48 :: (load (s64) from %stack.2, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x20_x21 = frame-destroy LD_RV32 $x2, 40 :: (load (s64) from %stack.3, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x22_x23 = frame-destroy LD_RV32 $x2, 32 :: (load (s64) from %stack.4, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x24_x25 = frame-destroy LD_RV32 $x2, 24 :: (load (s64) from %stack.5, align 1)
+  ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x26_x27 = frame-destroy LD_RV32 $x2, 16 :: (load (s64) from %stack.6, align 1)
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   $x2 = frame-destroy ADDI $x2, 64
   ; ZDINX-ZILSD-UNALIGNED-NEXT:   PseudoRET implicit $x10, implicit $x11
   ;
   ; ZDINX-ZILSD-4BYTEALIGN-LABEL: name: foo
   ; ZDINX-ZILSD-4BYTEALIGN: bb.0 (%ir-block.0):
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x8_x9, $x18_x19, $x20_x21, $x22_x23, $x24_x25, $x26_x27
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT: {{  $}}
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-setup ADDI $x2, -64
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x19, $x2, 48 :: (store (s32) into %stack.4)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x20, $x2, 44 :: (store (s32) into %stack.5)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x21, $x2, 40 :: (store (s32) into %stack.6)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x22, $x2, 36 :: (store (s32) into %stack.7)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x23, $x2, 32 :: (store (s32) into %stack.8)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x24, $x2, 28 :: (store (s32) into %stack.9)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x8_x9, $x2, 56 :: (store (s64) into %stack.1, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x18_x19, $x2, 48 :: (store (s64) into %stack.2, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x20_x21, $x2, 40 :: (store (s64) into %stack.3, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x22_x23, $x2, 32 :: (store (s64) into %stack.4, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x24_x25, $x2, 24 :: (store (s64) into %stack.5, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x26_x27, $x2, 16 :: (store (s64) into %stack.6, align 4)
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   SD_RV32 killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4)
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $x6, 12 /* clobber */, implicit-def dead early-clobber $x7, 12 /* clobber */, implicit-def dead early-clobber $x8, 12 /* clobber */, implicit-def dead early-clobber $x9, 12 /* clobber */, implicit-def dead early-clobber $x10, 12 /* clobber */, implicit-def dead early-clobber $x11, 12 /* clobber */, implicit-def dead early-clobber $x12, 12 /* clobber */, implicit-def dead early-clobber $x13, 12 /* clobber */, implicit-def dead early-clobber $x14, 12 /* clobber */, implicit-def dead early-clobber $x15, 12 /* clobber */, implicit-def dead early-clobber $x16, 12 /* clobber */, implicit-def dead early-clobber $x17, 12 /* clobber */, implicit-def dead early-clobber $x18, 12 /* clobber */, implicit-def dead early-clobber $x19, 12 /* clobber */, implicit-def dead early-clobber $x20, 12 /* clobber */, implicit-def dead early-clobber $x21, 12 /* clobber */, implicit-def dead early-clobber $x22, 12 /* clobber */, implicit-def dead early-clobber $x23, 12 /* clobber */, implicit-def dead early-clobber $x24, 12 /* clobber */, implicit-def dead early-clobber $x25, 12 /* clobber */, implicit-def dead early-clobber $x26, 12 /* clobber */, implicit-def dead early-clobber $x27, 12 /* clobber */, implicit-def dead early-clobber $x28, 12 /* clobber */, implicit-def dead early-clobber $x29, 12 /* clobber */, implicit-def dead early-clobber $x31
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   renamable $x10_x11 = LD_RV32 $x2, 8 :: (load (s64) from %stack.0, align 4)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x8 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.1)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x9 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.2)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x18 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.3)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x19 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.4)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x20 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.5)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x21 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.6)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x22 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.7)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x23 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.8)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x24 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.9)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11)
-  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x8_x9 = frame-destroy LD_RV32 $x2, 56 :: (load (s64) from %stack.1, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x18_x19 = frame-destroy LD_RV32 $x2, 48 :: (load (s64) from %stack.2, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x20_x21 = frame-destroy LD_RV32 $x2, 40 :: (load (s64) from %stack.3, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x22_x23 = frame-destroy LD_RV32 $x2, 32 :: (load (s64) from %stack.4, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x24_x25 = frame-destroy LD_RV32 $x2, 24 :: (load (s64) from %stack.5, align 4)
+  ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x26_x27 = frame-destroy LD_RV32 $x2, 16 :: (load (s64) from %stack.6, align 4)
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-destroy ADDI $x2, 64
   ; ZDINX-ZILSD-4BYTEALIGN-NEXT:   PseudoRET implicit $x10, implicit $x11
   %a = fadd double %x, %x
diff --git a/llvm/test/CodeGen/RISCV/zilsd-spill.ll b/llvm/test/CodeGen/RISCV/zilsd-spill.ll
index e937925dc7591..41eccedd287a7 100644
--- a/llvm/test/CodeGen/RISCV/zilsd-spill.ll
+++ b/llvm/test/CodeGen/RISCV/zilsd-spill.ll
@@ -62,22 +62,16 @@ define i64 @cmpxchg_i64_monotonic_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwi
   ;
   ; RV32I-ZILSD-LABEL: name: cmpxchg_i64_monotonic_monotonic
   ; RV32I-ZILSD: bb.0 (%ir-block.0):
-  ; RV32I-ZILSD-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-ZILSD-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8_x9, $x18_x19, $x20_x21, $x22_x23, $x24_x25, $x26_x27
   ; RV32I-ZILSD-NEXT: {{  $}}
   ; RV32I-ZILSD-NEXT:   $x2 = frame-setup ADDI $x2, -80
   ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x1, $x2, 76 :: (store (s32) into %stack.2)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x8, $x2, 72 :: (store (s32) into %stack.3)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x9, $x2, 68 :: (store (s32) into %stack.4)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x18, $x2, 64 :: (store (s32) into %stack.5)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x19, $x2, 60 :: (store (s32) into %stack.6)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x20, $x2, 56 :: (store (s32) into %stack.7)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x21, $x2, 52 :: (store (s32) into %stack.8)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x22, $x2, 48 :: (store (s32) into %stack.9)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x23, $x2, 44 :: (store (s32) into %stack.10)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x24, $x2, 40 :: (store (s32) into %stack.11)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x25, $x2, 36 :: (store (s32) into %stack.12)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x26, $x2, 32 :: (store (s32) into %stack.13)
-  ; RV32I-ZILSD-NEXT:   frame-setup SW killed $x27, $x2, 28 :: (store (s32) into %stack.14)
+  ; RV32I-ZILSD-NEXT:   frame-setup SD_RV32 killed $x8_x9, $x2, 64 :: (store (s64) into %stack.3)
+  ; RV32I-ZILSD-NEXT:   frame-setup SD_RV32 killed $x18_x19, $x2, 56 :: (store (s64) into %stack.4)
+  ; RV32I-ZILSD-NEXT:   frame-setup SD_RV32 killed $x20_x21, $x2, 48 :: (store (s64) into %stack.5)
+  ; RV32I-ZILSD-NEXT:   frame-setup SD_RV32 killed $x22_x23, $x2, 40 :: (store (s64) into %stack.6)
+  ; RV32I-ZILSD-NEXT:   frame-setup SD_RV32 killed $x24_x25, $x2, 32 :: (store (s64) into %stack.7)
+  ; RV32I-ZILSD-NEXT:   frame-setup SD_RV32 killed $x26_x27, $x2, 24 :: (store (s64) into %stack.8)
   ; RV32I-ZILSD-NEXT:   renamable $x17 = COPY $x12
   ; RV32I-ZILSD-NEXT:   renamable $x16 = COPY $x11
   ; RV32I-ZILSD-NEXT:   SD_RV32 killed renamable $x16_x17, $x2, 16 :: (store (s64) into %ir.1)
@@ -96,39 +90,27 @@ define i64 @cmpxchg_i64_monotonic_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwi
   ; RV32I-ZILSD-NEXT:   renamable $x12 = ADD killed renamable $x13, renamable $x13
   ; RV32I-ZILSD-NEXT:   renamable $x11 = ADD killed renamable $x12, killed renamable $x11
   ; RV32I-ZILSD-NEXT:   $x1 = frame-destroy LW $x2, 76 :: (load (s32) from %stack.2)
-  ; RV32I-ZILSD-NEXT:   $x8 = frame-destroy LW $x2, 72 :: (load (s32) from %stack.3)
-  ; RV32I-ZILSD-NEXT:   $x9 = frame-destroy LW $x2, 68 :: (load (s32) from %stack.4)
-  ; RV32I-ZILSD-NEXT:   $x18 = frame-destroy LW $x2, 64 :: (load (s32) from %stack.5)
-  ; RV32I-ZILSD-NEXT:   $x19 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.6)
-  ; RV32I-ZILSD-NEXT:   $x20 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.7)
-  ; RV32I-ZILSD-NEXT:   $x21 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.8)
-  ; RV32I-ZILSD-NEXT:   $x22 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.9)
-  ; RV32I-ZILSD-NEXT:   $x23 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.10)
-  ; RV32I-ZILSD-NEXT:   $x24 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.11)
-  ; RV32I-ZILSD-NEXT:   $x25 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.12)
-  ; RV32I-ZILSD-NEXT:   $x26 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.13)
-  ; RV32I-ZILSD-NEXT:   $x27 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.14)
+  ; RV32I-ZILSD-NEXT:   $x8_x9 = frame-destroy LD_RV32 $x2, 64 :: (load (s64) from %stack.3)
+  ; RV32I-ZILSD-NEXT:   $x18_x19 = frame-destroy LD_RV32 $x2, 56 :: (load (s64) from %stack.4)
+  ; RV32I-ZILSD-NEXT:   $x20_x21 = frame-destroy LD_RV32 $x2, 48 :: (load (s64) from %stack.5)
+  ; RV32I-ZILSD-NEXT:   $x22_x23 = frame-destroy LD_RV32 $x2, 40 :: (load (s64) from %stack.6)
+  ; RV32I-ZILSD-NEXT:   $x24_x25 = frame-destroy LD_RV32 $x2, 32 :: (load (s64) from %stack.7)
+  ; RV32I-ZILSD-NEXT:   $x26_x27 = frame-destroy LD_RV32 $x2, 24 :: (load (s64) from %stack.8)
   ; RV32I-ZILSD-NEXT:   $x2 = frame-destroy ADDI $x2, 80
   ; RV32I-ZILSD-NEXT:   PseudoRET implicit $x10, implicit $x11
   ;
   ; RV32I-ZILSD-UNALIGNED-LABEL: name: cmpxchg_i64_monotonic_monotonic
   ; RV32I-ZILSD-UNALIGNED: bb.0 (%ir-block.0):
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8_x9, $x18_x19, $x20_x21, $x22_x23, $x24_x25, $x26_x27
   ; RV32I-ZILSD-UNALIGNED-NEXT: {{  $}}
   ; RV32I-ZILSD-UNALIGNED-NEXT:   $x2 = frame-setup ADDI $x2, -80
   ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x1, $x2, 76 :: (store (s32) into %stack.2)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x8, $x2, 72 :: (store (s32) into %stack.3)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x9, $x2, 68 :: (store (s32) into %stack.4)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x18, $x2, 64 :: (store (s32) into %stack.5)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x19, $x2, 60 :: (store (s32) into %stack.6)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x20, $x2, 56 :: (store (s32) into %stack.7)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x21, $x2, 52 :: (store (s32) into %stack.8)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x22, $x2, 48 :: (store (s32) into %stack.9)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x23, $x2, 44 :: (store (s32) into %stack.10)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x24, $x2, 40 :: (store (s32) into %stack.11)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x25, $x2, 36 :: (store (s32) into %stack.12)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x26, $x2, 32 :: (store (s32) into %stack.13)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SW killed $x27, $x2, 28 :: (store (s32) into %stack.14)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x8_x9, $x2, 68 :: (store (s64) into %stack.3, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x18_x19, $x2, 60 :: (store (s64) into %stack.4, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x20_x21, $x2, 52 :: (store (s64) into %stack.5, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x22_x23, $x2, 44 :: (store (s64) into %stack.6, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x24_x25, $x2, 36 :: (store (s64) into %stack.7, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   frame-setup SD_RV32 killed $x26_x27, $x2, 28 :: (store (s64) into %stack.8, align 1)
   ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x17 = COPY $x12
   ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x16 = COPY $x11
   ; RV32I-ZILSD-UNALIGNED-NEXT:   SD_RV32 killed renamable $x16_x17, $x2, 16 :: (store (s64) into %ir.1)
@@ -147,39 +129,27 @@ define i64 @cmpxchg_i64_monotonic_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwi
   ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x12 = ADD killed renamable $x13, renamable $x13
   ; RV32I-ZILSD-UNALIGNED-NEXT:   renamable $x11 = ADD killed renamable $x12, killed renamable $x11
   ; RV32I-ZILSD-UNALIGNED-NEXT:   $x1 = frame-destroy LW $x2, 76 :: (load (s32) from %stack.2)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x8 = frame-destroy LW $x2, 72 :: (load (s32) from %stack.3)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x9 = frame-destroy LW $x2, 68 :: (load (s32) from %stack.4)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x18 = frame-destroy LW $x2, 64 :: (load (s32) from %stack.5)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x19 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.6)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x20 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.7)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x21 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.8)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x22 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.9)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x23 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.10)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x24 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.11)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x25 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.12)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x26 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.13)
-  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x27 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.14)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x8_x9 = frame-destroy LD_RV32 $x2, 68 :: (load (s64) from %stack.3, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x18_x19 = frame-destroy LD_RV32 $x2, 60 :: (load (s64) from %stack.4, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x20_x21 = frame-destroy LD_RV32 $x2, 52 :: (load (s64) from %stack.5, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x22_x23 = frame-destroy LD_RV32 $x2, 44 :: (load (s64) from %stack.6, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x24_x25 = frame-destroy LD_RV32 $x2, 36 :: (load (s64) from %stack.7, align 1)
+  ; RV32I-ZILSD-UNALIGNED-NEXT:   $x26_x27 = frame-destroy LD_RV32 $x2, 28 :: (load (s64) from %stack.8, align 1)
   ; RV32I-ZILSD-UNALIGNED-NEXT:   $x2 = frame-destroy ADDI $x2, 80
   ; RV32I-ZILSD-UNALIGNED-NEXT:   PseudoRET implicit $x10, implicit $x11
   ;
   ; RV32I-ZILSD-4BYTEALIGN-LABEL: name: cmpxchg_i64_monotonic_monotonic
   ; RV32I-ZILSD-4BYTEALIGN: bb.0 (%ir-block.0):
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x1, $x8_x9, $x18_x19, $x20_x21, $x22_x23, $x24_x25, $x26_x27
   ; RV32I-ZILSD-4BYTEALIGN-NEXT: {{  $}}
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-setup ADDI $x2, -80
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x1, $x2, 76 :: (store (s32) into %stack.2)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x8, $x2, 72 :: (store (s32) into %stack.3)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x9, $x2, 68 :: (store (s32) into %stack.4)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x18, $x2, 64 :: (store (s32) into %stack.5)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x19, $x2, 60 :: (store (s32) into %stack.6)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x20, $x2, 56 :: (store (s32) into %stack.7)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x21, $x2, 52 :: (store (s32) into %stack.8)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x22, $x2, 48 :: (store (s32) into %stack.9)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x23, $x2, 44 :: (store (s32) into %stack.10)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x24, $x2, 40 :: (store (s32) into %stack.11)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x25, $x2, 36 :: (store (s32) into %stack.12)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x26, $x2, 32 :: (store (s32) into %stack.13)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SW killed $x27, $x2, 28 :: (store (s32) into %stack.14)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x8_x9, $x2, 68 :: (store (s64) into %stack.3, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x18_x19, $x2, 60 :: (store (s64) into %stack.4, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x20_x21, $x2, 52 :: (store (s64) into %stack.5, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x22_x23, $x2, 44 :: (store (s64) into %stack.6, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x24_x25, $x2, 36 :: (store (s64) into %stack.7, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   frame-setup SD_RV32 killed $x26_x27, $x2, 28 :: (store (s64) into %stack.8, align 4)
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x17 = COPY $x12
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x16 = COPY $x11
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   SD_RV32 killed renamable $x16_x17, $x2, 16 :: (store (s64) into %ir.1)
@@ -198,18 +168,12 @@ define i64 @cmpxchg_i64_monotonic_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwi
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x12 = ADD killed renamable $x13, renamable $x13
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   renamable $x11 = ADD killed renamable $x12, killed renamable $x11
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x1 = frame-destroy LW $x2, 76 :: (load (s32) from %stack.2)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x8 = frame-destroy LW $x2, 72 :: (load (s32) from %stack.3)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x9 = frame-destroy LW $x2, 68 :: (load (s32) from %stack.4)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x18 = frame-destroy LW $x2, 64 :: (load (s32) from %stack.5)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x19 = frame-destroy LW $x2, 60 :: (load (s32) from %stack.6)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x20 = frame-destroy LW $x2, 56 :: (load (s32) from %stack.7)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x21 = frame-destroy LW $x2, 52 :: (load (s32) from %stack.8)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x22 = frame-destroy LW $x2, 48 :: (load (s32) from %stack.9)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x23 = frame-destroy LW $x2, 44 :: (load (s32) from %stack.10)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x24 = frame-destroy LW $x2, 40 :: (load (s32) from %stack.11)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x25 = frame-destroy LW $x2, 36 :: (load (s32) from %stack.12)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x26 = frame-destroy LW $x2, 32 :: (load (s32) from %stack.13)
-  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x27 = frame-destroy LW $x2, 28 :: (load (s32) from %stack.14)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x8_x9 = frame-destroy LD_RV32 $x2, 68 :: (load (s64) from %stack.3, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x18_x19 = frame-destroy LD_RV32 $x2, 60 :: (load (s64) from %stack.4, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x20_x21 = frame-destroy LD_RV32 $x2, 52 :: (load (s64) from %stack.5, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x22_x23 = frame-destroy LD_RV32 $x2, 44 :: (load (s64) from %stack.6, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x24_x25 = frame-destroy LD_RV32 $x2, 36 :: (load (s64) from %stack.7, align 4)
+  ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x26_x27 = frame-destroy LD_RV32 $x2, 28 :: (load (s64) from %stack.8, align 4)
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   $x2 = frame-destroy ADDI $x2, 80
   ; RV32I-ZILSD-4BYTEALIGN-NEXT:   PseudoRET implicit $x10, implicit $x11
   %res = cmpxchg ptr %ptr, i64 %cmp, i64 %val monotonic monotonic

>From 1653706d0668b4ff73395c86550773feaeb76918 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 5 Mar 2026 08:42:10 -0800
Subject: [PATCH 2/3] fixup! exceeds stack align

---
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp |   5 +-
 llvm/test/CodeGen/RISCV/callee-saved-gprs.ll | 501 +++++++++++++++++++
 2 files changed, 505 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 93a49ed8d23d4..ea179eee6aa71 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1653,7 +1653,10 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
 
   // For Zilsd on RV32, append GPRPair registers to the CSR list. This prevents
   // the need to create register sets for each abi which is a lot more complex.
-  bool UseZilsd = !STI.is64Bit() && STI.hasStdExtZilsd();
+  // Don't use Zilsd for callee-saved coalescing if the required alignment
+  // exceeds the stack alignment.
+  bool UseZilsd = !STI.is64Bit() && STI.hasStdExtZilsd() &&
+                  STI.getZilsdAlign() <= getStackAlign();
   if (UseZilsd) {
     SmallVector<MCPhysReg, 32> NewCSRs;
     SmallSet<MCPhysReg, 16> CSRSet;
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
index c3209493255c3..a62c790ffaf5d 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -35,6 +35,10 @@
 ; RUN:   | FileCheck %s -check-prefix=RV32I-ZILSD
 ; RUN: llc -mtriple=riscv32 -mattr=+zilsd -verify-machineinstrs -frame-pointer=all < %s \
 ; RUN:   | FileCheck %s -check-prefix=RV32I-ZILSD-WITH-FP
+; RUN: llc -mtriple=riscv32 -mattr=+zilsd -target-abi ilp32e -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I-ZILSD-ILP32E
+; RUN: llc -mtriple=riscv32 -mattr=+zilsd,+zilsd-4byte-align -target-abi ilp32e -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I-ZILSD-ILP32E-4BYTE
 
 @var = global [32 x i32] zeroinitializer
 
@@ -1490,6 +1494,174 @@ define void @callee() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 80
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV32I-ZILSD-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-LABEL: callee:
+; RV32I-ZILSD-ILP32E:       # %bb.0:
+; RV32I-ZILSD-ILP32E-NEXT:    addi sp, sp, -32
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_def_cfa_offset 32
+; RV32I-ZILSD-ILP32E-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset s0, -8
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset s1, -12
+; RV32I-ZILSD-ILP32E-NEXT:    lui a0, %hi(var)
+; RV32I-ZILSD-ILP32E-NEXT:    addi a0, a0, %lo(var)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 0(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a2, 4(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a2, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 16(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 8(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a2, 12(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a2, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 16(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a6, 20(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 0(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld t1, 24(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld t3, 32(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld t5, 40(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld s2, 48(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld s4, 56(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld s6, 64(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld s8, 72(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld s10, 80(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld s0, 88(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 120(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw t0, 124(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw ra, 96(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a7, 100(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld a2, 112(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    ld a4, 104(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t0, 124(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 120(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a3, 116(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a2, 112(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a5, 108(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a4, 104(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a7, 100(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw ra, 96(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s1, 92(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s0, 88(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s11, 84(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s10, 80(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s9, 76(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s8, 72(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s7, 68(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s6, 64(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s5, 60(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s4, 56(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s3, 52(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw s2, 48(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t6, 44(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t5, 40(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t4, 36(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t3, 32(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t2, 28(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw t1, 24(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a6, 20(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 0(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 16(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 12(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 8(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 4(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a1, 16(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 0(a0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-ILP32E-NEXT:    addi sp, sp, 32
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-ILP32E-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-4BYTE-LABEL: callee:
+; RV32I-ZILSD-ILP32E-4BYTE:       # %bb.0:
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi sp, sp, -32
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_def_cfa_offset 32
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sd s0, 20(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset s0, -12
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset s1, -8
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lui a0, %hi(var)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi a0, a0, %lo(var)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 0(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a2, 4(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a2, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 16(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 8(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a2, 12(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a2, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 16(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a6, 20(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 0(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld t1, 24(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld t3, 32(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld t5, 40(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s2, 48(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s4, 56(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s6, 64(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s8, 72(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s10, 80(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s0, 88(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 120(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw t0, 124(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw ra, 96(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a7, 100(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a2, 112(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a4, 104(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t0, 124(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 120(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a3, 116(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a2, 112(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a5, 108(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a4, 104(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a7, 100(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw ra, 96(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s1, 92(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s0, 88(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s11, 84(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s10, 80(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s9, 76(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s8, 72(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s7, 68(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s6, 64(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s5, 60(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s4, 56(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s3, 52(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s2, 48(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t6, 44(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t5, 40(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t4, 36(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t3, 32(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t2, 28(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw t1, 24(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a6, 20(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 0(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 16(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 12(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 8(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 4(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a1, 16(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 0(a0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s0, 20(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi sp, sp, 32
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ret
   %val = load [32 x i32], ptr @var
   store volatile [32 x i32] %val, ptr @var
   ret void
@@ -3382,6 +3554,272 @@ define void @caller() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 144
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV32I-ZILSD-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-LABEL: caller:
+; RV32I-ZILSD-ILP32E:       # %bb.0:
+; RV32I-ZILSD-ILP32E-NEXT:    addi sp, sp, -136
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_def_cfa_offset 136
+; RV32I-ZILSD-ILP32E-NEXT:    sw ra, 132(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw s0, 128(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw s1, 124(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset s0, -8
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset s1, -12
+; RV32I-ZILSD-ILP32E-NEXT:    lui s0, %hi(var)
+; RV32I-ZILSD-ILP32E-NEXT:    addi s0, s0, %lo(var)
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 0(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 116(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 120(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 8(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 108(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 112(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 16(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 100(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 104(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 24(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 92(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 96(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 32(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 84(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 88(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 40(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 76(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 80(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 48(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 68(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 72(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 56(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 60(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 64(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 64(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 52(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 56(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 72(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 44(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 48(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 80(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 36(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 40(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 88(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 28(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 32(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 96(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 20(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 24(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 104(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 16(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    ld a0, 112(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 120(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw s1, 124(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 0(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    call callee
+; RV32I-ZILSD-ILP32E-NEXT:    sw s1, 124(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 0(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 120(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 116(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 112(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 108(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 16(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 104(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 20(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 100(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 24(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 96(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 28(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 92(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 32(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 88(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 36(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 84(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 40(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 80(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 44(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 76(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 48(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 72(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 52(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 68(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 56(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 64(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 60(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 60(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 64(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 56(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 68(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 52(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 72(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 48(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 76(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 44(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 80(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 40(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 84(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 36(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 88(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 32(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 92(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 28(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 96(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 24(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 100(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 20(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 104(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 16(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 108(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 12(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 112(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 8(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 116(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 4(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw a0, 120(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 0(s0)
+; RV32I-ZILSD-ILP32E-NEXT:    lw ra, 132(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    lw s0, 128(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    lw s1, 124(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-ILP32E-NEXT:    addi sp, sp, 136
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-ILP32E-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-4BYTE-LABEL: caller:
+; RV32I-ZILSD-ILP32E-4BYTE:       # %bb.0:
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi sp, sp, -136
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_def_cfa_offset 136
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw ra, 132(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sd s0, 124(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset ra, -4
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset s0, -12
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset s1, -8
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lui s0, %hi(var)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi s0, s0, %lo(var)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 0(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 116(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 120(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 8(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 108(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 112(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 16(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 100(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 104(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 24(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 92(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 96(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 32(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 84(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 88(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 40(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 76(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 80(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 48(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 68(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 72(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 56(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 60(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 64(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 64(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 52(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 56(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 72(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 44(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 48(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 80(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 36(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 40(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 88(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 28(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 32(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 96(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 20(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 24(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 104(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 12(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 16(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld a0, 112(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a1, 4(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 8(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 120(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw s1, 124(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 0(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    call callee
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw s1, 124(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 0(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 120(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 4(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 116(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 8(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 112(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 12(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 108(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 16(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 104(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 20(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 100(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 24(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 96(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 28(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 92(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 32(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 88(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 36(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 84(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 40(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 80(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 44(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 76(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 48(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 72(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 52(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 68(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 56(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 64(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 60(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 60(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 64(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 56(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 68(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 52(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 72(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 48(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 76(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 44(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 80(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 40(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 84(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 36(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 88(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 32(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 92(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 28(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 96(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 24(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 100(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 20(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 104(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 16(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 108(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 12(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 112(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 8(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 116(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 4(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw a0, 120(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw a0, 0(s0)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw ra, 132(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ld s0, 124(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore s0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore s1
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi sp, sp, 136
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ret
   %val = load [32 x i32], ptr @var
   call void @callee()
   store volatile [32 x i32] %val, ptr @var
@@ -3599,6 +4037,20 @@ define void @foo() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 16
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV32I-ZILSD-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-LABEL: foo:
+; RV32I-ZILSD-ILP32E:       # %bb.0: # %entry
+; RV32I-ZILSD-ILP32E-NEXT:    #APP
+; RV32I-ZILSD-ILP32E-NEXT:    li s4, 0
+; RV32I-ZILSD-ILP32E-NEXT:    #NO_APP
+; RV32I-ZILSD-ILP32E-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-4BYTE-LABEL: foo:
+; RV32I-ZILSD-ILP32E-4BYTE:       # %bb.0: # %entry
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    #APP
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    li s4, 0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    #NO_APP
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ret
 entry:
   tail call void asm sideeffect "li s4, 0", "~{s4}"()
   ret void
@@ -3814,6 +4266,20 @@ define void @bar() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 16
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV32I-ZILSD-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-LABEL: bar:
+; RV32I-ZILSD-ILP32E:       # %bb.0: # %entry
+; RV32I-ZILSD-ILP32E-NEXT:    #APP
+; RV32I-ZILSD-ILP32E-NEXT:    li s11, 0
+; RV32I-ZILSD-ILP32E-NEXT:    #NO_APP
+; RV32I-ZILSD-ILP32E-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-4BYTE-LABEL: bar:
+; RV32I-ZILSD-ILP32E-4BYTE:       # %bb.0: # %entry
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    #APP
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    li s11, 0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    #NO_APP
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ret
 entry:
   tail call void asm sideeffect "li s11, 0", "~{s11}"()
   ret void
@@ -4094,6 +4560,41 @@ define void @varargs(...) {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, 48
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 0
 ; RV32I-ZILSD-WITH-FP-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-LABEL: varargs:
+; RV32I-ZILSD-ILP32E:       # %bb.0:
+; RV32I-ZILSD-ILP32E-NEXT:    addi sp, sp, -28
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_def_cfa_offset 28
+; RV32I-ZILSD-ILP32E-NEXT:    sw ra, 0(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_offset ra, -28
+; RV32I-ZILSD-ILP32E-NEXT:    sw a4, 20(sp)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a5, 24(sp)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a0, 4(sp)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a1, 8(sp)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a2, 12(sp)
+; RV32I-ZILSD-ILP32E-NEXT:    sw a3, 16(sp)
+; RV32I-ZILSD-ILP32E-NEXT:    call callee
+; RV32I-ZILSD-ILP32E-NEXT:    lw ra, 0(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-ILP32E-NEXT:    addi sp, sp, 28
+; RV32I-ZILSD-ILP32E-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-ILP32E-NEXT:    ret
+;
+; RV32I-ZILSD-ILP32E-4BYTE-LABEL: varargs:
+; RV32I-ZILSD-ILP32E-4BYTE:       # %bb.0:
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi sp, sp, -28
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_def_cfa_offset 28
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sw ra, 0(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_offset ra, -28
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sd a4, 20(sp)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sd a2, 12(sp)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    sd a0, 4(sp)
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    call callee
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    lw ra, 0(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_restore ra
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    addi sp, sp, 28
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-ZILSD-ILP32E-4BYTE-NEXT:    ret
   call void @callee()
   ret void
 }

>From fe0c3b3e1e162855daa064cdea35f95325849f43 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 5 Mar 2026 09:12:30 -0800
Subject: [PATCH 3/3] fixup! dont combine fp

---
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 12 ++++++++----
 llvm/test/CodeGen/RISCV/callee-saved-gprs.ll | 16 ++++++++++------
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index ea179eee6aa71..b7856b2805cb6 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1683,20 +1683,24 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
   // aliases like X8_W or X8_H which are not set in SavedRegs.
   for (unsigned i = 0; CSRegs[i]; ++i) {
     unsigned CSReg = CSRegs[i];
-    bool AllSubRegsSaved;
+    bool CombineToSuperReg;
     if (RISCV::GPRPairRegClass.contains(CSReg)) {
       MCPhysReg EvenReg = TRI.getSubReg(CSReg, RISCV::sub_gpr_even);
       MCPhysReg OddReg = TRI.getSubReg(CSReg, RISCV::sub_gpr_odd);
-      AllSubRegsSaved = SavedRegs.test(EvenReg) && SavedRegs.test(OddReg);
+      CombineToSuperReg = SavedRegs.test(EvenReg) && SavedRegs.test(OddReg);
+      // If s0(x8) is used as FP we can't generate load/store pair because it
+      // breaks the frame chain.
+      if (hasFP(MF) && CSReg == RISCV::X8_X9)
+        CombineToSuperReg = false;
     } else {
       auto SubRegs = TRI.subregs(CSReg);
-      AllSubRegsSaved =
+      CombineToSuperReg =
           !SubRegs.empty() && llvm::all_of(SubRegs, [&](unsigned Reg) {
             return SavedRegs.test(Reg);
           });
     }
 
-    if (AllSubRegsSaved)
+    if (CombineToSuperReg)
       SavedRegs.set(CSReg);
   }
 
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
index a62c790ffaf5d..4e5d175e0ee12 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -1382,14 +1382,15 @@ define void @callee() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -80
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 80
 ; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 76(sp) # 4-byte Folded Spill
-; RV32I-ZILSD-WITH-FP-NEXT:    sd s0, 64(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s0, 72(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s1, 68(sp) # 4-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s2, 56(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s4, 48(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s6, 40(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s8, 32(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s10, 24(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -4
-; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -8
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s1, -12
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s2, -24
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s3, -20
@@ -1472,7 +1473,8 @@ define void @callee() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    sw a1, 0(a0)
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 80
 ; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 76(sp) # 4-byte Folded Reload
-; RV32I-ZILSD-WITH-FP-NEXT:    ld s0, 64(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s0, 72(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s1, 68(sp) # 4-byte Folded Reload
 ; RV32I-ZILSD-WITH-FP-NEXT:    ld s2, 56(sp) # 8-byte Folded Reload
 ; RV32I-ZILSD-WITH-FP-NEXT:    ld s4, 48(sp) # 8-byte Folded Reload
 ; RV32I-ZILSD-WITH-FP-NEXT:    ld s6, 40(sp) # 8-byte Folded Reload
@@ -3414,14 +3416,15 @@ define void @caller() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    addi sp, sp, -144
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa_offset 144
 ; RV32I-ZILSD-WITH-FP-NEXT:    sw ra, 140(sp) # 4-byte Folded Spill
-; RV32I-ZILSD-WITH-FP-NEXT:    sd s0, 128(sp) # 8-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s0, 136(sp) # 4-byte Folded Spill
+; RV32I-ZILSD-WITH-FP-NEXT:    sw s1, 132(sp) # 4-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s2, 120(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s4, 112(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s6, 104(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s8, 96(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    sd s10, 88(sp) # 8-byte Folded Spill
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset ra, -4
-; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -16
+; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s0, -8
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s1, -12
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s2, -24
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_offset s3, -20
@@ -3532,7 +3535,8 @@ define void @caller() {
 ; RV32I-ZILSD-WITH-FP-NEXT:    sw a0, 0(s1)
 ; RV32I-ZILSD-WITH-FP-NEXT:    .cfi_def_cfa sp, 144
 ; RV32I-ZILSD-WITH-FP-NEXT:    lw ra, 140(sp) # 4-byte Folded Reload
-; RV32I-ZILSD-WITH-FP-NEXT:    ld s0, 128(sp) # 8-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s0, 136(sp) # 4-byte Folded Reload
+; RV32I-ZILSD-WITH-FP-NEXT:    lw s1, 132(sp) # 4-byte Folded Reload
 ; RV32I-ZILSD-WITH-FP-NEXT:    ld s2, 120(sp) # 8-byte Folded Reload
 ; RV32I-ZILSD-WITH-FP-NEXT:    ld s4, 112(sp) # 8-byte Folded Reload
 ; RV32I-ZILSD-WITH-FP-NEXT:    ld s6, 104(sp) # 8-byte Folded Reload



More information about the llvm-commits mailing list