@@ -6021,26 +6021,91 @@ static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
6021
6021
AndOrSETCCFoldKind TargetPreference = TLI.isDesirableToCombineLogicOpOfSETCC(
6022
6022
LogicOp, LHS.getNode(), RHS.getNode());
6023
6023
6024
- if (TargetPreference == AndOrSETCCFoldKind::None)
6025
- return SDValue();
6026
-
6027
- ISD::CondCode CCL = cast<CondCodeSDNode>(LHS.getOperand(2))->get();
6028
- ISD::CondCode CCR = cast<CondCodeSDNode>(RHS.getOperand(2))->get();
6029
-
6030
6024
SDValue LHS0 = LHS->getOperand(0);
6031
6025
SDValue RHS0 = RHS->getOperand(0);
6032
6026
SDValue LHS1 = LHS->getOperand(1);
6033
6027
SDValue RHS1 = RHS->getOperand(1);
6034
-
6035
6028
// TODO: We don't actually need a splat here, for vectors we just need the
6036
6029
// invariants to hold for each element.
6037
6030
auto *LHS1C = isConstOrConstSplat(LHS1);
6038
6031
auto *RHS1C = isConstOrConstSplat(RHS1);
6039
-
6032
+ ISD::CondCode CCL = cast<CondCodeSDNode>(LHS.getOperand(2))->get();
6033
+ ISD::CondCode CCR = cast<CondCodeSDNode>(RHS.getOperand(2))->get();
6040
6034
EVT VT = LogicOp->getValueType(0);
6041
6035
EVT OpVT = LHS0.getValueType();
6042
6036
SDLoc DL(LogicOp);
6043
6037
6038
+ // Check if the operands of an and/or operation are comparisons and if they
6039
+ // compare against the same value. Replace the and/or-cmp-cmp sequence with
6040
+ // min/max cmp sequence. If LHS1 is equal to RHS1, then the or-cmp-cmp
6041
+ // sequence will be replaced with min-cmp sequence:
6042
+ // (LHS0 < LHS1) | (RHS0 < RHS1) -> min(LHS0, RHS0) < LHS1
6043
+ // and and-cmp-cmp will be replaced with max-cmp sequence:
6044
+ // (LHS0 < LHS1) & (RHS0 < RHS1) -> max(LHS0, RHS0) < LHS1
6045
+ if (OpVT.isInteger() && TLI.isOperationLegal(ISD::UMAX, OpVT) &&
6046
+ TLI.isOperationLegal(ISD::SMAX, OpVT) &&
6047
+ TLI.isOperationLegal(ISD::UMIN, OpVT) &&
6048
+ TLI.isOperationLegal(ISD::SMIN, OpVT)) {
6049
+ SDValue CommonValue;
6050
+ SDValue Operand1;
6051
+ SDValue Operand2;
6052
+ ISD::CondCode CC = ISD::SETCC_INVALID;
6053
+ if (LHS->getOpcode() == ISD::SETCC && RHS->getOpcode() == ISD::SETCC &&
6054
+ LHS->hasOneUse() && RHS->hasOneUse() &&
6055
+ // The two comparisons should have either the same predicate or the
6056
+ // predicate of one of the comparisons is the opposite of the other one.
6057
+ (CCL == CCR || CCL == ISD::getSetCCSwappedOperands(CCR)) &&
6058
+ // The optimization does not work for `==` or `!=` .
6059
+ !ISD::isIntEqualitySetCC(CCL) && !ISD::isIntEqualitySetCC(CCR)) {
6060
+ if (CCL == CCR) {
6061
+ if (LHS0 == RHS0) {
6062
+ CommonValue = LHS0;
6063
+ Operand1 = LHS1;
6064
+ Operand2 = RHS1;
6065
+ CC = ISD::getSetCCSwappedOperands(CCL);
6066
+ } else if (LHS1 == RHS1) {
6067
+ CommonValue = LHS1;
6068
+ Operand1 = LHS0;
6069
+ Operand2 = RHS0;
6070
+ CC = CCL;
6071
+ }
6072
+ } else if (CCL == ISD::getSetCCSwappedOperands(CCR)) {
6073
+ if (LHS0 == RHS1) {
6074
+ CommonValue = LHS0;
6075
+ Operand1 = LHS1;
6076
+ Operand2 = RHS0;
6077
+ CC = ISD::getSetCCSwappedOperands(CCL);
6078
+ } else if (RHS0 == LHS1) {
6079
+ CommonValue = LHS1;
6080
+ Operand1 = LHS0;
6081
+ Operand2 = RHS1;
6082
+ CC = CCL;
6083
+ }
6084
+ }
6085
+
6086
+ if (CC != ISD::SETCC_INVALID) {
6087
+ unsigned NewOpcode;
6088
+ bool IsSigned = isSignedIntSetCC(CC);
6089
+ if (((CC == ISD::SETLE || CC == ISD::SETULE || CC == ISD::SETLT ||
6090
+ CC == ISD::SETULT) &&
6091
+ (LogicOp->getOpcode() == ISD::OR)) ||
6092
+ ((CC == ISD::SETGE || CC == ISD::SETUGE || CC == ISD::SETGT ||
6093
+ CC == ISD::SETUGT) &&
6094
+ (LogicOp->getOpcode() == ISD::AND)))
6095
+ NewOpcode = IsSigned ? ISD::SMIN : ISD::UMIN;
6096
+ else
6097
+ NewOpcode = IsSigned ? ISD::SMAX : ISD::UMAX;
6098
+
6099
+ SDValue MinMaxValue =
6100
+ DAG.getNode(NewOpcode, DL, OpVT, Operand1, Operand2);
6101
+ return DAG.getSetCC(DL, VT, MinMaxValue, CommonValue, CC);
6102
+ }
6103
+ }
6104
+ }
6105
+
6106
+ if (TargetPreference == AndOrSETCCFoldKind::None)
6107
+ return SDValue();
6108
+
6044
6109
if (CCL == CCR &&
6045
6110
CCL == (LogicOp->getOpcode() == ISD::AND ? ISD::SETNE : ISD::SETEQ) &&
6046
6111
LHS0 == RHS0 && LHS1C && RHS1C && OpVT.isInteger() && LHS.hasOneUse() &&
0 commit comments