[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