[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
Fri Mar 6 08:37:29 PST 2026


================
@@ -1633,6 +1651,59 @@ 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.
+  // 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;
+    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);
----------------
4vtomat wrote:

I think I was wrong, they pad the gap to make it align.

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


More information about the llvm-commits mailing list