@@ -13569,8 +13569,10 @@ static SDValue combineSubOfBoolean(SDNode *N, SelectionDAG &DAG) {
13569
13569
return DAG.getNode(ISD::ADD, DL, VT, NewLHS, NewRHS);
13570
13570
}
13571
13571
13572
- // Looks for (sub (shl X, 8), X) where only bits 8, 16, 24, 32, etc. of X are
13573
- // non-zero. Replace with orc.b.
13572
+ // Looks for (sub (shl X, 8-Y), (shr X, Y)) where the Y-th bit in each byte is
13573
+ // potentially set. It is fine for Y to be 0, meaning that (sub (shl X, 8), X)
13574
+ // is also valid. Replace with (orc.b X). For example, 0b0000_1000_0000_1000 is
13575
+ // valid with Y=3, while 0b0000_1000_0000_0100 is not.
13574
13576
static SDValue combineSubShiftToOrcB(SDNode *N, SelectionDAG &DAG,
13575
13577
const RISCVSubtarget &Subtarget) {
13576
13578
if (!Subtarget.hasStdExtZbb())
@@ -13584,18 +13586,44 @@ static SDValue combineSubShiftToOrcB(SDNode *N, SelectionDAG &DAG,
13584
13586
SDValue N0 = N->getOperand(0);
13585
13587
SDValue N1 = N->getOperand(1);
13586
13588
13587
- if (N0. getOpcode() != ISD::SHL || N0.getOperand(0) != N1 || !N0.hasOneUse() )
13589
+ if (N0-> getOpcode() != ISD::SHL)
13588
13590
return SDValue();
13589
13591
13590
- auto *ShAmtC = dyn_cast<ConstantSDNode>(N0.getOperand(1));
13591
- if (!ShAmtC || ShAmtC->getZExtValue() != 8 )
13592
+ auto *ShAmtCLeft = dyn_cast<ConstantSDNode>(N0.getOperand(1));
13593
+ if (!ShAmtCLeft )
13592
13594
return SDValue();
13595
+ unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
13593
13596
13594
- APInt Mask = APInt::getSplat(VT.getSizeInBits(), APInt(8, 0xfe));
13595
- if (!DAG.MaskedValueIsZero(N1, Mask))
13597
+ if (ShiftedAmount >= 8)
13596
13598
return SDValue();
13597
13599
13598
- return DAG.getNode(RISCVISD::ORC_B, SDLoc(N), VT, N1);
13600
+ SDValue LeftShiftOperand = N0->getOperand(0);
13601
+ SDValue RightShiftOperand = N1;
13602
+
13603
+ if (ShiftedAmount != 0) { // Right operand must be a right shift.
13604
+ if (N1->getOpcode() != ISD::SRL)
13605
+ return SDValue();
13606
+ auto *ShAmtCRight = dyn_cast<ConstantSDNode>(N1.getOperand(1));
13607
+ if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
13608
+ return SDValue();
13609
+ RightShiftOperand = N1.getOperand(0);
13610
+ }
13611
+
13612
+ // At least one shift should have a single use.
13613
+ if (!N0.hasOneUse() && (ShiftedAmount == 0 || !N1.hasOneUse()))
13614
+ return SDValue();
13615
+
13616
+ if (LeftShiftOperand != RightShiftOperand)
13617
+ return SDValue();
13618
+
13619
+ APInt Mask = APInt::getSplat(VT.getSizeInBits(), APInt(8, 0x1));
13620
+ Mask <<= ShiftedAmount;
13621
+ // Check that X has indeed the right shape (only the Y-th bit can be set in
13622
+ // every byte).
13623
+ if (!DAG.MaskedValueIsZero(LeftShiftOperand, ~Mask))
13624
+ return SDValue();
13625
+
13626
+ return DAG.getNode(RISCVISD::ORC_B, SDLoc(N), VT, LeftShiftOperand);
13599
13627
}
13600
13628
13601
13629
static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG,
0 commit comments