diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 97 |
1 files changed, 45 insertions, 52 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 20b3ca21ef8a..a5b7397253e0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -598,6 +598,8 @@ namespace { const SDLoc &DL); SDValue foldSubToUSubSat(EVT DstVT, SDNode *N, const SDLoc &DL); SDValue foldABSToABD(SDNode *N, const SDLoc &DL); + SDValue foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True, + SDValue False, ISD::CondCode CC, const SDLoc &DL); SDValue unfoldMaskedMerge(SDNode *N); SDValue unfoldExtremeBitClearingToShifts(SDNode *N); SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, @@ -3260,28 +3262,9 @@ static SDValue extractBooleanFlip(SDValue V, SelectionDAG &DAG, if (V.getOpcode() != ISD::XOR) return SDValue(); - ConstantSDNode *Const = isConstOrConstSplat(V.getOperand(1), false); - if (!Const) - return SDValue(); - - EVT VT = V.getValueType(); - - bool IsFlip = false; - switch(TLI.getBooleanContents(VT)) { - case TargetLowering::ZeroOrOneBooleanContent: - IsFlip = Const->isOne(); - break; - case TargetLowering::ZeroOrNegativeOneBooleanContent: - IsFlip = Const->isAllOnes(); - break; - case TargetLowering::UndefinedBooleanContent: - IsFlip = (Const->getAPIntValue() & 0x01) == 1; - break; - } - - if (IsFlip) + if (DAG.isBoolConstant(V.getOperand(1)) == true) return V.getOperand(0); - if (Force) + if (Force && isConstOrConstSplat(V.getOperand(1), false)) return DAG.getLogicalNOT(SDLoc(V), V, V.getValueType()); return SDValue(); } @@ -11585,6 +11568,45 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) { return SDValue(); } +// Match SELECTs with absolute difference patterns. +// (select (setcc a, b, set?gt), (sub a, b), (sub b, a)) --> (abd? a, b) +// (select (setcc a, b, set?ge), (sub a, b), (sub b, a)) --> (abd? a, b) +// (select (setcc a, b, set?lt), (sub b, a), (sub a, b)) --> (abd? a, b) +// (select (setcc a, b, set?le), (sub b, a), (sub a, b)) --> (abd? a, b) +SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True, + SDValue False, ISD::CondCode CC, + const SDLoc &DL) { + bool IsSigned = isSignedIntSetCC(CC); + unsigned ABDOpc = IsSigned ? ISD::ABDS : ISD::ABDU; + EVT VT = LHS.getValueType(); + + if (!hasOperation(ABDOpc, VT)) + return SDValue(); + + switch (CC) { + case ISD::SETGT: + case ISD::SETGE: + case ISD::SETUGT: + case ISD::SETUGE: + if (sd_match(True, m_Sub(m_Specific(LHS), m_Specific(RHS))) && + sd_match(False, m_Sub(m_Specific(RHS), m_Specific(LHS)))) + return DAG.getNode(ABDOpc, DL, VT, LHS, RHS); + break; + case ISD::SETLT: + case ISD::SETLE: + case ISD::SETULT: + case ISD::SETULE: + if (sd_match(True, m_Sub(m_Specific(RHS), m_Specific(LHS))) && + sd_match(False, m_Sub(m_Specific(LHS), m_Specific(RHS)))) + return DAG.getNode(ABDOpc, DL, VT, LHS, RHS); + break; + default: + break; + } + + return SDValue(); +} + SDValue DAGCombiner::visitSELECT(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -12385,37 +12407,8 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) { } } - // Match VSELECTs with absolute difference patterns. - // (vselect (setcc a, b, set?gt), (sub a, b), (sub b, a)) --> (abd? a, b) - // (vselect (setcc a, b, set?ge), (sub a, b), (sub b, a)) --> (abd? a, b) - // (vselect (setcc a, b, set?lt), (sub b, a), (sub a, b)) --> (abd? a, b) - // (vselect (setcc a, b, set?le), (sub b, a), (sub a, b)) --> (abd? a, b) - if (N1.getOpcode() == ISD::SUB && N2.getOpcode() == ISD::SUB && - N1.getOperand(0) == N2.getOperand(1) && - N1.getOperand(1) == N2.getOperand(0)) { - bool IsSigned = isSignedIntSetCC(CC); - unsigned ABDOpc = IsSigned ? ISD::ABDS : ISD::ABDU; - if (hasOperation(ABDOpc, VT)) { - switch (CC) { - case ISD::SETGT: - case ISD::SETGE: - case ISD::SETUGT: - case ISD::SETUGE: - if (LHS == N1.getOperand(0) && RHS == N1.getOperand(1)) - return DAG.getNode(ABDOpc, DL, VT, LHS, RHS); - break; - case ISD::SETLT: - case ISD::SETLE: - case ISD::SETULT: - case ISD::SETULE: - if (RHS == N1.getOperand(0) && LHS == N1.getOperand(1) ) - return DAG.getNode(ABDOpc, DL, VT, LHS, RHS); - break; - default: - break; - } - } - } + if (SDValue ABD = foldSelectToABD(LHS, RHS, N1, N2, CC, DL)) + return ABD; // Match VSELECTs into add with unsigned saturation. if (hasOperation(ISD::UADDSAT, VT)) { |
