Skip to content

Commit

Permalink
[DAG] Add foldSelectToABD helper. NFC.
Browse files Browse the repository at this point in the history
Pull out of visitVSELECT to allow reuse in the future.
  • Loading branch information
RKSimon authored and kstoimenov committed Aug 15, 2024
1 parent ca20ce6 commit c078d7b
Showing 1 changed file with 43 additions and 31 deletions.
74 changes: 43 additions & 31 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -11568,6 +11570,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 (LegalOperations && !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);
Expand Down Expand Up @@ -12368,37 +12409,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 (!LegalOperations || 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)) {
Expand Down

0 comments on commit c078d7b

Please sign in to comment.