[llvm] [RISCV] Add CompressPat for all cases in isCopyInstrImpl (PR #136875)

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 23 07:37:07 PDT 2025


https://github.com/asb created https://github.com/llvm/llvm-project/pull/136875

We may end up with a non-canonical move (copy) instruction after a pass like MachineCopyPropagation that doesn't get compressed because we don't have an explicit pattern for it. This patch addresses that by adding additional CompressPat. This means that the generated code will be slightly different with/without the compressed extension. This isn't expected to be problematic as the instructions in question are all simple arithmetic ops.

This removes 214 static instances of such instructions in an llvm-test-suite rva22 compile including SPEC. I don't claim this is any great win, but particularly as these do show up in benchmarks that people spend a lot of time analysing my preference is to remove codegen oddities like this where it's reasonable to do so, so as to avoid distraction/wasted time when people are analysing said benchmarks.

---
Question for reviewers: are you happy with the approach of adding as a CompressPat? The alternative would be to try to do this independent of whether C is enabled or not through either a canonicalisation pass, or adding a TargetInstrInfo hook like canonicalizeCopyInstr that MachineCopyPropagation calls after mutating something that was isCopyInstr.

If we're happy with this implementation approach I will add the necessary MC tests and mark for review.

>From 6a6a2241a9fa350240cf354b36cc692eb59f8508 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Wed, 23 Apr 2025 15:15:38 +0100
Subject: [PATCH] [RISCV] Add CompressPat for all cases in isCopyInstrImpl

We may end up with a non-canonical move (copy) instruction after a pass like
MachineCopyPropagation that doesn't get compressed because we don't have
an explicit pattern for it. This patch addressses that by adding
additional CompressPat. This means that the generated code will be
slightly different with/without the compressed extension. This isn't
expected to be problematic as the instructions in question are all
simple arithmetic ops.
---
 llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 30 ++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index 252100c814f2b..8dc26f7b1f29f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -1012,11 +1012,15 @@ let Predicates = [HasStdExtCOrZca] in {
 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
                   (C_JR GPRNoX0:$rs1)>;
 let isCompressOnly = true in {
-def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
-                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
-def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
-                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+foreach Inst=[ADD, OR, XOR] in {
+  def : CompressPat<(Inst GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                    (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+  def : CompressPat<(Inst GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
+                    (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
 }
+def : CompressPat<(SUB GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+} // isCompressOnly
 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
 def : CompressPat<(EBREAK), (C_EBREAK)>;
@@ -1053,3 +1057,21 @@ let Predicates = [HasStdExtCOrZca, IsRV64] in {
 def : CompressPat<(SD GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
                   (C_SDSP GPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
 } // Predicates = [HasStdExtCOrZca, IsRV64]
+
+let Predicates = [HasStdExtCOrZca, HasStdExtZba] in {
+def : CompressPat<(SH1ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+def : CompressPat<(SH2ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+def : CompressPat<(SH3ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+} // Predicates = [HasStdExtCOrZca, HasStdExtZba]
+
+let Predicates = [HasStdExtCOrZca, HasStdExtZba, IsRV64] in {
+def : CompressPat<(SH1ADD_UW GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+def : CompressPat<(SH2ADD_UW GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+def : CompressPat<(SH3ADD_UW GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
+                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+} // Predicates = [HasStdExtCOrZca, HasStdExtZba, IsRV64]



More information about the llvm-commits mailing list