[llvm] [SDAG] (abd? (?ext x), c) -> (zext (abd? x, c)) (PR #176366)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 16 08:53:09 PST 2026


================
@@ -5812,6 +5812,28 @@ SDValue DAGCombiner::visitABD(SDNode *N) {
     }
   }
 
+  APInt YConst;
+  // fold (abd? (?ext ty:x), small_const:c) -> (zext (abd? x, c))
+  if (sd_match(N, m_c_BinOp(ISD::ABDU, m_ZExt(m_Value(X)), m_Value(Y))) ||
+      sd_match(N, m_c_BinOp(ISD::ABDS, m_SExt(m_Value(X)), m_Value(Y)))) {
+    EVT SmallVT = X.getValueType();
+    auto Bits = SmallVT.getScalarSizeInBits();
+    bool IsConstSmall = ISD::matchUnaryPredicate(
----------------
DaKnig wrote:

tried the easier path, one side is matched with m_Z/Sext, the other is done using isTruncateFree. the problem arises when the default implementation of TLI.isTruncateFree gives the answer based on types alone, which is not correct in our case: truncating constants is always free. and truncating bv depends on truncation of each element. I believe we could do that better, separately, in the default isTruncFree implementation in another patch.

truncate is also free when we have `trunc` instruction in the dag, since the argument came from somewhere, regardless of `isTruncFree`. that too, would be a good patch to add to the default `isTruncFree(SDValue, EVT)` method, in a separate patch.

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


More information about the llvm-commits mailing list