From b50c6857a45b8fa753bde44efcea7d0000c55ac5 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 21 Mar 2023 19:15:30 -0700 Subject: [PATCH] [RISCV] Move fli selection in RISCVISelDAGToDAG.cpp. NFC We custom isel for ConstantFP that has higher priority than isel patterns. We were previously detecting valid FP constants for fli to early exit from the custom code. This detection called getLoadFPImm. Then we would run the isel patterns which would call getLoadFPImm a second time. With a little bit more code we can directly select the fli instruction in the custom handler and avoid a second call. Remove the incorrect mayRaiseFPException flag from the FLI instructions. Reviewed By: joshua-arch1 Differential Revision: https://reviews.llvm.org/D146093 --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 28 ++++++++++++++++++--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 13 +++++++--- llvm/lib/Target/RISCV/RISCVISelLowering.h | 2 +- llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td | 13 +--------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index f397ef12913d..fbdcbbfd5a19 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -842,8 +842,29 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { } case ISD::ConstantFP: { const APFloat &APF = cast(Node)->getValueAPF(); - if (static_cast(TLI)->isLegalZfaFPImm(APF, VT)) - break; + int FPImm = static_cast(TLI)->getLegalZfaFPImm( + APF, VT); + if (FPImm >= 0) { + unsigned Opc; + switch (VT.SimpleTy) { + default: + llvm_unreachable("Unexpected size"); + case MVT::f16: + Opc = RISCV::FLI_H; + break; + case MVT::f32: + Opc = RISCV::FLI_S; + break; + case MVT::f64: + Opc = RISCV::FLI_D; + break; + } + + SDNode *Res = CurDAG->getMachineNode( + Opc, DL, VT, CurDAG->getTargetConstant(FPImm, DL, XLenVT)); + ReplaceNode(Node, Res); + return; + } bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64; SDValue Imm; @@ -2967,7 +2988,8 @@ bool RISCVDAGToDAGISel::selectFPImm(SDValue N, SDValue &Imm) { MVT VT = CFP->getSimpleValueType(0); - if (static_cast(TLI)->isLegalZfaFPImm(APF, VT)) + if (static_cast(TLI)->getLegalZfaFPImm(APF, + VT) >= 0) return false; MVT XLenVT = Subtarget->getXLenVT(); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index e56a2b3b08b5..595e094662f9 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -1545,9 +1545,11 @@ bool RISCVTargetLowering::isOffsetFoldingLegal( return false; } -bool RISCVTargetLowering::isLegalZfaFPImm(const APFloat &Imm, EVT VT) const { +// Returns 0-31 if the fli instruction is available for the type and this is +// legal FP immediate for the type. Returns -1 otherwise. +int RISCVTargetLowering::getLegalZfaFPImm(const APFloat &Imm, EVT VT) const { if (!Subtarget.hasStdExtZfa()) - return false; + return -1; bool IsSupportedVT = false; if (VT == MVT::f16) { @@ -1559,7 +1561,10 @@ bool RISCVTargetLowering::isLegalZfaFPImm(const APFloat &Imm, EVT VT) const { IsSupportedVT = true; } - return IsSupportedVT && RISCVLoadFPImm::getLoadFPImm(Imm) != -1; + if (!IsSupportedVT) + return -1; + + return RISCVLoadFPImm::getLoadFPImm(Imm); } bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, @@ -1575,7 +1580,7 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, if (!IsLegalVT) return false; - if (isLegalZfaFPImm(Imm, VT)) + if (getLegalZfaFPImm(Imm, VT) >= 0) return true; // Cannot create a 64 bit floating-point immediate value for rv32. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index b3a202476751..19aaebc92ba6 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -393,7 +393,7 @@ public: SmallVectorImpl &Ops) const override; bool shouldScalarizeBinop(SDValue VecOp) const override; bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; - bool isLegalZfaFPImm(const APFloat &Imm, EVT VT) const; + int getLegalZfaFPImm(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/lib/Target/RISCV/RISCVInstrInfoZfa.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td index 28348b14a5ef..751a0eabbd39 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td @@ -63,7 +63,7 @@ class FPBinaryOp_rr funct7, bits<3> funct3, DAGOperand rdty, : RVInstR; -let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPUnaryOp_imm funct7, bits<5> rs2val, bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst { @@ -182,14 +182,7 @@ def : InstAlias<"fgeq.h $rd, $rs, $rt", // Codegen patterns //===----------------------------------------------------------------------===// -def fpimm_to_loadfpimm : SDNodeXFormgetTargetConstant(RISCVLoadFPImm::getLoadFPImm(N->getValueAPF()), - SDLoc(N), Subtarget->getXLenVT());}]>; - - let Predicates = [HasStdExtZfa] in { -def : Pat<(f32 fpimm:$imm), (FLI_S (fpimm_to_loadfpimm fpimm:$imm))>; - def: PatFprFpr; def: PatFprFpr; @@ -212,8 +205,6 @@ def: PatSetCC; } // Predicates = [HasStdExtZfa] let Predicates = [HasStdExtZfa, HasStdExtD] in { -def : Pat<(f64 fpimm:$imm), (FLI_D (fpimm_to_loadfpimm fpimm:$imm))>; - def: PatFprFpr; def: PatFprFpr; @@ -242,8 +233,6 @@ def : Pat<(RISCVBuildPairF64 GPR:$rs1, GPR:$rs2), } let Predicates = [HasStdExtZfa, HasStdExtZfh] in { -def : Pat<(f16 fpimm:$imm), (FLI_H (fpimm_to_loadfpimm fpimm:$imm))>; - def: PatFprFpr; def: PatFprFpr;