[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
This commit is contained in:
Craig Topper 2023-03-21 19:15:30 -07:00
parent 4dc04557d7
commit b50c6857a4
4 changed files with 36 additions and 20 deletions

View File

@ -842,8 +842,29 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
}
case ISD::ConstantFP: {
const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
if (static_cast<const RISCVTargetLowering *>(TLI)->isLegalZfaFPImm(APF, VT))
break;
int FPImm = static_cast<const RISCVTargetLowering *>(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<const RISCVTargetLowering *>(TLI)->isLegalZfaFPImm(APF, VT))
if (static_cast<const RISCVTargetLowering *>(TLI)->getLegalZfaFPImm(APF,
VT) >= 0)
return false;
MVT XLenVT = Subtarget->getXLenVT();

View File

@ -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.

View File

@ -393,7 +393,7 @@ public:
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;
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,

View File

@ -63,7 +63,7 @@ class FPBinaryOp_rr<bits<7> funct7, bits<3> funct3, DAGOperand rdty,
: RVInstR<funct7, funct3, OPC_OP_FP, (outs rdty:$rd),
(ins rsty:$rs1, rsty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class FPUnaryOp_imm<bits<7> funct7, bits<5> rs2val, bits<3> funct3, RISCVOpcode opcode,
dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
@ -182,14 +182,7 @@ def : InstAlias<"fgeq.h $rd, $rs, $rt",
// Codegen patterns
//===----------------------------------------------------------------------===//
def fpimm_to_loadfpimm : SDNodeXForm<fpimm, [{
return CurDAG->getTargetConstant(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<fminimum, FMINM_S, FPR32>;
def: PatFprFpr<fmaximum, FMAXM_S, FPR32>;
@ -212,8 +205,6 @@ def: PatSetCC<FPR32, strict_fsetcc, SETOLE, FLEQ_S>;
} // Predicates = [HasStdExtZfa]
let Predicates = [HasStdExtZfa, HasStdExtD] in {
def : Pat<(f64 fpimm:$imm), (FLI_D (fpimm_to_loadfpimm fpimm:$imm))>;
def: PatFprFpr<fminimum, FMINM_D, FPR64>;
def: PatFprFpr<fmaximum, FMAXM_D, FPR64>;
@ -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<fminimum, FMINM_H, FPR16>;
def: PatFprFpr<fmaximum, FMAXM_H, FPR16>;