diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-25 13:49:57 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-25 13:49:57 +0000 |
| commit | 99aabd70801bd4bc72c4942747f6d62c675112f5 (patch) | |
| tree | 02bf056e9098f5ecddc7f18a99db9c79f4404b02 /llvm/lib/Target/RISCV/RISCVISelLowering.cpp | |
| parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) | |
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 182 |
1 files changed, 148 insertions, 34 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 03e994586d0c..c2508a158837 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -122,7 +122,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, if (Subtarget.is64Bit() && RV64LegalI32) addRegisterClass(MVT::i32, &RISCV::GPRRegClass); - if (Subtarget.hasStdExtZfhOrZfhmin()) + if (Subtarget.hasStdExtZfhmin()) addRegisterClass(MVT::f16, &RISCV::FPR16RegClass); if (Subtarget.hasStdExtZfbfmin()) addRegisterClass(MVT::bf16, &RISCV::FPR16RegClass); @@ -130,7 +130,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, addRegisterClass(MVT::f32, &RISCV::FPR32RegClass); if (Subtarget.hasStdExtD()) addRegisterClass(MVT::f64, &RISCV::FPR64RegClass); - if (Subtarget.hasStdExtZhinxOrZhinxmin()) + if (Subtarget.hasStdExtZhinxmin()) addRegisterClass(MVT::f16, &RISCV::GPRF16RegClass); if (Subtarget.hasStdExtZfinx()) addRegisterClass(MVT::f32, &RISCV::GPRF32RegClass); @@ -439,7 +439,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FRINT, ISD::FROUND, ISD::FROUNDEVEN}; - if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) + if (Subtarget.hasStdExtZfhminOrZhinxmin()) setOperationAction(ISD::BITCAST, MVT::i16, Custom); static const unsigned ZfhminZfbfminPromoteOps[] = { @@ -469,7 +469,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FCOPYSIGN, MVT::bf16, Expand); } - if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) { + if (Subtarget.hasStdExtZfhminOrZhinxmin()) { if (Subtarget.hasStdExtZfhOrZhinx()) { setOperationAction(FPLegalNodeTypes, MVT::f16, Legal); setOperationAction(FPRndMode, MVT::f16, @@ -675,7 +675,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND, ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN, ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX, - ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE}; + ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE}; static const unsigned FloatingPointVPOps[] = { ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL, @@ -688,7 +688,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND, ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO, ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS, - ISD::EXPERIMENTAL_VP_REVERSE}; + ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE}; static const unsigned IntegerVecReduceOps[] = { ISD::VECREDUCE_ADD, ISD::VECREDUCE_AND, ISD::VECREDUCE_OR, @@ -773,6 +773,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::VECTOR_REVERSE, VT, Custom); + setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom); setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom); setOperationPromotedToType( @@ -1147,6 +1148,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, ISD::VP_SETCC, ISD::VP_TRUNCATE}, VT, Custom); + setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom); setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom); continue; } @@ -1322,7 +1324,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, // Custom-legalize bitcasts from fixed-length vectors to scalar types. setOperationAction(ISD::BITCAST, {MVT::i8, MVT::i16, MVT::i32, MVT::i64}, Custom); - if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) + if (Subtarget.hasStdExtZfhminOrZhinxmin()) setOperationAction(ISD::BITCAST, MVT::f16, Custom); if (Subtarget.hasStdExtFOrZfinx()) setOperationAction(ISD::BITCAST, MVT::f32, Custom); @@ -1388,7 +1390,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, if (Subtarget.hasStdExtZbkb()) setTargetDAGCombine(ISD::BITREVERSE); - if (Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) + if (Subtarget.hasStdExtZfhminOrZhinxmin()) setTargetDAGCombine(ISD::SIGN_EXTEND_INREG); if (Subtarget.hasStdExtFOrZfinx()) setTargetDAGCombine({ISD::ZERO_EXTEND, ISD::FP_TO_SINT, ISD::FP_TO_UINT, @@ -2099,7 +2101,7 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const { bool IsLegalVT = false; if (VT == MVT::f16) - IsLegalVT = Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin(); + IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin(); else if (VT == MVT::f32) IsLegalVT = Subtarget.hasStdExtFOrZfinx(); else if (VT == MVT::f64) @@ -2171,7 +2173,7 @@ MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context, // Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled. // We might still end up using a GPR but that will be decided based on ABI. if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() && - !Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) + !Subtarget.hasStdExtZfhminOrZhinxmin()) return MVT::f32; MVT PartVT = TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT); @@ -2188,7 +2190,7 @@ unsigned RISCVTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context // Use f32 to pass f16 if it is legal and Zfh/Zfhmin is not enabled. // We might still end up using a GPR but that will be decided based on ABI. if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() && - !Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) + !Subtarget.hasStdExtZfhminOrZhinxmin()) return 1; return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT); @@ -5528,7 +5530,7 @@ static unsigned getRISCVVLOp(SDValue Op) { case ISD::VP_SELECT: return RISCVISD::VSELECT_VL; case ISD::VP_MERGE: - return RISCVISD::VP_MERGE_VL; + return RISCVISD::VMERGE_VL; case ISD::VP_ASHR: return RISCVISD::SRA_VL; case ISD::VP_LSHR: @@ -5576,6 +5578,8 @@ static bool hasMergeOp(unsigned Opcode) { return true; if (Opcode >= RISCVISD::STRICT_FADD_VL && Opcode <= RISCVISD::STRICT_FDIV_VL) return true; + if (Opcode == RISCVISD::VMERGE_VL) + return true; return false; } @@ -5761,7 +5765,7 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, EVT Op0VT = Op0.getValueType(); MVT XLenVT = Subtarget.getXLenVT(); if (VT == MVT::f16 && Op0VT == MVT::i16 && - Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) { + Subtarget.hasStdExtZfhminOrZhinxmin()) { SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Op0); SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::f16, NewOp0); return FPConv; @@ -6637,6 +6641,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, !Subtarget.hasVInstructionsF16())) return SplitVPOp(Op, DAG); return lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(Op, DAG, Subtarget); + case ISD::EXPERIMENTAL_VP_SPLICE: + return lowerVPSpliceExperimental(Op, DAG); case ISD::EXPERIMENTAL_VP_REVERSE: return lowerVPReverseExperimental(Op, DAG); } @@ -8238,8 +8244,8 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG, AVL); // TUMA or TUMU: Currently we always emit tumu policy regardless of tuma. // It's fine because vmerge does not care mask policy. - return DAG.getNode(RISCVISD::VP_MERGE_VL, DL, VT, Mask, Vec, MaskedOff, - AVL); + return DAG.getNode(RISCVISD::VMERGE_VL, DL, VT, Mask, Vec, MaskedOff, + MaskedOff, AVL); } } @@ -10312,9 +10318,20 @@ SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG) const { for (const auto &OpIdx : enumerate(Op->ops())) { SDValue V = OpIdx.value(); assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!"); - // Add dummy merge value before the mask. - if (HasMergeOp && *ISD::getVPMaskIdx(Op.getOpcode()) == OpIdx.index()) - Ops.push_back(DAG.getUNDEF(ContainerVT)); + // Add dummy merge value before the mask. Or if there isn't a mask, before + // EVL. + if (HasMergeOp) { + auto MaskIdx = ISD::getVPMaskIdx(Op.getOpcode()); + if (MaskIdx) { + if (*MaskIdx == OpIdx.index()) + Ops.push_back(DAG.getUNDEF(ContainerVT)); + } else if (ISD::getVPExplicitVectorLengthIdx(Op.getOpcode()) == + OpIdx.index()) { + // For VP_MERGE, copy the false operand instead of an undef value. + assert(Op.getOpcode() == ISD::VP_MERGE); + Ops.push_back(Ops.back()); + } + } // Pass through operands which aren't fixed-length vectors. if (!V.getValueType().isFixedLengthVector()) { Ops.push_back(V); @@ -10583,6 +10600,87 @@ SDValue RISCVTargetLowering::lowerVPFPIntConvOp(SDValue Op, } SDValue +RISCVTargetLowering::lowerVPSpliceExperimental(SDValue Op, + SelectionDAG &DAG) const { + SDLoc DL(Op); + + SDValue Op1 = Op.getOperand(0); + SDValue Op2 = Op.getOperand(1); + SDValue Offset = Op.getOperand(2); + SDValue Mask = Op.getOperand(3); + SDValue EVL1 = Op.getOperand(4); + SDValue EVL2 = Op.getOperand(5); + + const MVT XLenVT = Subtarget.getXLenVT(); + MVT VT = Op.getSimpleValueType(); + MVT ContainerVT = VT; + if (VT.isFixedLengthVector()) { + ContainerVT = getContainerForFixedLengthVector(VT); + Op1 = convertToScalableVector(ContainerVT, Op1, DAG, Subtarget); + Op2 = convertToScalableVector(ContainerVT, Op2, DAG, Subtarget); + MVT MaskVT = getMaskTypeFor(ContainerVT); + Mask = convertToScalableVector(MaskVT, Mask, DAG, Subtarget); + } + + bool IsMaskVector = VT.getVectorElementType() == MVT::i1; + if (IsMaskVector) { + ContainerVT = ContainerVT.changeVectorElementType(MVT::i8); + + // Expand input operands + SDValue SplatOneOp1 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT, + DAG.getUNDEF(ContainerVT), + DAG.getConstant(1, DL, XLenVT), EVL1); + SDValue SplatZeroOp1 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT, + DAG.getUNDEF(ContainerVT), + DAG.getConstant(0, DL, XLenVT), EVL1); + Op1 = DAG.getNode(RISCVISD::VSELECT_VL, DL, ContainerVT, Op1, SplatOneOp1, + SplatZeroOp1, EVL1); + + SDValue SplatOneOp2 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT, + DAG.getUNDEF(ContainerVT), + DAG.getConstant(1, DL, XLenVT), EVL2); + SDValue SplatZeroOp2 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT, + DAG.getUNDEF(ContainerVT), + DAG.getConstant(0, DL, XLenVT), EVL2); + Op2 = DAG.getNode(RISCVISD::VSELECT_VL, DL, ContainerVT, Op2, SplatOneOp2, + SplatZeroOp2, EVL2); + } + + int64_t ImmValue = cast<ConstantSDNode>(Offset)->getSExtValue(); + SDValue DownOffset, UpOffset; + if (ImmValue >= 0) { + // The operand is a TargetConstant, we need to rebuild it as a regular + // constant. + DownOffset = DAG.getConstant(ImmValue, DL, XLenVT); + UpOffset = DAG.getNode(ISD::SUB, DL, XLenVT, EVL1, DownOffset); + } else { + // The operand is a TargetConstant, we need to rebuild it as a regular + // constant rather than negating the original operand. + UpOffset = DAG.getConstant(-ImmValue, DL, XLenVT); + DownOffset = DAG.getNode(ISD::SUB, DL, XLenVT, EVL1, UpOffset); + } + + SDValue SlideDown = + getVSlidedown(DAG, Subtarget, DL, ContainerVT, DAG.getUNDEF(ContainerVT), + Op1, DownOffset, Mask, UpOffset); + SDValue Result = getVSlideup(DAG, Subtarget, DL, ContainerVT, SlideDown, Op2, + UpOffset, Mask, EVL2, RISCVII::TAIL_AGNOSTIC); + + if (IsMaskVector) { + // Truncate Result back to a mask vector (Result has same EVL as Op2) + Result = DAG.getNode( + RISCVISD::SETCC_VL, DL, ContainerVT.changeVectorElementType(MVT::i1), + {Result, DAG.getConstant(0, DL, ContainerVT), + DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)), + Mask, EVL2}); + } + + if (!VT.isFixedLengthVector()) + return Result; + return convertFromScalableVector(VT, Result, DAG, Subtarget); +} + +SDValue RISCVTargetLowering::lowerVPReverseExperimental(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); @@ -11527,11 +11625,11 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, EVT Op0VT = Op0.getValueType(); MVT XLenVT = Subtarget.getXLenVT(); if (VT == MVT::i16 && Op0VT == MVT::f16 && - Subtarget.hasStdExtZfhOrZfhminOrZhinxOrZhinxmin()) { + Subtarget.hasStdExtZfhminOrZhinxmin()) { SDValue FPConv = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Op0); Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FPConv)); } else if (VT == MVT::i16 && Op0VT == MVT::bf16 && - Subtarget.hasStdExtZfbfmin()) { + Subtarget.hasStdExtZfbfmin()) { SDValue FPConv = DAG.getNode(RISCVISD::FMV_X_ANYEXTH, DL, XLenVT, Op0); Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FPConv)); } else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() && @@ -13493,6 +13591,7 @@ static SDValue performMemPairCombine(SDNode *N, // (fp_to_int (ffloor X)) -> fcvt X, rdn // (fp_to_int (fceil X)) -> fcvt X, rup // (fp_to_int (fround X)) -> fcvt X, rmm +// (fp_to_int (frint X)) -> fcvt X static SDValue performFP_TO_INTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const RISCVSubtarget &Subtarget) { @@ -13516,10 +13615,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N, RISCVFPRndMode::RoundingMode FRM = matchRoundingOp(Src.getOpcode()); // If the result is invalid, we didn't find a foldable instruction. - // If the result is dynamic, then we found an frint which we don't yet - // support. It will cause 7 to be written to the FRM CSR for vector. - // FIXME: We could support this by using VFCVT_X_F_VL/VFCVT_XU_F_VL below. - if (FRM == RISCVFPRndMode::Invalid || FRM == RISCVFPRndMode::DYN) + if (FRM == RISCVFPRndMode::Invalid) return SDValue(); SDLoc DL(N); @@ -13558,6 +13654,10 @@ static SDValue performFP_TO_INTCombine(SDNode *N, unsigned Opc = IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL; FpToInt = DAG.getNode(Opc, DL, ContainerVT, XVal, Mask, VL); + } else if (FRM == RISCVFPRndMode::DYN) { + unsigned Opc = + IsSigned ? RISCVISD::VFCVT_X_F_VL : RISCVISD::VFCVT_XU_F_VL; + FpToInt = DAG.getNode(Opc, DL, ContainerVT, XVal, Mask, VL); } else { unsigned Opc = IsSigned ? RISCVISD::VFCVT_RM_X_F_VL : RISCVISD::VFCVT_RM_XU_F_VL; @@ -13594,6 +13694,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N, // (fp_to_int_sat (ffloor X)) -> (select X == nan, 0, (fcvt X, rdn)) // (fp_to_int_sat (fceil X)) -> (select X == nan, 0, (fcvt X, rup)) // (fp_to_int_sat (fround X)) -> (select X == nan, 0, (fcvt X, rmm)) +// (fp_to_int_sat (frint X)) -> (select X == nan, 0, (fcvt X, dyn)) static SDValue performFP_TO_INT_SATCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const RISCVSubtarget &Subtarget) { @@ -15998,13 +16099,26 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op, // We can't do anything for most intrinsics. break; case Intrinsic::riscv_vsetvli: - case Intrinsic::riscv_vsetvlimax: - // Assume that VL output is <= 65536. - // TODO: Take SEW and LMUL into account. - if (BitWidth > 17) - Known.Zero.setBitsFrom(17); + case Intrinsic::riscv_vsetvlimax: { + bool HasAVL = IntNo == Intrinsic::riscv_vsetvli; + unsigned VSEW = Op.getConstantOperandVal(HasAVL + 1); + RISCVII::VLMUL VLMUL = + static_cast<RISCVII::VLMUL>(Op.getConstantOperandVal(HasAVL + 2)); + unsigned SEW = RISCVVType::decodeVSEW(VSEW); + auto [LMul, Fractional] = RISCVVType::decodeVLMUL(VLMUL); + uint64_t MaxVL = Subtarget.getRealMaxVLen() / SEW; + MaxVL = (Fractional) ? MaxVL / LMul : MaxVL * LMul; + + // Result of vsetvli must be not larger than AVL. + if (HasAVL && isa<ConstantSDNode>(Op.getOperand(1))) + MaxVL = std::min(MaxVL, Op.getConstantOperandVal(1)); + + unsigned KnownZeroFirstBit = Log2_32(MaxVL) + 1; + if (BitWidth > KnownZeroFirstBit) + Known.Zero.setBitsFrom(KnownZeroFirstBit); break; } + } break; } } @@ -18570,7 +18684,7 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(VNSRL_VL) NODE_NAME_CASE(SETCC_VL) NODE_NAME_CASE(VSELECT_VL) - NODE_NAME_CASE(VP_MERGE_VL) + NODE_NAME_CASE(VMERGE_VL) NODE_NAME_CASE(VMAND_VL) NODE_NAME_CASE(VMOR_VL) NODE_NAME_CASE(VMXOR_VL) @@ -18632,7 +18746,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, // TODO: Support fixed vectors up to XLen for P extension? if (VT.isVector()) break; - if (VT == MVT::f16 && Subtarget.hasStdExtZhinxOrZhinxmin()) + if (VT == MVT::f16 && Subtarget.hasStdExtZhinxmin()) return std::make_pair(0U, &RISCV::GPRF16RegClass); if (VT == MVT::f32 && Subtarget.hasStdExtZfinx()) return std::make_pair(0U, &RISCV::GPRF32RegClass); @@ -18640,7 +18754,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return std::make_pair(0U, &RISCV::GPRPF64RegClass); return std::make_pair(0U, &RISCV::GPRNoX0RegClass); case 'f': - if (Subtarget.hasStdExtZfhOrZfhmin() && VT == MVT::f16) + if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16) return std::make_pair(0U, &RISCV::FPR16RegClass); if (Subtarget.hasStdExtF() && VT == MVT::f32) return std::make_pair(0U, &RISCV::FPR32RegClass); @@ -18753,7 +18867,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, } if (VT == MVT::f32 || VT == MVT::Other) return std::make_pair(FReg, &RISCV::FPR32RegClass); - if (Subtarget.hasStdExtZfhOrZfhmin() && VT == MVT::f16) { + if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16) { unsigned RegNo = FReg - RISCV::F0_F; unsigned HReg = RISCV::F0_H + RegNo; return std::make_pair(HReg, &RISCV::FPR16RegClass); @@ -19100,7 +19214,7 @@ bool RISCVTargetLowering::shouldConvertFpToSat(unsigned Op, EVT FPVT, switch (FPVT.getSimpleVT().SimpleTy) { case MVT::f16: - return Subtarget.hasStdExtZfhOrZfhmin(); + return Subtarget.hasStdExtZfhmin(); case MVT::f32: return Subtarget.hasStdExtF(); case MVT::f64: |
