[llvm] ada2641 - [RISCV][CodeGen] Add codegen pattern for FLI instruction in experimental zfa extension
Jun Sha via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 6 22:27:47 PST 2023
Author: Jun Sha (Joshua)
Date: 2023-03-07T14:27:48+08:00
New Revision: ada2641460672ed888df9e2791d3d4635f06e2ae
URL: https://github.com/llvm/llvm-project/commit/ada2641460672ed888df9e2791d3d4635f06e2ae
DIFF: https://github.com/llvm/llvm-project/commit/ada2641460672ed888df9e2791d3d4635f06e2ae.diff
LOG: [RISCV][CodeGen] Add codegen pattern for FLI instruction in experimental zfa extension
This patch implements experimental support for the RISCV Zfa extension as specified here: https://github.com/riscv/riscv-isa-manual/releases/download/draft-20221119-5234c63/riscv-spec.pdf, Ch. 25. This extension has not been ratified. Once ratified, it'll move out of experimental status.
This change adds codegen support for load-immediate instructions (fli.s/fli.d/fli.h).
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D141560
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td
llvm/test/CodeGen/RISCV/double-zfa.ll
llvm/test/CodeGen/RISCV/float-zfa.ll
llvm/test/CodeGen/RISCV/half-zfa.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index ca63794db7b6e..91ef4f58d274e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -842,6 +842,14 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
}
case ISD::ConstantFP: {
const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
+ if (Subtarget->hasStdExtZfa()) {
+ if ((VT == MVT::f64 && RISCVLoadFPImm::getLoadFP64Imm(APF) != -1) ||
+ (VT == MVT::f16 && RISCVLoadFPImm::getLoadFP16Imm(APF) != -1) ||
+ (VT == MVT::f32 && RISCVLoadFPImm::getLoadFP32Imm(APF) != -1 &&
+ !APF.isPosZero()))
+ break;
+ }
+
bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
SDValue Imm;
// For +0.0 or f64 -0.0 we need to start from X0. For all others, we will
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 6b93d53d7dbf3..c8047cd09cadd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1518,6 +1518,14 @@ bool RISCVTargetLowering::isOffsetFoldingLegal(
bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
+ if (Subtarget.hasStdExtZfa()) {
+ if ((VT == MVT::f64 && RISCVLoadFPImm::getLoadFP64Imm(Imm) != -1) ||
+ (VT == MVT::f16 && RISCVLoadFPImm::getLoadFP16Imm(Imm) != -1) ||
+ (VT == MVT::f32 && RISCVLoadFPImm::getLoadFP32Imm(Imm) != -1 &&
+ !Imm.isPosZero()))
+ return true;
+ }
+
if (VT == MVT::f16 && !Subtarget.hasStdExtZfhOrZfhmin())
return false;
if (VT == MVT::f32 && !Subtarget.hasStdExtF())
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td
index c39b7f543f472..2b37a8df4d54c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td
@@ -178,7 +178,21 @@ def : InstAlias<"fgeq.h $rd, $rs, $rt",
// Codegen patterns
//===----------------------------------------------------------------------===//
+def fp32imm_to_loadfpimm : SDNodeXForm<fpimm, [{
+ return CurDAG->getTargetConstant(RISCVLoadFPImm::getLoadFP32Imm(N->getValueAPF()),
+ SDLoc(N), Subtarget->getXLenVT());}]>;
+
+def fp64imm_to_loadfpimm : SDNodeXForm<fpimm, [{
+ return CurDAG->getTargetConstant(RISCVLoadFPImm::getLoadFP64Imm(N->getValueAPF()),
+ SDLoc(N), Subtarget->getXLenVT());}]>;
+
+def fp16imm_to_loadfpimm : SDNodeXForm<fpimm, [{
+ return CurDAG->getTargetConstant(RISCVLoadFPImm::getLoadFP16Imm(N->getValueAPF()),
+ SDLoc(N), Subtarget->getXLenVT());}]>;
+
let Predicates = [HasStdExtZfa] in {
+def : Pat<(f32 fpimm:$imm), (FLI_S (fp32imm_to_loadfpimm fpimm:$imm))>;
+
def: PatFprFpr<fminimum, FMINM_S, FPR32>;
def: PatFprFpr<fmaximum, FMAXM_S, FPR32>;
@@ -201,6 +215,8 @@ def: PatSetCC<FPR32, strict_fsetcc, SETOLE, FLEQ_S>;
} // Predicates = [HasStdExtZfa]
let Predicates = [HasStdExtZfa, HasStdExtD] in {
+def : Pat<(f64 fpimm:$imm), (FLI_D (fp64imm_to_loadfpimm fpimm:$imm))>;
+
def: PatFprFpr<fminimum, FMINM_D, FPR64>;
def: PatFprFpr<fmaximum, FMAXM_D, FPR64>;
@@ -229,6 +245,8 @@ def : Pat<(RISCVBuildPairF64 GPR:$rs1, GPR:$rs2),
}
let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
+def : Pat<(f16 fpimm:$imm), (FLI_H (fp16imm_to_loadfpimm fpimm:$imm))>;
+
def: PatFprFpr<fminimum, FMINM_H, FPR16>;
def: PatFprFpr<fmaximum, FMAXM_H, FPR16>;
diff --git a/llvm/test/CodeGen/RISCV/double-zfa.ll b/llvm/test/CodeGen/RISCV/double-zfa.ll
index a4550cde2d67c..8bbe5e59ccbbc 100644
--- a/llvm/test/CodeGen/RISCV/double-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/double-zfa.ll
@@ -4,6 +4,79 @@
; RUN: llc -mtriple=riscv64 -target-abi lp64d -mattr=+experimental-zfa,+d < %s \
; RUN: | FileCheck --check-prefixes=CHECK,RV64DZFA %s
+define double @loadfpimm1() {
+; CHECK-LABEL: loadfpimm1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, 6.250000e-02
+; CHECK-NEXT: ret
+ ret double 0.0625
+}
+
+define double @loadfpimm2() {
+; CHECK-LABEL: loadfpimm2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, 7.500000e-01
+; CHECK-NEXT: ret
+ ret double 0.75
+}
+
+define double @loadfpimm3() {
+; CHECK-LABEL: loadfpimm3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, 1.250000e+00
+; CHECK-NEXT: ret
+ ret double 1.25
+}
+
+define double @loadfpimm4() {
+; CHECK-LABEL: loadfpimm4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, 3.000000e+00
+; CHECK-NEXT: ret
+ ret double 3.0
+}
+
+define double @loadfpimm5() {
+; CHECK-LABEL: loadfpimm5:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, 2.560000e+02
+; CHECK-NEXT: ret
+ ret double 256.0
+}
+
+define double @loadfpimm6() {
+; CHECK-LABEL: loadfpimm6:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, inf
+; CHECK-NEXT: ret
+ ret double 0x7FF0000000000000
+}
+
+define double @loadfpimm7() {
+; CHECK-LABEL: loadfpimm7:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, nan
+; CHECK-NEXT: ret
+ ret double 0x7FF8000000000000
+}
+
+define double @loadfpimm8() {
+; CHECK-LABEL: loadfpimm8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.d fa0, min
+; CHECK-NEXT: ret
+ ret double 0x0010000000000000
+}
+
+define double @loadfpimm9() {
+; CHECK-LABEL: loadfpimm9:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lui a0, %hi(.LCPI8_0)
+; CHECK-NEXT: fld fa0, %lo(.LCPI8_0)(a0)
+; CHECK-NEXT: ret
+ ret double 255.0
+}
+
declare double @llvm.minimum.f64(double, double)
define double @fminm_d(double %a, double %b) nounwind {
diff --git a/llvm/test/CodeGen/RISCV/float-zfa.ll b/llvm/test/CodeGen/RISCV/float-zfa.ll
index 2b47399e75278..fe8359d61a747 100644
--- a/llvm/test/CodeGen/RISCV/float-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/float-zfa.ll
@@ -4,6 +4,79 @@
; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+experimental-zfa < %s \
; RUN: | FileCheck %s
+define float @loadfpimm1() {
+; CHECK-LABEL: loadfpimm1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, 6.250000e-02
+; CHECK-NEXT: ret
+ ret float 0.0625
+}
+
+define float @loadfpimm2() {
+; CHECK-LABEL: loadfpimm2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, 7.500000e-01
+; CHECK-NEXT: ret
+ ret float 0.75
+}
+
+define float @loadfpimm3() {
+; CHECK-LABEL: loadfpimm3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, 1.250000e+00
+; CHECK-NEXT: ret
+ ret float 1.25
+}
+
+define float @loadfpimm4() {
+; CHECK-LABEL: loadfpimm4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, 3.000000e+00
+; CHECK-NEXT: ret
+ ret float 3.0
+}
+
+define float @loadfpimm5() {
+; CHECK-LABEL: loadfpimm5:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, 2.560000e+02
+; CHECK-NEXT: ret
+ ret float 256.0
+}
+
+define float @loadfpimm6() {
+; CHECK-LABEL: loadfpimm6:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, inf
+; CHECK-NEXT: ret
+ ret float 0x7FF0000000000000
+}
+
+define float @loadfpimm7() {
+; CHECK-LABEL: loadfpimm7:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, nan
+; CHECK-NEXT: ret
+ ret float 0x7FF8000000000000
+}
+
+define float @loadfpimm8() {
+; CHECK-LABEL: loadfpimm8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa0, min
+; CHECK-NEXT: ret
+ ret float 0x3810000000000000
+}
+
+define float @loadfpimm9() {
+; CHECK-LABEL: loadfpimm9:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lui a0, 276464
+; CHECK-NEXT: fmv.w.x fa0, a0
+; CHECK-NEXT: ret
+ ret float 255.0
+}
+
declare float @llvm.minimum.f32(float, float)
define float @fminm_s(float %a, float %b) nounwind {
diff --git a/llvm/test/CodeGen/RISCV/half-zfa.ll b/llvm/test/CodeGen/RISCV/half-zfa.ll
index 798977e540047..b6ff3fbae415c 100644
--- a/llvm/test/CodeGen/RISCV/half-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/half-zfa.ll
@@ -4,6 +4,79 @@
; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+experimental-zfa,+zfh < %s \
; RUN: | FileCheck %s
+define half @loadfpimm1() {
+; CHECK-LABEL: loadfpimm1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, 6.250000e-02
+; CHECK-NEXT: ret
+ ret half 0.0625
+}
+
+define half @loadfpimm2() {
+; CHECK-LABEL: loadfpimm2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, 7.500000e-01
+; CHECK-NEXT: ret
+ ret half 0.75
+}
+
+define half @loadfpimm3() {
+; CHECK-LABEL: loadfpimm3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, 1.250000e+00
+; CHECK-NEXT: ret
+ ret half 1.25
+}
+
+define half @loadfpimm4() {
+; CHECK-LABEL: loadfpimm4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, 3.000000e+00
+; CHECK-NEXT: ret
+ ret half 3.0
+}
+
+define half @loadfpimm5() {
+; CHECK-LABEL: loadfpimm5:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, 2.560000e+02
+; CHECK-NEXT: ret
+ ret half 256.0
+}
+
+define half @loadfpimm6() {
+; CHECK-LABEL: loadfpimm6:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, inf
+; CHECK-NEXT: ret
+ ret half 0xH7C00
+}
+
+define half @loadfpimm7() {
+; CHECK-LABEL: loadfpimm7:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, nan
+; CHECK-NEXT: ret
+ ret half 0xH7E00
+}
+
+define half @loadfpimm8() {
+; CHECK-LABEL: loadfpimm8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.h fa0, min
+; CHECK-NEXT: ret
+ ret half 0xH0400
+}
+
+define half @loadfpimm9() {
+; CHECK-LABEL: loadfpimm9:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lui a0, %hi(.LCPI8_0)
+; CHECK-NEXT: flh fa0, %lo(.LCPI8_0)(a0)
+; CHECK-NEXT: ret
+ ret half 255.0
+}
+
declare half @llvm.minimum.f16(half, half)
define half @fminm_h(half %a, half %b) nounwind {
More information about the llvm-commits
mailing list