[llvm] [RISCV] Optimize lowering of VECREDUCE_FMINIMUM/VECREDUCE_FMAXIMUM. (PR #85165)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 14 09:05:47 PDT 2024
================
@@ -9571,9 +9576,30 @@ SDValue RISCVTargetLowering::lowerFPVECREDUCE(SDValue Op,
VectorVal = convertToScalableVector(ContainerVT, VectorVal, DAG, Subtarget);
}
+ MVT ResVT = Op.getSimpleValueType();
auto [Mask, VL] = getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget);
- return lowerReductionSeq(RVVOpcode, Op.getSimpleValueType(), ScalarVal,
- VectorVal, Mask, VL, DL, DAG, Subtarget);
+ SDValue Res = lowerReductionSeq(RVVOpcode, ResVT, ScalarVal, VectorVal, Mask,
+ VL, DL, DAG, Subtarget);
+ if (Op.getOpcode() != ISD::VECREDUCE_FMINIMUM &&
+ Op.getOpcode() != ISD::VECREDUCE_FMAXIMUM)
+ return Res;
+
+ if (Op->getFlags().hasNoNaNs())
+ return Res;
+
+ // Force output to NaN if any element is Nan.
+ SDValue IsNan =
+ DAG.getNode(RISCVISD::SETCC_VL, DL, Mask.getValueType(),
+ {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
+ DAG.getUNDEF(Mask.getValueType()), Mask, VL});
+ MVT XLenVT = Subtarget.getXLenVT();
+ SDValue CPop = DAG.getNode(RISCVISD::VCPOP_VL, DL, XLenVT, IsNan, Mask, VL);
+ SDValue NoNaNs = DAG.getSetCC(DL, XLenVT, CPop,
+ DAG.getConstant(0, DL, XLenVT), ISD::SETEQ);
+ return DAG.getSelect(
+ DL, ResVT, NoNaNs, Res,
+ DAG.getConstantFP(APFloat::getNaN(DAG.EVTToAPFloatSemantics(ResVT)), DL,
----------------
preames wrote:
I think this is okay, but let me call out a possible concern here to confirm.
This is not propagating the nan payload (if any) from the argument. Instead, it is returning a canonical nan if any of the inputs were nan (of any payload). I don't believe we're required to propagate nan payloads per relevant spec documents, but would be good to confirm you agree.
https://github.com/llvm/llvm-project/pull/85165
More information about the llvm-commits
mailing list