[llvm] [DAG] foldShiftToAvg - recognize sub(x, xor(y, -1)) >> 1 as avgceil[su] (PR #182616)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 01:18:35 PDT 2026


================
@@ -12432,6 +12432,36 @@ static SDValue combineMinNumMaxNumImpl(const SDLoc &DL, EVT VT, SDValue LHS,
   }
 }
 
+// Check whether sub(X, xor Y, C) matches the all_ones xor form:
+//   C := all_ones (after truncation to elt width) -> (xor Y, C) == ~Y,
+//   thus, sub (X, xor Y, c) == (X - ~Y) == (X + Y + 1).
+// Returns AVGCEILS if sext(X) and sext(Y),
+//         AVGCEILU if zext(X) and zext(Y),
+//         0 otherwise.
+static unsigned getAvgCeilFromXor(SDValue XorRHS, SDValue X, SDValue Y) {
+  auto *Splat = dyn_cast<ConstantSDNode>(XorRHS.getOperand(0));
+  if (!Splat)
+    return 0;
+
+  unsigned EltBits =
+      XorRHS.getValueType().getVectorElementType().getSizeInBits();
+  if (!Splat->getAPIntValue().trunc(EltBits).isAllOnes())
+    return 0;
+
+  auto IsSExt = [](SDValue V) {
+    return V.getOpcode() == ISD::SIGN_EXTEND ||
+           V.getOpcode() == ISD::SIGN_EXTEND_INREG;
+  };
+  auto IsZExt = [](SDValue V) {
+    return V.getOpcode() == ISD::ZERO_EXTEND ||
+           V.getOpcode() == ISD::ZERO_EXTEND_VECTOR_INREG;
+  };
----------------
laurenmchin wrote:

@arsenm @RKSimon 

I've removed the lambdas.

I believe the INREG cases are currently tested by:
1. rhadds_v4i16_lsh
2. rhadds_v2i32_lsh
3. rhadds_v8i8_lsh

However, I’d like to do more testing to verify whether the INREG cases are actually needed here. If necessary, I'll add the bitwidth check, thanks for pointing this out.

I'm currently preparing for a midterm this week, so I'll follow up after the exam with an updated patch.

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


More information about the llvm-commits mailing list