[llvm] DAGCombiner: Support fmaximum/fminimum and fmaximumnum/fminimumnum (PR #137318)
YunQiang Su via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 26 01:24:23 PDT 2025
================
@@ -6333,60 +6333,70 @@ static bool arebothOperandsNotNan(SDValue Operand1, SDValue Operand2,
return DAG.isKnownNeverNaN(Operand2) && DAG.isKnownNeverNaN(Operand1);
}
-// FIXME: use FMINIMUMNUM if possible, such as for RISC-V.
-static unsigned getMinMaxOpcodeForFP(SDValue Operand1, SDValue Operand2,
- ISD::CondCode CC, unsigned OrAndOpcode,
- SelectionDAG &DAG,
- bool isFMAXNUMFMINNUM_IEEE,
- bool isFMAXNUMFMINNUM) {
- // The optimization cannot be applied for all the predicates because
- // of the way FMINNUM/FMAXNUM and FMINNUM_IEEE/FMAXNUM_IEEE handle
- // NaNs. For FMINNUM_IEEE/FMAXNUM_IEEE, the optimization cannot be
- // applied at all if one of the operands is a signaling NaN.
-
- // It is safe to use FMINNUM_IEEE/FMAXNUM_IEEE if all the operands
- // are non NaN values.
- if (((CC == ISD::SETLT || CC == ISD::SETLE) && (OrAndOpcode == ISD::OR)) ||
- ((CC == ISD::SETGT || CC == ISD::SETGE) && (OrAndOpcode == ISD::AND)))
- return arebothOperandsNotNan(Operand1, Operand2, DAG) &&
- isFMAXNUMFMINNUM_IEEE
- ? ISD::FMINNUM_IEEE
- : ISD::DELETED_NODE;
- else if (((CC == ISD::SETGT || CC == ISD::SETGE) &&
- (OrAndOpcode == ISD::OR)) ||
- ((CC == ISD::SETLT || CC == ISD::SETLE) &&
- (OrAndOpcode == ISD::AND)))
- return arebothOperandsNotNan(Operand1, Operand2, DAG) &&
- isFMAXNUMFMINNUM_IEEE
- ? ISD::FMAXNUM_IEEE
- : ISD::DELETED_NODE;
- // Both FMINNUM/FMAXNUM and FMINNUM_IEEE/FMAXNUM_IEEE handle quiet
- // NaNs in the same way. But, FMINNUM/FMAXNUM and FMINNUM_IEEE/
- // FMAXNUM_IEEE handle signaling NaNs differently. If we cannot prove
- // that there are not any sNaNs, then the optimization is not valid
- // for FMINNUM_IEEE/FMAXNUM_IEEE. In the presence of sNaNs, we apply
- // the optimization using FMINNUM/FMAXNUM for the following cases. If
- // we can prove that we do not have any sNaNs, then we can do the
- // optimization using FMINNUM_IEEE/FMAXNUM_IEEE for the following
- // cases.
- else if (((CC == ISD::SETOLT || CC == ISD::SETOLE) &&
- (OrAndOpcode == ISD::OR)) ||
- ((CC == ISD::SETUGT || CC == ISD::SETUGE) &&
- (OrAndOpcode == ISD::AND)))
- return isFMAXNUMFMINNUM ? ISD::FMINNUM
- : arebothOperandsNotSNan(Operand1, Operand2, DAG) &&
- isFMAXNUMFMINNUM_IEEE
- ? ISD::FMINNUM_IEEE
- : ISD::DELETED_NODE;
- else if (((CC == ISD::SETOGT || CC == ISD::SETOGE) &&
- (OrAndOpcode == ISD::OR)) ||
- ((CC == ISD::SETULT || CC == ISD::SETULE) &&
- (OrAndOpcode == ISD::AND)))
- return isFMAXNUMFMINNUM ? ISD::FMAXNUM
- : arebothOperandsNotSNan(Operand1, Operand2, DAG) &&
- isFMAXNUMFMINNUM_IEEE
- ? ISD::FMAXNUM_IEEE
- : ISD::DELETED_NODE;
+static unsigned
+getMinMaxOpcodeForFP(SDValue Operand1, SDValue Operand2, ISD::CondCode CC,
+ unsigned OrAndOpcode, SelectionDAG &DAG,
+ bool isFMAXNUMFMINNUM_IEEE, bool isFMAXNUMFMINNUM,
+ bool isFMAXIMUMFMINIMUM, bool isFMAXIMUMNUMFMINIMUMNUM) {
+ bool isMax = true;
+ // SETLT/SETLE/SETGT/SETGE are undefined if any Operand is NaN. We
+ // treat them as SETOLT/SETOLE/SETOGT/SETOGE.
+ if (((CC == ISD::SETLT || CC == ISD::SETLE || CC == ISD::SETOLT ||
+ CC == ISD::SETOLE) &&
+ (OrAndOpcode == ISD::OR)) ||
+ ((CC == ISD::SETUGT || CC == ISD::SETUGE) && (OrAndOpcode == ISD::AND))) {
+ isMax = false;
+ if (arebothOperandsNotSNan(Operand1, Operand2, DAG) &&
----------------
wzssyqa wrote:
It's already there for about 20 months. I will use a better name for them.
https://github.com/llvm/llvm-project/pull/137318
More information about the llvm-commits
mailing list