Hi Richard,

On 07/07/2026 09:38, Richard Biener wrote:
On Tue, Jul 7, 2026 at 10:00 AM Pengfei Li <[email protected]> wrote:
Normally, SAD_EXPRs with identical first and second operands are not
constructed, since the absolute difference value is zero. However, this
can still appear when vectorizing small iteration-count reduction loops
with an absolute difference operation.

This patch adds a match.pd rule to fold the redundant SAD_EXPR to its
accumulator operand.

Bootstrapped and tested on aarch64-linux-gnu and x86_64-linux-gnu.
The pattern looks good to me, but I don't see how the testcase exercises it?

In this testcase, SAD_EXPR is expanded to AArch64 uabd + udot instructions. Without the pattern, the uabd is eliminated but SAD_EXPR still generates an extra udot with a zero vector, e.g.

    movi    d31, #0
    ...
    udot    z29.s, z31.b, z28.b

The 48-iteration loop needs 3 udot, instead of 4. That's what the testcase checks. Ok for trunk?

Thanks,
Pengfei


gcc/ChangeLog:

         * match.pd: Simplify SAD(x, x, acc) into acc.

gcc/testsuite/ChangeLog:

         * gcc.target/aarch64/sve/sad_2.c: New test.
---
  gcc/match.pd                                 |  7 +++++++
  gcc/testsuite/gcc.target/aarch64/sve/sad_2.c | 16 ++++++++++++++++
  2 files changed, 23 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sad_2.c

diff --git a/gcc/match.pd b/gcc/match.pd
index a7cec25dbad..4520a23a026 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1229,6 +1229,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (mult (absu@1 @0) @1)
   (mult (convert@2 @0) @2))

+#if GIMPLE
+/* Simplify SAD(x, x, acc) -> acc since the absolute difference is zero.  */
+(simplify
+ (sad @0 @0 @1)
+ @1)
+#endif
+
  /* cos(copysign(x, y)) -> cos(x).  Similarly for cosh.  */
  (for coss (COS COSH)
   (for copysigns (COPYSIGN)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sad_2.c 
b/gcc/testsuite/gcc.target/aarch64/sve/sad_2.c
new file mode 100644
index 00000000000..d46517f10d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/sad_2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -msve-vector-bits=128 -mtune=neoverse-v2" } */
+
+#include <stdint.h>
+
+int foo (uint8_t *pix1, uint8_t *pix2)
+{
+    int sum = 0;
+    for (int x = 0; x < 48; x++)
+    {
+        sum += __builtin_abs (pix1[x] - pix2[x]);
+    }
+    return sum;
+}
+
+/* { dg-final { scan-assembler-times {\tudot\t} 3 } } */
--
2.43.0

Reply via email to