https://gcc.gnu.org/g:50be38676af8ed32744b856ad6864302f7b400bc

commit r17-4241-g50be38676af8ed32744b856ad6864302f7b400bc
Author: Naveen <[email protected]>
Date:   Mon Sep 14 20:19:42 2026 -0700

    aarch64: Use UDOT for V8QI sad when dot product is available
    
    On TARGET_DOTPROD targets the SAD can be lowered to two instructions:
    UABD/SABD to compute the lane-wise absolute differences into a V8QI 
temporary
    followed by a single UDOT against a vector of all-ones to widen and 
accumulate
    the eight byte lanes into a V2SI result. The signed variant uses SABD but
    still feeds UDOT since absolute differences are unsigned.
    
    A new test sadv8qi-dotprod.c verifies that both unsigned and signed
    SAD loops emit UABD/SABD + UDOT on arm_v8_2a_dotprod targets.
    
    gcc/ChangeLog
            * config/aarch64/aarch64-simd.md: Add define_expand <su>sadv8qi
            guarded by TARGET_DOTPROD.
    
    gcc/testsuite/ChangeLog
            * gcc.target/aarch64/sadv8qi-dotprod.c: New test.
    
    Signed-off-by: Naveen <[email protected]>

Diff:
---
 gcc/config/aarch64/aarch64-simd.md                 | 15 ++++++++++
 gcc/testsuite/gcc.target/aarch64/sadv8qi-dotprod.c | 35 ++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index 5e87df2bb5fd..fe6cb4250f6a 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1235,6 +1235,21 @@
   [(set_attr "type" "neon_reduc_add<q>")]
 )
 
+(define_expand "<su>sadv8qi"
+  [(use (match_operand:V2SI 0 "register_operand"))
+   (USMAX:V8QI (match_operand:V8QI 1 "register_operand")
+               (match_operand:V8QI 2 "register_operand"))
+   (use (match_operand:V2SI 3 "register_operand"))]
+  "TARGET_DOTPROD"
+  {
+    rtx ones = force_reg (V8QImode, CONST1_RTX (V8QImode));
+    rtx abd = gen_reg_rtx (V8QImode);
+    emit_insn (gen_aarch64_<su>abdv8qi (abd, operands[1], operands[2]));
+    emit_insn (gen_udot_prodv2siv8qi (operands[0], abd, ones, operands[3]));
+    DONE;
+  }
+)
+
 ;; Emit a sequence to produce a sum-of-absolute-differences of the V16QI
 ;; inputs in operands 1 and 2.  The sequence also has to perform a widening
 ;; reduction of the difference into a V4SI vector and accumulate that into
diff --git a/gcc/testsuite/gcc.target/aarch64/sadv8qi-dotprod.c 
b/gcc/testsuite/gcc.target/aarch64/sadv8qi-dotprod.c
new file mode 100644
index 000000000000..351bb66e1fbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sadv8qi-dotprod.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_2a_dotprod_neon_ok } */
+/* { dg-add-options arm_v8_2a_dotprod_neon }  */
+/* { dg-additional-options "-O3 -fno-unroll-loops" } */
+
+#pragma GCC target "+nosve"
+
+#define N 8
+
+unsigned char upix1[N], upix2[N];
+signed char spix1[N], spix2[N];
+
+int
+ufoo (void)
+{
+  int sum = 0;
+  int i;
+  for (i = 0; i < N; ++i)
+    sum += __builtin_abs (upix1[i] - upix2[i]);
+  return sum;
+}
+
+int
+sfoo (void)
+{
+  int sum = 0;
+  int i;
+  for (i = 0; i < N; ++i)
+    sum += __builtin_abs (spix1[i] - spix2[i]);
+  return sum;
+}
+
+/* { dg-final { scan-assembler {\tuabd\tv[0-9]+\.8b, v[0-9]+\.8b, v[0-9]+\.8b} 
} } */
+/* { dg-final { scan-assembler {\tsabd\tv[0-9]+\.8b, v[0-9]+\.8b, v[0-9]+\.8b} 
} } */
+/* { dg-final { scan-assembler-times {\tudot\tv[0-9]+\.2s, v[0-9]+\.8b, 
v[0-9]+\.8b} 2 } } */

Reply via email to