@@ -19340,8 +19340,10 @@ SDValue DAGCombiner::visitFMinMax(SDNode *N) {
19340
19340
EVT VT = N->getValueType(0);
19341
19341
const SDNodeFlags Flags = N->getFlags();
19342
19342
unsigned Opc = N->getOpcode();
19343
- bool PropagatesNaN = Opc == ISD::FMINIMUM || Opc == ISD::FMAXIMUM;
19344
- bool IsMin = Opc == ISD::FMINNUM || Opc == ISD::FMINIMUM;
19343
+ bool PropAllNaNsToQNaNs = Opc == ISD::FMINIMUM || Opc == ISD::FMAXIMUM;
19344
+ bool PropOnlySNaNsToQNaNs = Opc == ISD::FMINNUM || Opc == ISD::FMAXNUM;
19345
+ bool IsMin =
19346
+ Opc == ISD::FMINNUM || Opc == ISD::FMINIMUM || Opc == ISD::FMINIMUMNUM;
19345
19347
SelectionDAG::FlagInserter FlagsInserter(DAG, N);
19346
19348
19347
19349
// Constant fold.
@@ -19356,34 +19358,53 @@ SDValue DAGCombiner::visitFMinMax(SDNode *N) {
19356
19358
if (const ConstantFPSDNode *N1CFP = isConstOrConstSplatFP(N1)) {
19357
19359
const APFloat &AF = N1CFP->getValueAPF();
19358
19360
19359
- // minnum(X, nan) -> X
19360
- // maxnum(X, nan) -> X
19361
- // minimum(X, nan) -> nan
19362
- // maximum(X, nan) -> nan
19363
- if (AF.isNaN())
19364
- return PropagatesNaN ? N->getOperand(1) : N->getOperand(0);
19361
+ // minnum(X, qnan) -> X
19362
+ // maxnum(X, qnan) -> X
19363
+ // minnum(X, snan) -> qnan
19364
+ // maxnum(X, snan) -> qnan
19365
+ // minimum(X, nan) -> qnan
19366
+ // maximum(X, nan) -> qnan
19367
+ // minimumnum(X, nan) -> X
19368
+ // maximumnum(X, nan) -> X
19369
+ if (AF.isNaN()) {
19370
+ if (PropAllNaNsToQNaNs || (AF.isSignaling() && PropOnlySNaNsToQNaNs)) {
19371
+ if (AF.isSignaling())
19372
+ return DAG.getConstantFP(AF.makeQuiet(), SDLoc(N), VT);
19373
+ return N->getOperand(1);
19374
+ }
19375
+ return N->getOperand(0);
19376
+ }
19365
19377
19366
19378
// In the following folds, inf can be replaced with the largest finite
19367
19379
// float, if the ninf flag is set.
19368
19380
if (AF.isInfinity() || (Flags.hasNoInfs() && AF.isLargest())) {
19369
- // minnum(X, -inf) -> -inf
19370
- // maxnum(X, +inf) -> +inf
19381
+ // minnum(X, -inf) -> -inf (ignoring sNaN -> qNaN propagation)
19382
+ // maxnum(X, +inf) -> +inf (ignoring sNaN -> qNaN propagation)
19371
19383
// minimum(X, -inf) -> -inf if nnan
19372
19384
// maximum(X, +inf) -> +inf if nnan
19373
- if (IsMin == AF.isNegative() && (!PropagatesNaN || Flags.hasNoNaNs()))
19385
+ // minimumnum(X, -inf) -> -inf
19386
+ // maximumnum(X, +inf) -> +inf
19387
+ if (IsMin == AF.isNegative() &&
19388
+ (!PropAllNaNsToQNaNs || Flags.hasNoNaNs()))
19374
19389
return N->getOperand(1);
19375
19390
19376
19391
// minnum(X, +inf) -> X if nnan
19377
19392
// maxnum(X, -inf) -> X if nnan
19378
- // minimum(X, +inf) -> X
19379
- // maximum(X, -inf) -> X
19380
- if (IsMin != AF.isNegative() && (PropagatesNaN || Flags.hasNoNaNs()))
19393
+ // minimum(X, +inf) -> X (ignoring quieting of sNaNs)
19394
+ // maximum(X, -inf) -> X (ignoring quieting of sNaNs)
19395
+ // minimumnum(X, +inf) -> X if nnan
19396
+ // maximumnum(X, -inf) -> X if nnan
19397
+ if (IsMin != AF.isNegative() && (PropAllNaNsToQNaNs || Flags.hasNoNaNs()))
19381
19398
return N->getOperand(0);
19382
19399
}
19383
19400
}
19384
19401
19402
+ // There are no VECREDUCE variants of FMINIMUMNUM or FMAXIMUMNUM
19403
+ if (Opc == ISD::FMINIMUMNUM || Opc == ISD::FMAXIMUMNUM)
19404
+ return SDValue();
19405
+
19385
19406
if (SDValue SD = reassociateReduction(
19386
- PropagatesNaN
19407
+ PropAllNaNsToQNaNs
19387
19408
? (IsMin ? ISD::VECREDUCE_FMINIMUM : ISD::VECREDUCE_FMAXIMUM)
19388
19409
: (IsMin ? ISD::VECREDUCE_FMIN : ISD::VECREDUCE_FMAX),
19389
19410
Opc, SDLoc(N), VT, N0, N1, Flags))
0 commit comments