[llvm] [RISCV] Add DAG combine to turn (sub (shl X, 8-Y), (shr X, Y)) into orc.b (PR #111828)
Nemanja Ivanovic via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 08:07:43 PDT 2024
================
@@ -13587,18 +13591,41 @@ static SDValue combineSubShiftToOrcB(SDNode *N, SelectionDAG &DAG,
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- if (N0.getOpcode() != ISD::SHL || N0.getOperand(0) != N1 || !N0.hasOneUse())
+ if (N0->getOpcode() != ISD::SHL)
+ return SDValue();
+
+ auto *ShAmtCLeft = dyn_cast<ConstantSDNode>(N0.getOperand(1));
+ if (!ShAmtCLeft)
+ return SDValue();
+ unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
+ SDValue LeftShiftOperand = N0->getOperand(0);
+ SDValue RightShiftOperand = N1;
+
+ if (ShiftedAmount != 0 && N1->getOpcode() != ISD::SRL)
+ return SDValue();
+
+ if (ShiftedAmount != 0) { // Right operand must be a right shift.
+ auto *ShAmtCRight = dyn_cast<ConstantSDNode>(N1.getOperand(1));
+ if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
+ return SDValue();
+ RightShiftOperand = N1.getOperand(0);
+ }
+
+ // At least one shift should have a single use.
+ if (!N0.hasOneUse() && (ShiftedAmount == 0 || !N1.hasOneUse()))
return SDValue();
- auto *ShAmtC = dyn_cast<ConstantSDNode>(N0.getOperand(1));
- if (!ShAmtC || ShAmtC->getZExtValue() != 8)
+ if (LeftShiftOperand != RightShiftOperand)
return SDValue();
- APInt Mask = APInt::getSplat(VT.getSizeInBits(), APInt(8, 0xfe));
- if (!DAG.MaskedValueIsZero(N1, Mask))
+ APInt Mask = APInt::getSplat(VT.getSizeInBits(), APInt(8, 0x1));
+ Mask <<= ShiftedAmount;
----------------
nemanjai wrote:
Or are you saying that the computation of `Y` is not correct here? @damokeev can you verify that in this case, `Y` will indeed be set to the correct value and that `(sub (shl X, 2), (shr X, 6))` with `X == 4` will indeed be rejected?
https://github.com/llvm/llvm-project/pull/111828
More information about the llvm-commits
mailing list