[llvm] 30705e9 - [RISCV] Support Zfa fli instructions with vector splats.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 10 09:16:39 PST 2023
Author: Craig Topper
Date: 2023-03-10T09:16:21-08:00
New Revision: 30705e977061e437a337070fd6a21c7df2c62670
URL: https://github.com/llvm/llvm-project/commit/30705e977061e437a337070fd6a21c7df2c62670
DIFF: https://github.com/llvm/llvm-project/commit/30705e977061e437a337070fd6a21c7df2c62670.diff
LOG: [RISCV] Support Zfa fli instructions with vector splats.
-Return false from RISCVDAGToDAGISel::selectFPImm for fli
constants so we don't try to use integer expansion.
-Support fli.h with Zvfh+Zfhmin.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D145766
Added:
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index a0ac5dd3349b6..f397ef12913db 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -842,16 +842,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
}
case ISD::ConstantFP: {
const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
- if (Subtarget->hasStdExtZfa()) {
- // fli.h requires Zfh, but we might only have Zfhmin.
- if (VT == MVT::f16 && Subtarget->hasStdExtZfh() &&
- RISCVLoadFPImm::getLoadFP16Imm(APF) != -1)
- break;
- if (VT == MVT::f32 && RISCVLoadFPImm::getLoadFP32Imm(APF) != -1)
- break;
- if (VT == MVT::f64 && RISCVLoadFPImm::getLoadFP64Imm(APF) != -1)
- break;
- }
+ if (static_cast<const RISCVTargetLowering *>(TLI)->isLegalZfaFPImm(APF, VT))
+ break;
bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
SDValue Imm;
@@ -2972,8 +2964,14 @@ bool RISCVDAGToDAGISel::selectFPImm(SDValue N, SDValue &Imm) {
// td can handle +0.0 already.
if (APF.isPosZero())
return false;
+
+ MVT VT = CFP->getSimpleValueType(0);
+
+ if (static_cast<const RISCVTargetLowering *>(TLI)->isLegalZfaFPImm(APF, VT))
+ return false;
+
MVT XLenVT = Subtarget->getXLenVT();
- if (CFP->getValueType(0) == MVT::f64 && !Subtarget->is64Bit()) {
+ if (VT == MVT::f64 && !Subtarget->is64Bit()) {
assert(APF.isNegZero() && "Unexpected constant.");
return false;
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 8ac5934c89623..95009ca9cd144 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1538,6 +1538,24 @@ bool RISCVTargetLowering::isOffsetFoldingLegal(
return false;
}
+bool RISCVTargetLowering::isLegalZfaFPImm(const APFloat &Imm, EVT VT) const {
+ if (!Subtarget.hasStdExtZfa() || !VT.isSimple())
+ return false;
+
+ switch (VT.getSimpleVT().SimpleTy) {
+ default:
+ return false;
+ case MVT::f16:
+ return (Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh()) &&
+ RISCVLoadFPImm::getLoadFP16Imm(Imm) != -1;
+ case MVT::f32:
+ return RISCVLoadFPImm::getLoadFP32Imm(Imm) != -1;
+ case MVT::f64:
+ assert(Subtarget.hasStdExtD() && "Expect D extension");
+ return RISCVLoadFPImm::getLoadFP64Imm(Imm) != -1;
+ }
+}
+
bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
if (VT == MVT::f16 && !Subtarget.hasStdExtZfhOrZfhmin())
@@ -1547,16 +1565,8 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
if (VT == MVT::f64 && !Subtarget.hasStdExtD())
return false;
- if (Subtarget.hasStdExtZfa()) {
- // fli.h requires Zfh, but we might only have Zfhmin.
- if (VT == MVT::f16 && Subtarget.hasStdExtZfh() &&
- RISCVLoadFPImm::getLoadFP16Imm(Imm) != -1)
- return true;
- if (VT == MVT::f32 && RISCVLoadFPImm::getLoadFP32Imm(Imm) != -1)
- return true;
- if (VT == MVT::f64 && RISCVLoadFPImm::getLoadFP64Imm(Imm) != -1)
- return true;
- }
+ if (isLegalZfaFPImm(Imm, VT))
+ return true;
// Cannot create a 64 bit floating-point immediate value for rv32.
if (Subtarget.getXLen() < VT.getScalarSizeInBits()) {
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 171e13a62a0ae..7018b2a81a555 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -389,6 +389,7 @@ class RISCVTargetLowering : public TargetLowering {
SmallVectorImpl<Use *> &Ops) const override;
bool shouldScalarizeBinop(SDValue VecOp) const override;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
+ bool isLegalZfaFPImm(const APFloat &Imm, EVT VT) const;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;
bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
new file mode 100644
index 0000000000000..e4ae59e012026
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+zfh,+experimental-zfa,+experimental-zvfh,+v -target-abi ilp32d -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK
+; RUN: llc -mtriple=riscv64 -mattr=+zfh,+experimental-zfa,+experimental-zvfh,+v -target-abi lp64d -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK
+
+define <vscale x 8 x half> @vsplat_f16_0p625() {
+; CHECK-LABEL: vsplat_f16_0p625:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h ft0, 0.625
+; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, ma
+; CHECK-NEXT: vfmv.v.f v8, ft0
+; CHECK-NEXT: ret
+ %head = insertelement <vscale x 8 x half> poison, half 0.625, i32 0
+ %splat = shufflevector <vscale x 8 x half> %head, <vscale x 8 x half> poison, <vscale x 8 x i32> zeroinitializer
+ ret <vscale x 8 x half> %splat
+}
+
+define <vscale x 8 x float> @vsplat_f32_0p75() {
+; CHECK-LABEL: vsplat_f32_0p75:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s ft0, 0.75
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfmv.v.f v8, ft0
+; CHECK-NEXT: ret
+ %head = insertelement <vscale x 8 x float> poison, float 0.75, i32 0
+ %splat = shufflevector <vscale x 8 x float> %head, <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer
+ ret <vscale x 8 x float> %splat
+}
+
+define <vscale x 8 x double> @vsplat_f64_neg1() {
+; CHECK-LABEL: vsplat_f64_neg1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d ft0, -1.0
+; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma
+; CHECK-NEXT: vfmv.v.f v8, ft0
+; CHECK-NEXT: ret
+ %head = insertelement <vscale x 8 x double> poison, double -1.0, i32 0
+ %splat = shufflevector <vscale x 8 x double> %head, <vscale x 8 x double> poison, <vscale x 8 x i32> zeroinitializer
+ ret <vscale x 8 x double> %splat
+}
More information about the llvm-commits
mailing list