[llvm] [RISCV] Use SelectAddrRegRegScale for Xqcisls instructions. (PR #145608)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 25 21:01:06 PDT 2025


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/145608

>From 2c4d0e93c72f5912a3b972b6c2a6a9970a7ad12d Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Tue, 24 Jun 2025 14:58:46 -0700
Subject: [PATCH] [RISCV] Use SelectAddrRegRegScale for Qcisls instructions.

This reuses code from XTHeadMemIdex. This saves ~500 bytes
from the isel table and provides more flexibility in what patterns
can be matched.
---
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |  6 +++
 llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td | 14 +++---
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   |  9 ++--
 llvm/test/CodeGen/RISCV/xqcisls.ll            | 47 ++++++++-----------
 4 files changed, 36 insertions(+), 40 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index aa1ebba567824..a25d4e67d1d73 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -502,6 +502,12 @@ def uimm6gt32 : ImmLeaf<XLenVT, [{
 // Addressing modes.
 def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">;
 
+class AddrRegRegScale<int N>
+    : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<"#N#">">;
+class AddrRegZextRegScale<int N>
+    : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<"#N#", 32>",
+                     [], [], 10>;
+
 // Return the negation of an immediate value.
 def NegImm : SDNodeXForm<imm, [{
   return CurDAG->getSignedTargetConstant(-N->getSExtValue(), SDLoc(N),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td
index 89441444a994e..c23a58ceccead 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td
@@ -743,32 +743,30 @@ def TH_SYNC_I      : THCacheInst_void<0b11010, "th.sync.i">;
 def TH_SYNC_IS     : THCacheInst_void<0b11011, "th.sync.is">;
 }
 
-def AddrRegRegScale : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<3>">;
-def AddrRegZextRegScale
-    : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<3, 32>",
-                     [], [], 10>;
+def AddrRegRegScale3 : AddrRegRegScale<3>;
+def AddrRegZextRegScale3 : AddrRegZextRegScale<3>;
 
 multiclass LdIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
-def : Pat<(vt (LoadOp (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2))),
+def : Pat<(vt (LoadOp (AddrRegRegScale3 (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2))),
           (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
 }
 
 multiclass LdZextIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = i64> {
-def : Pat<(vt (LoadOp (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2))),
+def : Pat<(vt (LoadOp (AddrRegZextRegScale3 (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2))),
           (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
 }
 
 multiclass StIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
                     ValueType vt = XLenVT> {
 def : Pat<(StoreOp (vt StTy:$rd),
-            (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2)),
+            (AddrRegRegScale3 (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2)),
           (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
 }
 
 multiclass StZextIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
                         ValueType vt = i64> {
 def : Pat<(StoreOp (vt StTy:$rd),
-            (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2)),
+            (AddrRegZextRegScale3 (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2)),
           (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
 }
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index ccd20859c24e6..a62428a997e11 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -198,9 +198,6 @@ def AddLike: PatFrags<(ops node:$A, node:$B),
     return CurDAG->isBaseWithConstantOffset(SDValue(N, 0));
 }]>;
 
-def AddShl : PatFrag<(ops node:$Ra, node:$Rb, node:$SH3),
-                     (add node:$Ra, (shl node:$Rb, node:$SH3))>;
-
 def IntCCtoQCRISCVCC : SDNodeXForm<riscv_selectcc, [{
   ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
   int64_t Imm = cast<ConstantSDNode>(N->getOperand(1))->getSExtValue();
@@ -1327,12 +1324,14 @@ class QC48StPat<PatFrag StoreOp, RVInst48 Inst>
     : Pat<(StoreOp (i32 GPR:$rs2), (AddLike (i32 GPR:$rs1), simm26_nosimm12:$imm26)),
           (Inst GPR:$rs2, GPR:$rs1, simm26_nosimm12:$imm26)>;
 
+def AddrRegRegScale7 : AddrRegRegScale<7>;
+
 class QCScaledLdPat<PatFrag LoadOp, RVInst Inst>
-    : Pat<(i32 (LoadOp (AddShl (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt))),
+    : Pat<(i32 (LoadOp (AddrRegRegScale7 (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt))),
           (Inst GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;
 
 class QCScaledStPat<PatFrag StoreOp, RVInst Inst>
-    : Pat<(StoreOp (i32 GPR:$rd), (AddShl (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt)),
+    : Pat<(StoreOp (i32 GPR:$rd), (AddrRegRegScale7 (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt)),
           (Inst GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;
 
 // Match `riscv_brcc` and lower to the appropriate XQCIBI branch instruction.
diff --git a/llvm/test/CodeGen/RISCV/xqcisls.ll b/llvm/test/CodeGen/RISCV/xqcisls.ll
index fc54a67c1fee9..2bc4834ad3559 100644
--- a/llvm/test/CodeGen/RISCV/xqcisls.ll
+++ b/llvm/test/CodeGen/RISCV/xqcisls.ll
@@ -221,8 +221,7 @@ define i8 @lrb_anyext(ptr %a, i64 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lrb_anyext:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    lbu a0, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.lrbu a0, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    ret
   %1 = getelementptr i8, ptr %a, i64 %b
   %2 = load i8, ptr %1, align 1
@@ -254,8 +253,7 @@ define i64 @lrb(ptr %a, i64 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lrb:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    lb a1, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.lrb a1, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    srai a2, a1, 31
 ; RV32IZBAXQCISLS-NEXT:    add a0, a1, a1
 ; RV32IZBAXQCISLS-NEXT:    sltu a1, a0, a1
@@ -284,8 +282,7 @@ define i8 @lurb_anyext(ptr %a, i32 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lurb_anyext:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    lbu a0, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.lrbu a0, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
@@ -318,8 +315,7 @@ define i64 @lurb(ptr %a, i32 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lurb:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    lb a1, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.lrb a1, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    srai a2, a1, 31
 ; RV32IZBAXQCISLS-NEXT:    add a0, a1, a1
 ; RV32IZBAXQCISLS-NEXT:    sltu a1, a0, a1
@@ -353,8 +349,7 @@ define i64 @lrbu(ptr %a, i64 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lrbu:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    lbu a1, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.lrbu a1, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    add a0, a1, a1
 ; RV32IZBAXQCISLS-NEXT:    sltu a1, a0, a1
 ; RV32IZBAXQCISLS-NEXT:    ret
@@ -384,8 +379,7 @@ define i64 @lurbu(ptr %a, i32 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lurbu:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    lbu a1, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.lrbu a1, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    add a0, a1, a1
 ; RV32IZBAXQCISLS-NEXT:    sltu a1, a0, a1
 ; RV32IZBAXQCISLS-NEXT:    ret
@@ -423,13 +417,14 @@ define i64 @lrd_2(ptr %a, i64 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lrd_2:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    sh3add a0, a1, a0
-; RV32IZBAXQCISLS-NEXT:    lw a1, 96(a0)
-; RV32IZBAXQCISLS-NEXT:    lw a2, 100(a0)
-; RV32IZBAXQCISLS-NEXT:    add a0, a1, a1
-; RV32IZBAXQCISLS-NEXT:    sltu a1, a0, a1
-; RV32IZBAXQCISLS-NEXT:    add a2, a2, a2
-; RV32IZBAXQCISLS-NEXT:    add a1, a2, a1
+; RV32IZBAXQCISLS-NEXT:    addi a2, a0, 96
+; RV32IZBAXQCISLS-NEXT:    qc.lrw a2, a2, a1, 3
+; RV32IZBAXQCISLS-NEXT:    addi a0, a0, 100
+; RV32IZBAXQCISLS-NEXT:    qc.lrw a1, a0, a1, 3
+; RV32IZBAXQCISLS-NEXT:    add a0, a2, a2
+; RV32IZBAXQCISLS-NEXT:    sltu a2, a0, a2
+; RV32IZBAXQCISLS-NEXT:    add a1, a1, a1
+; RV32IZBAXQCISLS-NEXT:    add a1, a1, a2
 ; RV32IZBAXQCISLS-NEXT:    ret
   %1 = add i64 %b, 12
   %2 = getelementptr i64, ptr %a, i64 %1
@@ -456,8 +451,7 @@ define void @srb(ptr %a, i64 %b, i8 %c) {
 ; RV32IZBAXQCISLS-LABEL: srb:
 ; RV32IZBAXQCISLS:       # %bb.0:
 ; RV32IZBAXQCISLS-NEXT:    add a3, a3, a3
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    sb a3, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.srb a3, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    ret
   %1 = add i8 %c, %c
   %2 = getelementptr i8, ptr %a, i64 %b
@@ -483,8 +477,7 @@ define void @surb(ptr %a, i32 %b, i8 %c) {
 ; RV32IZBAXQCISLS-LABEL: surb:
 ; RV32IZBAXQCISLS:       # %bb.0:
 ; RV32IZBAXQCISLS-NEXT:    add a2, a2, a2
-; RV32IZBAXQCISLS-NEXT:    add a0, a0, a1
-; RV32IZBAXQCISLS-NEXT:    sb a2, 0(a0)
+; RV32IZBAXQCISLS-NEXT:    qc.srb a2, a0, a1, 0
 ; RV32IZBAXQCISLS-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = add i8 %c, %c
@@ -512,10 +505,10 @@ define i64 @lrd_large_shift(ptr %a, i64 %b) {
 ;
 ; RV32IZBAXQCISLS-LABEL: lrd_large_shift:
 ; RV32IZBAXQCISLS:       # %bb.0:
-; RV32IZBAXQCISLS-NEXT:    slli a1, a1, 5
-; RV32IZBAXQCISLS-NEXT:    add a1, a1, a0
-; RV32IZBAXQCISLS-NEXT:    lw a0, 384(a1)
-; RV32IZBAXQCISLS-NEXT:    lw a1, 388(a1)
+; RV32IZBAXQCISLS-NEXT:    addi a2, a0, 384
+; RV32IZBAXQCISLS-NEXT:    addi a3, a0, 388
+; RV32IZBAXQCISLS-NEXT:    qc.lrw a0, a2, a1, 5
+; RV32IZBAXQCISLS-NEXT:    qc.lrw a1, a3, a1, 5
 ; RV32IZBAXQCISLS-NEXT:    ret
   %1 = add i64 %b, 12
   %2 = shl i64 %1, 2



More information about the llvm-commits mailing list