diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6022,7 +6022,8 @@ // TODO: Search past casts/truncates. SDValue LHS = LogicOp->getOperand(0); SDValue RHS = LogicOp->getOperand(1); - if (LHS->getOpcode() != ISD::SETCC || RHS->getOpcode() != ISD::SETCC) + if (LHS->getOpcode() != ISD::SETCC || RHS->getOpcode() != ISD::SETCC || + !LHS->hasOneUse() || !RHS->hasOneUse()) return SDValue(); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); @@ -6050,63 +6051,58 @@ // (LHS0 < LHS1) | (RHS0 < RHS1) -> min(LHS0, RHS0) < LHS1 // and and-cmp-cmp will be replaced with max-cmp sequence: // (LHS0 < LHS1) & (RHS0 < RHS1) -> max(LHS0, RHS0) < LHS1 - if (OpVT.isInteger() && TLI.isOperationLegal(ISD::UMAX, OpVT) && + // The optimization does not work for `==` or `!=` . + // The two comparisons should have either the same predicate or the + // predicate of one of the comparisons is the opposite of the other one. + if (OpVT.isInteger() && !ISD::isIntEqualitySetCC(CCL) && + (CCL == CCR || CCL == ISD::getSetCCSwappedOperands(CCR)) && + TLI.isOperationLegal(ISD::UMAX, OpVT) && TLI.isOperationLegal(ISD::SMAX, OpVT) && TLI.isOperationLegal(ISD::UMIN, OpVT) && TLI.isOperationLegal(ISD::SMIN, OpVT)) { - if (LHS->getOpcode() == ISD::SETCC && RHS->getOpcode() == ISD::SETCC && - LHS->hasOneUse() && RHS->hasOneUse() && - // The two comparisons should have either the same predicate or the - // predicate of one of the comparisons is the opposite of the other one. - (CCL == CCR || CCL == ISD::getSetCCSwappedOperands(CCR)) && - // The optimization does not work for `==` or `!=` . - !ISD::isIntEqualitySetCC(CCL) && !ISD::isIntEqualitySetCC(CCR)) { - SDValue CommonValue, Operand1, Operand2; - ISD::CondCode CC = ISD::SETCC_INVALID; - if (CCL == CCR) { - if (LHS0 == RHS0) { - CommonValue = LHS0; - Operand1 = LHS1; - Operand2 = RHS1; - CC = ISD::getSetCCSwappedOperands(CCL); - } else if (LHS1 == RHS1) { - CommonValue = LHS1; - Operand1 = LHS0; - Operand2 = RHS0; - CC = CCL; - } - } else { - assert(CCL == ISD::getSetCCSwappedOperands(CCR) && "Unexpected CC"); - if (LHS0 == RHS1) { - CommonValue = LHS0; - Operand1 = LHS1; - Operand2 = RHS0; - CC = ISD::getSetCCSwappedOperands(CCL); - } else if (RHS0 == LHS1) { - CommonValue = LHS1; - Operand1 = LHS0; - Operand2 = RHS1; - CC = CCL; - } + SDValue CommonValue, Operand1, Operand2; + ISD::CondCode CC = ISD::SETCC_INVALID; + if (CCL == CCR) { + if (LHS0 == RHS0) { + CommonValue = LHS0; + Operand1 = LHS1; + Operand2 = RHS1; + CC = ISD::getSetCCSwappedOperands(CCL); + } else if (LHS1 == RHS1) { + CommonValue = LHS1; + Operand1 = LHS0; + Operand2 = RHS0; + CC = CCL; + } + } else { + assert(CCL == ISD::getSetCCSwappedOperands(CCR) && "Unexpected CC"); + if (LHS0 == RHS1) { + CommonValue = LHS0; + Operand1 = LHS1; + Operand2 = RHS0; + CC = CCR; + } else if (RHS0 == LHS1) { + CommonValue = LHS1; + Operand1 = LHS0; + Operand2 = RHS1; + CC = CCL; } + } - if (CC != ISD::SETCC_INVALID) { - unsigned NewOpcode; - bool IsSigned = isSignedIntSetCC(CC); - if (((CC == ISD::SETLE || CC == ISD::SETULE || CC == ISD::SETLT || - CC == ISD::SETULT) && - (LogicOp->getOpcode() == ISD::OR)) || - ((CC == ISD::SETGE || CC == ISD::SETUGE || CC == ISD::SETGT || - CC == ISD::SETUGT) && - (LogicOp->getOpcode() == ISD::AND))) - NewOpcode = IsSigned ? ISD::SMIN : ISD::UMIN; - else - NewOpcode = IsSigned ? ISD::SMAX : ISD::UMAX; + if (CC != ISD::SETCC_INVALID) { + unsigned NewOpcode; + bool IsSigned = isSignedIntSetCC(CC); + bool IsLess = (CC == ISD::SETLE || CC == ISD::SETULE || + CC == ISD::SETLT || CC == ISD::SETULT); + bool IsOr = (LogicOp->getOpcode() == ISD::OR); + if (IsLess == IsOr) + NewOpcode = IsSigned ? ISD::SMIN : ISD::UMIN; + else + NewOpcode = IsSigned ? ISD::SMAX : ISD::UMAX; - SDValue MinMaxValue = - DAG.getNode(NewOpcode, DL, OpVT, Operand1, Operand2); - return DAG.getSetCC(DL, VT, MinMaxValue, CommonValue, CC); - } + SDValue MinMaxValue = + DAG.getNode(NewOpcode, DL, OpVT, Operand1, Operand2); + return DAG.getSetCC(DL, VT, MinMaxValue, CommonValue, CC); } } @@ -6115,8 +6111,7 @@ if (CCL == CCR && CCL == (LogicOp->getOpcode() == ISD::AND ? ISD::SETNE : ISD::SETEQ) && - LHS0 == RHS0 && LHS1C && RHS1C && OpVT.isInteger() && LHS.hasOneUse() && - RHS.hasOneUse()) { + LHS0 == RHS0 && LHS1C && RHS1C && OpVT.isInteger()) { const APInt &APLhs = LHS1C->getAPIntValue(); const APInt &APRhs = RHS1C->getAPIntValue();