@@ -6042,6 +6042,67 @@ SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
6042
6042
return SDValue();
6043
6043
}
6044
6044
6045
+ static bool arebothOperandsNotSNan(SDValue Operand1, SDValue Operand2,
6046
+ SelectionDAG &DAG) {
6047
+ return DAG.isKnownNeverSNaN(Operand2) && DAG.isKnownNeverSNaN(Operand1);
6048
+ }
6049
+
6050
+ static bool arebothOperandsNotNan(SDValue Operand1, SDValue Operand2,
6051
+ SelectionDAG &DAG) {
6052
+ return DAG.isKnownNeverNaN(Operand2) && DAG.isKnownNeverNaN(Operand1);
6053
+ }
6054
+
6055
+ static unsigned getMinMaxOpcodeForFP(SDValue Operand1, SDValue Operand2,
6056
+ ISD::CondCode CC, unsigned OrAndOpcode,
6057
+ SelectionDAG &DAG) {
6058
+ // The optimization cannot be applied for all the predicates because
6059
+ // of the way FMINNUM/FMAXNUM and FMINNUM_IEEE/FMAXNUM_IEEE handle
6060
+ // NaNs. For FMINNUM_IEEE/FMAXNUM_IEEE, the optimization cannot be
6061
+ // applied at all if one of the operands is a signaling NaN.
6062
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6063
+ EVT OpVT = Operand1.getValueType();
6064
+ // It is safe to use FMINNUM_IEEE/FMAXNUM_IEEE if all the operands
6065
+ // are non NaN values.
6066
+ if (((CC == ISD::SETLT || CC == ISD::SETLE) && (OrAndOpcode == ISD::OR)) ||
6067
+ ((CC == ISD::SETGT || CC == ISD::SETGE) && (OrAndOpcode == ISD::AND)))
6068
+ return arebothOperandsNotNan(Operand1, Operand2, DAG) ? ISD::FMINNUM_IEEE
6069
+ : ISD::DELETED_NODE;
6070
+ else if (((CC == ISD::SETGT || CC == ISD::SETGE) &&
6071
+ (OrAndOpcode == ISD::OR)) ||
6072
+ ((CC == ISD::SETLT || CC == ISD::SETLE) &&
6073
+ (OrAndOpcode == ISD::AND)))
6074
+ return arebothOperandsNotNan(Operand1, Operand2, DAG) ? ISD::FMAXNUM_IEEE
6075
+ : ISD::DELETED_NODE;
6076
+ // Both FMINNUM/FMAXNUM and FMINNUM_IEEE/FMAXNUM_IEEE handle quiet
6077
+ // NaNs in the same way. But, FMINNUM/FMAXNUM and FMINNUM_IEEE/
6078
+ // FMAXNUM_IEEE handle signaling NaNs differently. If we cannot prove
6079
+ // that there are not any sNaNs, then the optimization is not valid
6080
+ // for FMINNUM_IEEE/FMAXNUM_IEEE. In the presence of sNaNs, we apply
6081
+ // the optimization using FMINNUM/FMAXNUM for the following cases. If
6082
+ // we can prove that we do not have any sNaNs, then we can do the
6083
+ // optimization using FMINNUM_IEEE/FMAXNUM_IEEE for the following
6084
+ // cases.
6085
+ else if (((CC == ISD::SETOLT || CC == ISD::SETOLE) &&
6086
+ (OrAndOpcode == ISD::OR)) ||
6087
+ ((CC == ISD::SETUGT || CC == ISD::SETUGE) &&
6088
+ (OrAndOpcode == ISD::AND)))
6089
+ return TLI.isOperationLegalOrCustom(ISD::FMINNUM, OpVT)
6090
+ ? ISD::FMINNUM
6091
+ : arebothOperandsNotSNan(Operand1, Operand2, DAG)
6092
+ ? ISD::FMINNUM_IEEE
6093
+ : ISD::DELETED_NODE;
6094
+ else if (((CC == ISD::SETOGT || CC == ISD::SETOGE) &&
6095
+ (OrAndOpcode == ISD::OR)) ||
6096
+ ((CC == ISD::SETULT || CC == ISD::SETULE) &&
6097
+ (OrAndOpcode == ISD::AND)))
6098
+ return TLI.isOperationLegalOrCustom(ISD::FMAXNUM, OpVT)
6099
+ ? ISD::FMAXNUM
6100
+ : arebothOperandsNotSNan(Operand1, Operand2, DAG)
6101
+ ? ISD::FMAXNUM_IEEE
6102
+ : ISD::DELETED_NODE;
6103
+ return ISD::DELETED_NODE;
6104
+ }
6105
+
6045
6106
static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
6046
6107
using AndOrSETCCFoldKind = TargetLowering::AndOrSETCCFoldKind;
6047
6108
assert(
@@ -6083,12 +6144,20 @@ static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
6083
6144
// The optimization does not work for `==` or `!=` .
6084
6145
// The two comparisons should have either the same predicate or the
6085
6146
// predicate of one of the comparisons is the opposite of the other one.
6086
- if (OpVT.isInteger() && !ISD::isIntEqualitySetCC(CCL) &&
6087
- (CCL == CCR || CCL == ISD::getSetCCSwappedOperands(CCR)) &&
6088
- TLI.isOperationLegal(ISD::UMAX, OpVT) &&
6089
- TLI.isOperationLegal(ISD::SMAX, OpVT) &&
6090
- TLI.isOperationLegal(ISD::UMIN, OpVT) &&
6091
- TLI.isOperationLegal(ISD::SMIN, OpVT)) {
6147
+ if (((OpVT.isInteger() && TLI.isOperationLegal(ISD::UMAX, OpVT) &&
6148
+ TLI.isOperationLegal(ISD::SMAX, OpVT) &&
6149
+ TLI.isOperationLegal(ISD::UMIN, OpVT) &&
6150
+ TLI.isOperationLegal(ISD::SMIN, OpVT)) ||
6151
+ (OpVT.isFloatingPoint() &&
6152
+ ((TLI.isOperationLegalOrCustom(ISD::FMAXNUM, OpVT) &&
6153
+ TLI.isOperationLegalOrCustom(ISD::FMINNUM, OpVT)) ||
6154
+ (TLI.isOperationLegal(ISD::FMAXNUM_IEEE, OpVT) &&
6155
+ TLI.isOperationLegal(ISD::FMINNUM_IEEE, OpVT))))) &&
6156
+ !ISD::isIntEqualitySetCC(CCL) && !ISD::isFPEqualitySetCC(CCL) &&
6157
+ CCL != ISD::SETFALSE && CCL != ISD::SETO && CCL != ISD::SETUO &&
6158
+ CCL != ISD::SETTRUE &&
6159
+ (CCL == CCR || CCL == ISD::getSetCCSwappedOperands(CCR))) {
6160
+
6092
6161
SDValue CommonValue, Operand1, Operand2;
6093
6162
ISD::CondCode CC = ISD::SETCC_INVALID;
6094
6163
if (CCL == CCR) {
@@ -6126,19 +6195,25 @@ static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
6126
6195
CC = ISD::SETCC_INVALID;
6127
6196
6128
6197
if (CC != ISD::SETCC_INVALID) {
6129
- unsigned NewOpcode;
6198
+ unsigned NewOpcode = ISD::DELETED_NODE ;
6130
6199
bool IsSigned = isSignedIntSetCC(CC);
6131
- bool IsLess = (CC == ISD::SETLE || CC == ISD::SETULE ||
6132
- CC == ISD::SETLT || CC == ISD::SETULT);
6133
- bool IsOr = (LogicOp->getOpcode() == ISD::OR);
6134
- if (IsLess == IsOr)
6135
- NewOpcode = IsSigned ? ISD::SMIN : ISD::UMIN;
6136
- else
6137
- NewOpcode = IsSigned ? ISD::SMAX : ISD::UMAX;
6138
-
6139
- SDValue MinMaxValue =
6140
- DAG.getNode(NewOpcode, DL, OpVT, Operand1, Operand2);
6141
- return DAG.getSetCC(DL, VT, MinMaxValue, CommonValue, CC);
6200
+ if (OpVT.isInteger()) {
6201
+ bool IsLess = (CC == ISD::SETLE || CC == ISD::SETULE ||
6202
+ CC == ISD::SETLT || CC == ISD::SETULT);
6203
+ bool IsOr = (LogicOp->getOpcode() == ISD::OR);
6204
+ if (IsLess == IsOr)
6205
+ NewOpcode = IsSigned ? ISD::SMIN : ISD::UMIN;
6206
+ else
6207
+ NewOpcode = IsSigned ? ISD::SMAX : ISD::UMAX;
6208
+ } else if (OpVT.isFloatingPoint())
6209
+ NewOpcode = getMinMaxOpcodeForFP(Operand1, Operand2, CC,
6210
+ LogicOp->getOpcode(), DAG);
6211
+
6212
+ if (NewOpcode != ISD::DELETED_NODE) {
6213
+ SDValue MinMaxValue =
6214
+ DAG.getNode(NewOpcode, DL, OpVT, Operand1, Operand2);
6215
+ return DAG.getSetCC(DL, VT, MinMaxValue, CommonValue, CC);
6216
+ }
6142
6217
}
6143
6218
}
6144
6219
0 commit comments