[llvm] [RISCV] Refactor copy from X0 recognition in RISCVRedundantCopyElimination. (PR #228661)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 22:07:53 PDT 2026


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/228661

Move the x0 copy recognition into matchRegImmediate and rename to matchRegKnownVal.

Not sure if this completely NFC since we use matchRegImmediate in two places. Copy from X0 was only recognized in one of those places. The other place is when we want to know if the input to a compare is a known value. It's possible for the compare to use a copy from X0 but it's probably uncommon.

>From 7d8a05b2e701372b581b239dcc69919d8f598579 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 2 Oct 2026 21:44:41 -0700
Subject: [PATCH] [RISCV] Refactor copy from X0 recognition in
 RISCVRedundantCopyElimination.

Move the x0 copy recognition into matchRegImmediate and rename
to matchRegKnownVal.

Not sure if this completely NFC since we use matchRegImmediate in
two places. Copy from X0 was only recognized in one of those places.
The other place is when we want to know if the input to a compare
is a known value. It's possible for the compare to use a copy from
X0 but it's probably uncommon.
---
 .../RISCV/RISCVRedundantCopyElimination.cpp   | 39 +++++++------------
 1 file changed, 13 insertions(+), 26 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVRedundantCopyElimination.cpp b/llvm/lib/Target/RISCV/RISCVRedundantCopyElimination.cpp
index 67785f666531f..cfeb2b967d88d 100644
--- a/llvm/lib/Target/RISCV/RISCVRedundantCopyElimination.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRedundantCopyElimination.cpp
@@ -109,10 +109,12 @@ guaranteesRegEqualsImmInBlock(MachineBasicBlock &MBB,
   return false;
 }
 
-// Match "addi rd, x0, imm" or "qc.li rd, imm", returning the defined
-// register and the materialized immediate. Reg is invalid if MI isn't a
-// match.
-static RegImmPair matchRegImmediate(const MachineInstr &MI) {
+// Match copy from x0, "addi rd, x0, imm", or "qc.li rd, imm", returning the
+// defined register and the known value. Reg is invalid if MI isn't a match.
+static RegImmPair matchRegKnownVal(const MachineInstr &MI) {
+  if (MI.isCopy() && MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
+      MI.getOperand(1).getReg() == RISCV::X0)
+    return RegImmPair(MI.getOperand(0).getReg(), 0);
   if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(0).isReg() &&
       MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
       MI.getOperand(2).isImm())
@@ -134,8 +136,8 @@ getRegImmediateBeforeTerminator(MachineBasicBlock &MBB, Register Reg,
     MachineInstr &MI = *--I;
     if (!MI.modifiesRegister(Reg, TRI))
       continue;
-    // The last modification must define Reg itself to a known immediate.
-    RegImmPair Match = matchRegImmediate(MI);
+    // The last modification must define Reg itself to a known value.
+    RegImmPair Match = matchRegKnownVal(MI);
     if (Match.Reg == Reg)
       return Match.Imm;
     return std::nullopt;
@@ -202,26 +204,11 @@ bool RISCVRedundantCopyElimination::optimizeBlock(MachineBasicBlock &MBB) {
   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;) {
     MachineInstr *MI = &*I;
     ++I;
-    bool RemoveMI = false;
-    if (IsZeroCopy) {
-      if (MI->isCopy() && MI->getOperand(0).isReg() &&
-          MI->getOperand(1).isReg()) {
-        Register DefReg = MI->getOperand(0).getReg();
-        Register SrcReg = MI->getOperand(1).getReg();
-
-        if (SrcReg == RISCV::X0 && TargetReg == DefReg &&
-            !MRI->isReserved(DefReg))
-          RemoveMI = true;
-      }
-    } else {
-      // Compare with non-zero immediate or a known register value:
-      // remove redundant addi rd,x0,imm or qc.li rd,imm as applicable.
-      RegImmPair Match = matchRegImmediate(*MI);
-      if (Match.Reg && TargetReg == Match.Reg && Match.Imm == CompareImm)
-        RemoveMI = true;
-    }
-
-    if (RemoveMI) {
+    // Compare with non-zero immediate or a known register value:
+    // remove redundant copy, addi rd,x0,imm, or qc.li rd,imm as applicable.
+    RegImmPair Match = matchRegKnownVal(*MI);
+    if (Match.Reg && TargetReg == Match.Reg && Match.Imm == CompareImm &&
+        !MRI->isReserved(Match.Reg)) {
       LLVM_DEBUG(dbgs() << "Remove redundant Copy: ");
       LLVM_DEBUG(MI->print(dbgs()));
 



More information about the llvm-commits mailing list