[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 07:58:03 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:

Huh? `(0x4 << 6) - (0x4 >> 2) == 16`? What kind of math is this? I think your error is that if `X = 4`, you think that `Y = 6` when it is actually `Y = 2`.
The algorithm is simple: convert `(sub N0, N1)` to `orc.b N1` if `N0 == (N1 << 8)` and if only the least significant bits of `N1` are possibly set.

https://github.com/llvm/llvm-project/pull/111828


More information about the llvm-commits mailing list