[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