@@ -717,7 +717,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
717
717
718
718
static const unsigned FloatingPointVecReduceOps[] = {
719
719
ISD::VECREDUCE_FADD, ISD::VECREDUCE_SEQ_FADD, ISD::VECREDUCE_FMIN,
720
- ISD::VECREDUCE_FMAX};
720
+ ISD::VECREDUCE_FMAX, ISD::VECREDUCE_FMINIMUM, ISD::VECREDUCE_FMAXIMUM };
721
721
722
722
if (!Subtarget.is64Bit()) {
723
723
// We must custom-lower certain vXi64 operations on RV32 due to the vector
@@ -6541,6 +6541,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
6541
6541
case ISD::VECREDUCE_SEQ_FADD:
6542
6542
case ISD::VECREDUCE_FMIN:
6543
6543
case ISD::VECREDUCE_FMAX:
6544
+ case ISD::VECREDUCE_FMAXIMUM:
6545
+ case ISD::VECREDUCE_FMINIMUM:
6544
6546
return lowerFPVECREDUCE(Op, DAG);
6545
6547
case ISD::VP_REDUCE_ADD:
6546
6548
case ISD::VP_REDUCE_UMAX:
@@ -9541,14 +9543,17 @@ getRVVFPReductionOpAndOperands(SDValue Op, SelectionDAG &DAG, EVT EltVT,
9541
9543
case ISD::VECREDUCE_SEQ_FADD:
9542
9544
return std::make_tuple(RISCVISD::VECREDUCE_SEQ_FADD_VL, Op.getOperand(1),
9543
9545
Op.getOperand(0));
9546
+ case ISD::VECREDUCE_FMINIMUM:
9547
+ case ISD::VECREDUCE_FMAXIMUM:
9544
9548
case ISD::VECREDUCE_FMIN:
9545
9549
case ISD::VECREDUCE_FMAX: {
9546
9550
SDValue Front =
9547
9551
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Op.getOperand(0),
9548
9552
DAG.getVectorIdxConstant(0, DL));
9549
- unsigned RVVOpc = (Opcode == ISD::VECREDUCE_FMIN)
9550
- ? RISCVISD::VECREDUCE_FMIN_VL
9551
- : RISCVISD::VECREDUCE_FMAX_VL;
9553
+ unsigned RVVOpc =
9554
+ (Opcode == ISD::VECREDUCE_FMIN || Opcode == ISD::VECREDUCE_FMINIMUM)
9555
+ ? RISCVISD::VECREDUCE_FMIN_VL
9556
+ : RISCVISD::VECREDUCE_FMAX_VL;
9552
9557
return std::make_tuple(RVVOpc, Op.getOperand(0), Front);
9553
9558
}
9554
9559
}
@@ -9571,9 +9576,30 @@ SDValue RISCVTargetLowering::lowerFPVECREDUCE(SDValue Op,
9571
9576
VectorVal = convertToScalableVector(ContainerVT, VectorVal, DAG, Subtarget);
9572
9577
}
9573
9578
9579
+ MVT ResVT = Op.getSimpleValueType();
9574
9580
auto [Mask, VL] = getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget);
9575
- return lowerReductionSeq(RVVOpcode, Op.getSimpleValueType(), ScalarVal,
9576
- VectorVal, Mask, VL, DL, DAG, Subtarget);
9581
+ SDValue Res = lowerReductionSeq(RVVOpcode, ResVT, ScalarVal, VectorVal, Mask,
9582
+ VL, DL, DAG, Subtarget);
9583
+ if (Op.getOpcode() != ISD::VECREDUCE_FMINIMUM &&
9584
+ Op.getOpcode() != ISD::VECREDUCE_FMAXIMUM)
9585
+ return Res;
9586
+
9587
+ if (Op->getFlags().hasNoNaNs())
9588
+ return Res;
9589
+
9590
+ // Force output to NaN if any element is Nan.
9591
+ SDValue IsNan =
9592
+ DAG.getNode(RISCVISD::SETCC_VL, DL, Mask.getValueType(),
9593
+ {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
9594
+ DAG.getUNDEF(Mask.getValueType()), Mask, VL});
9595
+ MVT XLenVT = Subtarget.getXLenVT();
9596
+ SDValue CPop = DAG.getNode(RISCVISD::VCPOP_VL, DL, XLenVT, IsNan, Mask, VL);
9597
+ SDValue NoNaNs = DAG.getSetCC(DL, XLenVT, CPop,
9598
+ DAG.getConstant(0, DL, XLenVT), ISD::SETEQ);
9599
+ return DAG.getSelect(
9600
+ DL, ResVT, NoNaNs, Res,
9601
+ DAG.getConstantFP(APFloat::getNaN(DAG.EVTToAPFloatSemantics(ResVT)), DL,
9602
+ ResVT));
9577
9603
}
9578
9604
9579
9605
SDValue RISCVTargetLowering::lowerVPREDUCE(SDValue Op,
0 commit comments