[llvm] e1b3af6 - [RISCV] Add isel patterns to use Zilsd for f64 load/store for Zdinx on RV32. (#139935)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 14 12:19:42 PDT 2025


Author: Craig Topper
Date: 2025-05-14T12:19:38-07:00
New Revision: e1b3af6dc4362c5281abf255c4078992ce64ad33

URL: https://github.com/llvm/llvm-project/commit/e1b3af6dc4362c5281abf255c4078992ce64ad33
DIFF: https://github.com/llvm/llvm-project/commit/e1b3af6dc4362c5281abf255c4078992ce64ad33.diff

LOG: [RISCV] Add isel patterns to use Zilsd for f64 load/store for Zdinx on RV32. (#139935)

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVFeatures.td
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/lib/Target/RISCV/RISCVInstrInfoD.td
    llvm/test/CodeGen/RISCV/double-mem.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index daae4e88a38e2..76a238d2b523f 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -187,6 +187,7 @@ def FeatureStdExtZilsd
 def HasStdExtZilsd : Predicate<"Subtarget->hasStdExtZilsd()">,
                        AssemblerPredicate<(all_of FeatureStdExtZilsd),
                                           "'Zilsd' (Load/Store pair instructions)">;
+def NoHasStdExtZilsd : Predicate<"!Subtarget->hasStdExtZilsd()">;
 
 // Multiply Extensions
 

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index e9bdeb88e4ca8..1089072eea6e3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2210,6 +2210,13 @@ include "RISCVInstrInfoA.td"
 include "RISCVInstrInfoZa.td"
 include "RISCVInstrInfoZalasr.td"
 
+// Integer
+include "RISCVInstrInfoZimop.td"
+include "RISCVInstrInfoZicbo.td"
+include "RISCVInstrInfoZicond.td"
+include "RISCVInstrInfoZicfiss.td"
+include "RISCVInstrInfoZilsd.td"
+
 // Scalar FP
 include "RISCVInstrInfoF.td"
 include "RISCVInstrInfoD.td"
@@ -2226,13 +2233,6 @@ include "RISCVInstrInfoV.td"
 include "RISCVInstrInfoZvk.td"
 include "RISCVInstrInfoZvqdotq.td"
 
-// Integer
-include "RISCVInstrInfoZimop.td"
-include "RISCVInstrInfoZicbo.td"
-include "RISCVInstrInfoZicond.td"
-include "RISCVInstrInfoZicfiss.td"
-include "RISCVInstrInfoZilsd.td"
-
 // Compressed
 include "RISCVInstrInfoC.td"
 include "RISCVInstrInfoZc.td"

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index 0c584daf45b14..c947252c466f2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -531,15 +531,23 @@ def PseudoFROUND_D_IN32X : PseudoFROUND<FPR64IN32X, f64>;
 /// Loads
 let isCall = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 1 in
 def PseudoRV32ZdinxLD : Pseudo<(outs GPRPair:$dst), (ins GPR:$rs1, simm12:$imm12), []>;
-def : Pat<(f64 (load (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12))),
-          (PseudoRV32ZdinxLD GPR:$rs1, simm12:$imm12)>;
 
 /// Stores
 let isCall = 0, mayLoad = 0, mayStore = 1, Size = 8, isCodeGenOnly = 1 in
 def PseudoRV32ZdinxSD : Pseudo<(outs), (ins GPRPair:$rs2, GPRNoX0:$rs1, simm12:$imm12), []>;
+} // Predicates = [HasStdExtZdinx, IsRV32]
+
+let Predicates = [HasStdExtZdinx, NoHasStdExtZilsd, IsRV32] in {
+def : Pat<(f64 (load (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12))),
+          (PseudoRV32ZdinxLD GPR:$rs1, simm12:$imm12)>;
 def : Pat<(store (f64 GPRPair:$rs2), (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12)),
           (PseudoRV32ZdinxSD GPRPair:$rs2, GPR:$rs1, simm12:$imm12)>;
-} // Predicates = [HasStdExtZdinx, IsRV32]
+}
+
+let Predicates = [HasStdExtZdinx, HasStdExtZilsd, IsRV32] in {
+def : LdPat<load, LD_RV32, f64>;
+def : StPat<store, SD_RV32, GPRPair, f64>;
+}
 
 let Predicates = [HasStdExtD, IsRV32] in {
 

diff  --git a/llvm/test/CodeGen/RISCV/double-mem.ll b/llvm/test/CodeGen/RISCV/double-mem.ll
index dba9489e7511d..b14994dc78ba7 100644
--- a/llvm/test/CodeGen/RISCV/double-mem.ll
+++ b/llvm/test/CodeGen/RISCV/double-mem.ll
@@ -7,6 +7,8 @@
 ; RUN:   -target-abi=ilp32 | FileCheck -check-prefixes=RV32IZFINXZDINX %s
 ; RUN: llc -mtriple=riscv64 -mattr=+zdinx -verify-machineinstrs < %s \
 ; RUN:   -target-abi=lp64 | FileCheck -check-prefixes=RV64IZFINXZDINX %s
+; RUN: llc -mtriple=riscv32 -mattr=+zdinx,+zilsd -verify-machineinstrs < %s \
+; RUN:   -target-abi=ilp32 | FileCheck -check-prefixes=RV32IZFINXZDINXZILSD %s
 
 define dso_local double @fld(ptr %a) nounwind {
 ; CHECKIFD-LABEL: fld:
@@ -31,6 +33,13 @@ define dso_local double @fld(ptr %a) nounwind {
 ; RV64IZFINXZDINX-NEXT:    ld a0, 24(a0)
 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a1, a0
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fld:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    ld a2, 0(a0)
+; RV32IZFINXZDINXZILSD-NEXT:    ld a0, 24(a0)
+; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a0, a2, a0
+; RV32IZFINXZDINXZILSD-NEXT:    ret
   %1 = load double, ptr %a
   %2 = getelementptr double, ptr %a, i32 3
   %3 = load double, ptr %2
@@ -67,6 +76,17 @@ define dso_local void @fsd(ptr %a, double %b, double %c) nounwind {
 ; RV64IZFINXZDINX-NEXT:    sd a1, 0(a0)
 ; RV64IZFINXZDINX-NEXT:    sd a1, 64(a0)
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fsd:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    mv a5, a4
+; RV32IZFINXZDINXZILSD-NEXT:    mv a7, a2
+; RV32IZFINXZDINXZILSD-NEXT:    mv a4, a3
+; RV32IZFINXZDINXZILSD-NEXT:    mv a6, a1
+; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a2, a6, a4
+; RV32IZFINXZDINXZILSD-NEXT:    sd a2, 0(a0)
+; RV32IZFINXZDINXZILSD-NEXT:    sd a2, 64(a0)
+; RV32IZFINXZDINXZILSD-NEXT:    ret
 ; Use %b and %c in an FP op to ensure floating point registers are used, even
 ; for the soft float ABI
   %1 = fadd double %b, %c
@@ -116,6 +136,17 @@ define dso_local double @fld_fsd_global(double %a, double %b) nounwind {
 ; RV64IZFINXZDINX-NEXT:    ld zero, 72(a2)
 ; RV64IZFINXZDINX-NEXT:    sd a0, 72(a2)
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fld_fsd_global:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    lui a4, %hi(G)
+; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a0, a0, a2
+; RV32IZFINXZDINXZILSD-NEXT:    ld a2, %lo(G)(a4)
+; RV32IZFINXZDINXZILSD-NEXT:    addi a2, a4, %lo(G)
+; RV32IZFINXZDINXZILSD-NEXT:    sd a0, %lo(G)(a4)
+; RV32IZFINXZDINXZILSD-NEXT:    ld a4, 72(a2)
+; RV32IZFINXZDINXZILSD-NEXT:    sd a0, 72(a2)
+; RV32IZFINXZDINXZILSD-NEXT:    ret
 ; Use %a and %b in an FP op to ensure floating point registers are used, even
 ; for the soft float ABI
   %1 = fadd double %a, %b
@@ -164,6 +195,14 @@ define dso_local double @fld_fsd_constant(double %a) nounwind {
 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, a2
 ; RV64IZFINXZDINX-NEXT:    sd a0, -273(a1)
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fld_fsd_constant:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    lui a2, 912092
+; RV32IZFINXZDINXZILSD-NEXT:    ld a4, -273(a2)
+; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a0, a0, a4
+; RV32IZFINXZDINXZILSD-NEXT:    sd a0, -273(a2)
+; RV32IZFINXZDINXZILSD-NEXT:    ret
   %1 = inttoptr i32 3735928559 to ptr
   %2 = load volatile double, ptr %1
   %3 = fadd double %a, %2
@@ -237,6 +276,24 @@ define dso_local double @fld_stack(double %a) nounwind {
 ; RV64IZFINXZDINX-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
 ; RV64IZFINXZDINX-NEXT:    addi sp, sp, 32
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fld_stack:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    addi sp, sp, -32
+; RV32IZFINXZDINXZILSD-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINXZILSD-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINXZILSD-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINXZILSD-NEXT:    mv s1, a1
+; RV32IZFINXZDINXZILSD-NEXT:    mv s0, a0
+; RV32IZFINXZDINXZILSD-NEXT:    addi a0, sp, 8
+; RV32IZFINXZDINXZILSD-NEXT:    call notdead
+; RV32IZFINXZDINXZILSD-NEXT:    ld a0, 8(sp)
+; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a0, a0, s0
+; RV32IZFINXZDINXZILSD-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINXZILSD-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINXZILSD-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINXZILSD-NEXT:    addi sp, sp, 32
+; RV32IZFINXZDINXZILSD-NEXT:    ret
   %1 = alloca double, align 8
   call void @notdead(ptr %1)
   %2 = load double, ptr %1
@@ -293,6 +350,18 @@ define dso_local void @fsd_stack(double %a, double %b) nounwind {
 ; RV64IZFINXZDINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IZFINXZDINX-NEXT:    addi sp, sp, 16
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fsd_stack:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    addi sp, sp, -16
+; RV32IZFINXZDINXZILSD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINXZILSD-NEXT:    fadd.d a0, a0, a2
+; RV32IZFINXZDINXZILSD-NEXT:    sd a0, 0(sp)
+; RV32IZFINXZDINXZILSD-NEXT:    mv a0, sp
+; RV32IZFINXZDINXZILSD-NEXT:    call notdead
+; RV32IZFINXZDINXZILSD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINXZILSD-NEXT:    addi sp, sp, 16
+; RV32IZFINXZDINXZILSD-NEXT:    ret
   %1 = fadd double %a, %b ; force store from FPR64
   %2 = alloca double, align 8
   store double %1, ptr %2
@@ -321,6 +390,14 @@ define dso_local void @fsd_trunc(ptr %a, double %b) nounwind noinline optnone {
 ; RV64IZFINXZDINX-NEXT:    fcvt.s.d a1, a1
 ; RV64IZFINXZDINX-NEXT:    sw a1, 0(a0)
 ; RV64IZFINXZDINX-NEXT:    ret
+;
+; RV32IZFINXZDINXZILSD-LABEL: fsd_trunc:
+; RV32IZFINXZDINXZILSD:       # %bb.0:
+; RV32IZFINXZDINXZILSD-NEXT:    mv a3, a2
+; RV32IZFINXZDINXZILSD-NEXT:    mv a2, a1
+; RV32IZFINXZDINXZILSD-NEXT:    fcvt.s.d a1, a2
+; RV32IZFINXZDINXZILSD-NEXT:    sw a1, 0(a0)
+; RV32IZFINXZDINXZILSD-NEXT:    ret
   %1 = fptrunc double %b to float
   store float %1, ptr %a, align 4
   ret void


        


More information about the llvm-commits mailing list