@@ -598,6 +598,8 @@ namespace {
598
598
const SDLoc &DL);
599
599
SDValue foldSubToUSubSat(EVT DstVT, SDNode *N, const SDLoc &DL);
600
600
SDValue foldABSToABD(SDNode *N, const SDLoc &DL);
601
+ SDValue foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
602
+ SDValue False, ISD::CondCode CC, const SDLoc &DL);
601
603
SDValue unfoldMaskedMerge(SDNode *N);
602
604
SDValue unfoldExtremeBitClearingToShifts(SDNode *N);
603
605
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
@@ -11568,6 +11570,45 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
11568
11570
return SDValue();
11569
11571
}
11570
11572
11573
+ // Match SELECTs with absolute difference patterns.
11574
+ // (select (setcc a, b, set?gt), (sub a, b), (sub b, a)) --> (abd? a, b)
11575
+ // (select (setcc a, b, set?ge), (sub a, b), (sub b, a)) --> (abd? a, b)
11576
+ // (select (setcc a, b, set?lt), (sub b, a), (sub a, b)) --> (abd? a, b)
11577
+ // (select (setcc a, b, set?le), (sub b, a), (sub a, b)) --> (abd? a, b)
11578
+ SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
11579
+ SDValue False, ISD::CondCode CC,
11580
+ const SDLoc &DL) {
11581
+ bool IsSigned = isSignedIntSetCC(CC);
11582
+ unsigned ABDOpc = IsSigned ? ISD::ABDS : ISD::ABDU;
11583
+ EVT VT = LHS.getValueType();
11584
+
11585
+ if (LegalOperations && !hasOperation(ABDOpc, VT))
11586
+ return SDValue();
11587
+
11588
+ switch (CC) {
11589
+ case ISD::SETGT:
11590
+ case ISD::SETGE:
11591
+ case ISD::SETUGT:
11592
+ case ISD::SETUGE:
11593
+ if (sd_match(True, m_Sub(m_Specific(LHS), m_Specific(RHS))) &&
11594
+ sd_match(False, m_Sub(m_Specific(RHS), m_Specific(LHS))))
11595
+ return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
11596
+ break;
11597
+ case ISD::SETLT:
11598
+ case ISD::SETLE:
11599
+ case ISD::SETULT:
11600
+ case ISD::SETULE:
11601
+ if (sd_match(True, m_Sub(m_Specific(RHS), m_Specific(LHS))) &&
11602
+ sd_match(False, m_Sub(m_Specific(LHS), m_Specific(RHS))))
11603
+ return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
11604
+ break;
11605
+ default:
11606
+ break;
11607
+ }
11608
+
11609
+ return SDValue();
11610
+ }
11611
+
11571
11612
SDValue DAGCombiner::visitSELECT(SDNode *N) {
11572
11613
SDValue N0 = N->getOperand(0);
11573
11614
SDValue N1 = N->getOperand(1);
@@ -12368,37 +12409,8 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
12368
12409
}
12369
12410
}
12370
12411
12371
- // Match VSELECTs with absolute difference patterns.
12372
- // (vselect (setcc a, b, set?gt), (sub a, b), (sub b, a)) --> (abd? a, b)
12373
- // (vselect (setcc a, b, set?ge), (sub a, b), (sub b, a)) --> (abd? a, b)
12374
- // (vselect (setcc a, b, set?lt), (sub b, a), (sub a, b)) --> (abd? a, b)
12375
- // (vselect (setcc a, b, set?le), (sub b, a), (sub a, b)) --> (abd? a, b)
12376
- if (N1.getOpcode() == ISD::SUB && N2.getOpcode() == ISD::SUB &&
12377
- N1.getOperand(0) == N2.getOperand(1) &&
12378
- N1.getOperand(1) == N2.getOperand(0)) {
12379
- bool IsSigned = isSignedIntSetCC(CC);
12380
- unsigned ABDOpc = IsSigned ? ISD::ABDS : ISD::ABDU;
12381
- if (!LegalOperations || hasOperation(ABDOpc, VT)) {
12382
- switch (CC) {
12383
- case ISD::SETGT:
12384
- case ISD::SETGE:
12385
- case ISD::SETUGT:
12386
- case ISD::SETUGE:
12387
- if (LHS == N1.getOperand(0) && RHS == N1.getOperand(1))
12388
- return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
12389
- break;
12390
- case ISD::SETLT:
12391
- case ISD::SETLE:
12392
- case ISD::SETULT:
12393
- case ISD::SETULE:
12394
- if (RHS == N1.getOperand(0) && LHS == N1.getOperand(1) )
12395
- return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
12396
- break;
12397
- default:
12398
- break;
12399
- }
12400
- }
12401
- }
12412
+ if (SDValue ABD = foldSelectToABD(LHS, RHS, N1, N2, CC, DL))
12413
+ return ABD;
12402
12414
12403
12415
// Match VSELECTs into add with unsigned saturation.
12404
12416
if (hasOperation(ISD::UADDSAT, VT)) {
0 commit comments