@@ -713,7 +713,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
713713        ISD::VP_FRINT,       ISD::VP_FNEARBYINT,  ISD::VP_IS_FPCLASS,
714714        ISD::VP_FMINIMUM,    ISD::VP_FMAXIMUM,    ISD::VP_LRINT,
715715        ISD::VP_LLRINT,      ISD::EXPERIMENTAL_VP_REVERSE,
716-         ISD::EXPERIMENTAL_VP_SPLICE};
716+         ISD::EXPERIMENTAL_VP_SPLICE, ISD::VP_REDUCE_FMINIMUM,
717+         ISD::VP_REDUCE_FMAXIMUM};
717718
718719    static const unsigned IntegerVecReduceOps[] = {
719720        ISD::VECREDUCE_ADD,  ISD::VECREDUCE_AND,  ISD::VECREDUCE_OR,
@@ -958,7 +959,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
958959        ISD::VP_FFLOOR,      ISD::VP_FROUND,       ISD::VP_FROUNDEVEN,
959960        ISD::VP_FCOPYSIGN,   ISD::VP_FROUNDTOZERO, ISD::VP_FRINT,
960961        ISD::VP_FNEARBYINT,  ISD::VP_SETCC,        ISD::VP_FMINIMUM,
961-         ISD::VP_FMAXIMUM};
962+         ISD::VP_FMAXIMUM,    ISD::VP_REDUCE_FMINIMUM, ISD::VP_REDUCE_FMAXIMUM };
962963
963964    // Sets common operation actions on RVV floating-point vector types.
964965    const auto SetCommonVFPActions = [&](MVT VT) {
@@ -6661,6 +6662,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
66616662  case ISD::VP_REDUCE_SEQ_FADD:
66626663  case ISD::VP_REDUCE_FMIN:
66636664  case ISD::VP_REDUCE_FMAX:
6665+   case ISD::VP_REDUCE_FMINIMUM:
6666+   case ISD::VP_REDUCE_FMAXIMUM:
66646667    if (Op.getOperand(1).getValueType() == MVT::nxv32f16 &&
66656668        (Subtarget.hasVInstructionsF16Minimal() &&
66666669         !Subtarget.hasVInstructionsF16()))
@@ -9526,8 +9529,10 @@ static unsigned getRVVReductionOp(unsigned ISDOpcode) {
95269529  case ISD::VP_REDUCE_SEQ_FADD:
95279530    return RISCVISD::VECREDUCE_SEQ_FADD_VL;
95289531  case ISD::VP_REDUCE_FMAX:
9532+   case ISD::VP_REDUCE_FMAXIMUM:
95299533    return RISCVISD::VECREDUCE_FMAX_VL;
95309534  case ISD::VP_REDUCE_FMIN:
9535+   case ISD::VP_REDUCE_FMINIMUM:
95319536    return RISCVISD::VECREDUCE_FMIN_VL;
95329537  }
95339538
@@ -9786,16 +9791,19 @@ SDValue RISCVTargetLowering::lowerFPVECREDUCE(SDValue Op,
97869791SDValue RISCVTargetLowering::lowerVPREDUCE(SDValue Op,
97879792                                           SelectionDAG &DAG) const {
97889793  SDLoc DL(Op);
9794+   unsigned Opc = Op.getOpcode();
9795+   SDValue Start = Op.getOperand(0);
97899796  SDValue Vec = Op.getOperand(1);
97909797  EVT VecEVT = Vec.getValueType();
9798+   MVT XLenVT = Subtarget.getXLenVT();
97919799
97929800  // TODO: The type may need to be widened rather than split. Or widened before
97939801  // it can be split.
97949802  if (!isTypeLegal(VecEVT))
97959803    return SDValue();
97969804
97979805  MVT VecVT = VecEVT.getSimpleVT();
9798-   unsigned RVVOpcode = getRVVReductionOp(Op.getOpcode() );
9806+   unsigned RVVOpcode = getRVVReductionOp(Opc );
97999807
98009808  if (VecVT.isFixedLengthVector()) {
98019809    auto ContainerVT = getContainerForFixedLengthVector(VecVT);
@@ -9804,8 +9812,30 @@ SDValue RISCVTargetLowering::lowerVPREDUCE(SDValue Op,
98049812
98059813  SDValue VL = Op.getOperand(3);
98069814  SDValue Mask = Op.getOperand(2);
9807-   return lowerReductionSeq(RVVOpcode, Op.getSimpleValueType(), Op.getOperand(0),
9808-                            Vec, Mask, VL, DL, DAG, Subtarget);
9815+   SDValue Res =
9816+       lowerReductionSeq(RVVOpcode, Op.getSimpleValueType(), Op.getOperand(0),
9817+                         Vec, Mask, VL, DL, DAG, Subtarget);
9818+   if ((Opc != ISD::VP_REDUCE_FMINIMUM && Opc != ISD::VP_REDUCE_FMAXIMUM) ||
9819+       Op->getFlags().hasNoNaNs())
9820+     return Res;
9821+ 
9822+   // Propagate NaNs.
9823+   MVT PredVT = getMaskTypeFor(Vec.getSimpleValueType());
9824+   // Check if any of the elements in Vec is NaN.
9825+   SDValue IsNaN = DAG.getNode(
9826+       RISCVISD::SETCC_VL, DL, PredVT,
9827+       {Vec, Vec, DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(PredVT), Mask, VL});
9828+   SDValue VCPop = DAG.getNode(RISCVISD::VCPOP_VL, DL, XLenVT, IsNaN, Mask, VL);
9829+   // Check if the start value is NaN.
9830+   SDValue StartIsNaN = DAG.getSetCC(DL, XLenVT, Start, Start, ISD::SETUO);
9831+   VCPop = DAG.getNode(ISD::OR, DL, XLenVT, VCPop, StartIsNaN);
9832+   SDValue NoNaNs = DAG.getSetCC(DL, XLenVT, VCPop,
9833+                                 DAG.getConstant(0, DL, XLenVT), ISD::SETEQ);
9834+   MVT ResVT = Res.getSimpleValueType();
9835+   return DAG.getSelect(
9836+       DL, ResVT, NoNaNs, Res,
9837+       DAG.getConstantFP(APFloat::getNaN(DAG.EVTToAPFloatSemantics(ResVT)), DL,
9838+                         ResVT));
98099839}
98109840
98119841SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
0 commit comments