@@ -649,14 +649,15 @@ namespace {
649
649
bool DemandHighBits = true);
650
650
SDValue MatchBSwapHWord(SDNode *N, SDValue N0, SDValue N1);
651
651
SDValue MatchRotatePosNeg(SDValue Shifted, SDValue Pos, SDValue Neg,
652
- SDValue InnerPos, SDValue InnerNeg, bool HasPos ,
653
- unsigned PosOpcode , unsigned NegOpcode ,
654
- const SDLoc &DL);
652
+ SDValue InnerPos, SDValue InnerNeg, bool FromAdd ,
653
+ bool HasPos , unsigned PosOpcode ,
654
+ unsigned NegOpcode, const SDLoc &DL);
655
655
SDValue MatchFunnelPosNeg(SDValue N0, SDValue N1, SDValue Pos, SDValue Neg,
656
- SDValue InnerPos, SDValue InnerNeg, bool HasPos,
657
- unsigned PosOpcode, unsigned NegOpcode,
658
- const SDLoc &DL);
659
- SDValue MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL);
656
+ SDValue InnerPos, SDValue InnerNeg, bool FromAdd,
657
+ bool HasPos, unsigned PosOpcode,
658
+ unsigned NegOpcode, const SDLoc &DL);
659
+ SDValue MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL,
660
+ bool FromAdd);
660
661
SDValue MatchLoadCombine(SDNode *N);
661
662
SDValue mergeTruncStores(StoreSDNode *N);
662
663
SDValue reduceLoadWidth(SDNode *N);
@@ -2982,6 +2983,9 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
2982
2983
if (SDValue V = foldAddSubOfSignBit(N, DL, DAG))
2983
2984
return V;
2984
2985
2986
+ if (SDValue V = MatchRotate(N0, N1, SDLoc(N), /*FromAdd=*/true))
2987
+ return V;
2988
+
2985
2989
// Try to match AVGFLOOR fixedwidth pattern
2986
2990
if (SDValue V = foldAddToAvg(N, DL))
2987
2991
return V;
@@ -8151,7 +8155,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
8151
8155
return V;
8152
8156
8153
8157
// See if this is some rotate idiom.
8154
- if (SDValue Rot = MatchRotate(N0, N1, DL))
8158
+ if (SDValue Rot = MatchRotate(N0, N1, DL, /*FromAdd=*/false ))
8155
8159
return Rot;
8156
8160
8157
8161
if (SDValue Load = MatchLoadCombine(N))
@@ -8340,7 +8344,7 @@ static SDValue extractShiftForRotate(SelectionDAG &DAG, SDValue OppShift,
8340
8344
// The IsRotate flag should be set when the LHS of both shifts is the same.
8341
8345
// Otherwise if matching a general funnel shift, it should be clear.
8342
8346
static bool matchRotateSub(SDValue Pos, SDValue Neg, unsigned EltSize,
8343
- SelectionDAG &DAG, bool IsRotate) {
8347
+ SelectionDAG &DAG, bool IsRotate, bool FromAdd ) {
8344
8348
const auto &TLI = DAG.getTargetLoweringInfo();
8345
8349
// If EltSize is a power of 2 then:
8346
8350
//
@@ -8379,7 +8383,7 @@ static bool matchRotateSub(SDValue Pos, SDValue Neg, unsigned EltSize,
8379
8383
// NOTE: We can only do this when matching operations which won't modify the
8380
8384
// least Log2(EltSize) significant bits and not a general funnel shift.
8381
8385
unsigned MaskLoBits = 0;
8382
- if (IsRotate && isPowerOf2_64(EltSize)) {
8386
+ if (IsRotate && !FromAdd && isPowerOf2_64(EltSize)) {
8383
8387
unsigned Bits = Log2_64(EltSize);
8384
8388
unsigned NegBits = Neg.getScalarValueSizeInBits();
8385
8389
if (NegBits >= Bits) {
@@ -8462,9 +8466,9 @@ static bool matchRotateSub(SDValue Pos, SDValue Neg, unsigned EltSize,
8462
8466
// Neg with outer conversions stripped away.
8463
8467
SDValue DAGCombiner::MatchRotatePosNeg(SDValue Shifted, SDValue Pos,
8464
8468
SDValue Neg, SDValue InnerPos,
8465
- SDValue InnerNeg, bool HasPos ,
8466
- unsigned PosOpcode , unsigned NegOpcode ,
8467
- const SDLoc &DL) {
8469
+ SDValue InnerNeg, bool FromAdd ,
8470
+ bool HasPos , unsigned PosOpcode ,
8471
+ unsigned NegOpcode, const SDLoc &DL) {
8468
8472
// fold (or (shl x, (*ext y)),
8469
8473
// (srl x, (*ext (sub 32, y)))) ->
8470
8474
// (rotl x, y) or (rotr x, (sub 32, y))
@@ -8474,10 +8478,9 @@ SDValue DAGCombiner::MatchRotatePosNeg(SDValue Shifted, SDValue Pos,
8474
8478
// (rotr x, y) or (rotl x, (sub 32, y))
8475
8479
EVT VT = Shifted.getValueType();
8476
8480
if (matchRotateSub(InnerPos, InnerNeg, VT.getScalarSizeInBits(), DAG,
8477
- /*IsRotate*/ true)) {
8481
+ /*IsRotate*/ true, FromAdd))
8478
8482
return DAG.getNode(HasPos ? PosOpcode : NegOpcode, DL, VT, Shifted,
8479
8483
HasPos ? Pos : Neg);
8480
- }
8481
8484
8482
8485
return SDValue();
8483
8486
}
@@ -8490,9 +8493,9 @@ SDValue DAGCombiner::MatchRotatePosNeg(SDValue Shifted, SDValue Pos,
8490
8493
// TODO: Merge with MatchRotatePosNeg.
8491
8494
SDValue DAGCombiner::MatchFunnelPosNeg(SDValue N0, SDValue N1, SDValue Pos,
8492
8495
SDValue Neg, SDValue InnerPos,
8493
- SDValue InnerNeg, bool HasPos ,
8494
- unsigned PosOpcode , unsigned NegOpcode ,
8495
- const SDLoc &DL) {
8496
+ SDValue InnerNeg, bool FromAdd ,
8497
+ bool HasPos , unsigned PosOpcode ,
8498
+ unsigned NegOpcode, const SDLoc &DL) {
8496
8499
EVT VT = N0.getValueType();
8497
8500
unsigned EltBits = VT.getScalarSizeInBits();
8498
8501
@@ -8503,10 +8506,10 @@ SDValue DAGCombiner::MatchFunnelPosNeg(SDValue N0, SDValue N1, SDValue Pos,
8503
8506
// fold (or (shl x0, (*ext (sub 32, y))),
8504
8507
// (srl x1, (*ext y))) ->
8505
8508
// (fshr x0, x1, y) or (fshl x0, x1, (sub 32, y))
8506
- if (matchRotateSub(InnerPos, InnerNeg, EltBits, DAG, /*IsRotate*/ N0 == N1)) {
8509
+ if (matchRotateSub(InnerPos, InnerNeg, EltBits, DAG, /*IsRotate*/ N0 == N1,
8510
+ FromAdd))
8507
8511
return DAG.getNode(HasPos ? PosOpcode : NegOpcode, DL, VT, N0, N1,
8508
8512
HasPos ? Pos : Neg);
8509
- }
8510
8513
8511
8514
// Matching the shift+xor cases, we can't easily use the xor'd shift amount
8512
8515
// so for now just use the PosOpcode case if its legal.
@@ -8545,11 +8548,12 @@ SDValue DAGCombiner::MatchFunnelPosNeg(SDValue N0, SDValue N1, SDValue Pos,
8545
8548
return SDValue();
8546
8549
}
8547
8550
8548
- // MatchRotate - Handle an 'or' of two operands. If this is one of the many
8549
- // idioms for rotate, and if the target supports rotation instructions, generate
8550
- // a rot[lr]. This also matches funnel shift patterns, similar to rotation but
8551
- // with different shifted sources.
8552
- SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
8551
+ // MatchRotate - Handle an 'or' or 'add' of two operands. If this is one of the
8552
+ // many idioms for rotate, and if the target supports rotation instructions,
8553
+ // generate a rot[lr]. This also matches funnel shift patterns, similar to
8554
+ // rotation but with different shifted sources.
8555
+ SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL,
8556
+ bool FromAdd) {
8553
8557
EVT VT = LHS.getValueType();
8554
8558
8555
8559
// The target must have at least one rotate/funnel flavor.
@@ -8576,9 +8580,9 @@ SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
8576
8580
if (LHS.getOpcode() == ISD::TRUNCATE && RHS.getOpcode() == ISD::TRUNCATE &&
8577
8581
LHS.getOperand(0).getValueType() == RHS.getOperand(0).getValueType()) {
8578
8582
assert(LHS.getValueType() == RHS.getValueType());
8579
- if (SDValue Rot = MatchRotate(LHS.getOperand(0), RHS.getOperand(0), DL)) {
8583
+ if (SDValue Rot =
8584
+ MatchRotate(LHS.getOperand(0), RHS.getOperand(0), DL, FromAdd))
8580
8585
return DAG.getNode(ISD::TRUNCATE, SDLoc(LHS), LHS.getValueType(), Rot);
8581
- }
8582
8586
}
8583
8587
8584
8588
// Match "(X shl/srl V1) & V2" where V2 may not be present.
@@ -8758,29 +8762,25 @@ SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
8758
8762
}
8759
8763
8760
8764
if (IsRotate && (HasROTL || HasROTR)) {
8761
- SDValue TryL =
8762
- MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt, LExtOp0,
8763
- RExtOp0, HasROTL, ISD::ROTL, ISD::ROTR, DL);
8764
- if (TryL)
8765
+ if (SDValue TryL = MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt,
8766
+ LExtOp0, RExtOp0, FromAdd, HasROTL,
8767
+ ISD::ROTL, ISD::ROTR, DL))
8765
8768
return TryL;
8766
8769
8767
- SDValue TryR =
8768
- MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt, RExtOp0,
8769
- LExtOp0, HasROTR, ISD::ROTR, ISD::ROTL, DL);
8770
- if (TryR)
8770
+ if (SDValue TryR = MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
8771
+ RExtOp0, LExtOp0, FromAdd, HasROTR,
8772
+ ISD::ROTR, ISD::ROTL, DL))
8771
8773
return TryR;
8772
8774
}
8773
8775
8774
- SDValue TryL =
8775
- MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, LHSShiftAmt, RHSShiftAmt,
8776
- LExtOp0, RExtOp0, HasFSHL, ISD::FSHL, ISD::FSHR, DL);
8777
- if (TryL)
8776
+ if (SDValue TryL = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, LHSShiftAmt,
8777
+ RHSShiftAmt, LExtOp0, RExtOp0, FromAdd,
8778
+ HasFSHL, ISD::FSHL, ISD::FSHR, DL))
8778
8779
return TryL;
8779
8780
8780
- SDValue TryR =
8781
- MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
8782
- RExtOp0, LExtOp0, HasFSHR, ISD::FSHR, ISD::FSHL, DL);
8783
- if (TryR)
8781
+ if (SDValue TryR = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, RHSShiftAmt,
8782
+ LHSShiftAmt, RExtOp0, LExtOp0, FromAdd,
8783
+ HasFSHR, ISD::FSHR, ISD::FSHL, DL))
8784
8784
return TryR;
8785
8785
8786
8786
return SDValue();
0 commit comments