[clang] [llvm] [RISCV] Add partial support for -fzero-call-used-regs (PR #194883)

Lucas Chollet via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 30 07:27:09 PDT 2026


================
@@ -3935,6 +3939,22 @@ MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall(
   return It;
 }
 
+void RISCVInstrInfo::buildClearRegister(Register Reg, MachineBasicBlock &MBB,
+                                        MachineBasicBlock::iterator Iter,
+                                        DebugLoc &DL,
+                                        bool AllowSideEffects) const {
+
+  const MachineFunction &MF = *MBB.getParent();
+  const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>();
+  const RISCVRegisterInfo &TRI = *STI.getRegisterInfo();
+
+  if (TRI.isGeneralPurposeRegister(MF, Reg)) {
+    BuildMI(MBB, Iter, DL, get(RISCV::PseudoLI), Reg).addImm(0);
----------------
LucasChollet wrote:

I looked a bit into it and I can't find a way to clear the registers that is not optimized away.

`ADDI rd, x0, 0` are removed by the `machine-cp` pass due to `ADDI rd, r, 0` being flagged as a copy instruction (`isCopyInstrImpl`). If I patch this function to not consider `ADDI rd, x0, 0` as a copy, it allows us to properly clear the registers but make other test fail.

More complex instructions (like `AND`, `XOR` and even `MUL`) are turned into a `ADDI rd, x0, 0` in the first `machine-cp` pass after `prologepilog`. Then a second `machine-cp` pass remove them completely.

---

> PseudoLI is tagged as isAsmParserOnly it should not be used in CodeGen.

I don't understand how, but I think it is used. `ADDI rd, x0, 1` are turned into `li rd, 1`.

---

It seems that the only reason the X86 and the AArch64 version of `buildClearRegister` work is that they use instructions that are not recognized by `isCopyInstr` (and thus not optimized away by `machine-cp`).

X86's `buildClearRegister` uses `MOV32ri` or `XOR32rr` but `isCopyInstrImpl` only considers `isMoveReg` (`MOV32ri` is a `MovImm` not `MovReg`)

AArch64's `buildClearRegister` uses `MOV` but `isCopyInstrImpl` doesn't check for it.

---

Do you have an idea of how we should proceed?

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


More information about the cfe-commits mailing list