[llvm] [AArch64] Add a few tests showing in-reg absolute differences (NFC) (PR #191383)
Benjamin Maxwell via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 15 02:24:52 PDT 2026
https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/191383
>From c55f0ceb63393e3b5653968ae92c133cc9fa1e37 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 10 Apr 2026 10:29:03 +0000
Subject: [PATCH 1/2] [AArch64] Add a few tests showing in-reg absolute
differences (NFC)
---
.../AArch64/inreg-absolute-difference.ll | 83 +++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll
diff --git a/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll b/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll
new file mode 100644
index 0000000000000..027697fc56729
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll
@@ -0,0 +1,83 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mattr=+sve2,+dotprod < %s | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnu"
+
+define <vscale x 16 x i8> @sabs_nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
+; CHECK-LABEL: sabs_nxv16i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.b
+; CHECK-NEXT: sabd z0.b, p0/m, z0.b, z1.b
+; CHECK-NEXT: ret
+ %smax = tail call <vscale x 16 x i8> @llvm.smax.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %smin = tail call <vscale x 16 x i8> @llvm.smin.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %sabs = sub <vscale x 16 x i8> %smax, %smin
+ ret <vscale x 16 x i8> %sabs
+}
+
+define <vscale x 16 x i8> @uabs_nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
+; CHECK-LABEL: uabs_nxv16i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.b
+; CHECK-NEXT: uabd z0.b, p0/m, z0.b, z1.b
+; CHECK-NEXT: ret
+ %umax = tail call <vscale x 16 x i8> @llvm.umax.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %umin = tail call <vscale x 16 x i8> @llvm.umin.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %uabs = sub <vscale x 16 x i8> %umax, %umin
+ ret <vscale x 16 x i8> %uabs
+}
+
+define <vscale x 4 x i32> @sabs_nxv16i8_dot(<vscale x 4 x i32> %acc, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
+; CHECK-LABEL: sabs_nxv16i8_dot:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.b
+; CHECK-NEXT: sabd z1.b, p0/m, z1.b, z2.b
+; CHECK-NEXT: mov z2.b, #1 // =0x1
+; CHECK-NEXT: udot z0.s, z1.b, z2.b
+; CHECK-NEXT: ret
+ %smax = tail call <vscale x 16 x i8> @llvm.smax.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %smin = tail call <vscale x 16 x i8> @llvm.smin.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %sabs = sub <vscale x 16 x i8> %smax, %smin
+ %ext = zext <vscale x 16 x i8> %sabs to <vscale x 16 x i32>
+ %dot = call <vscale x 4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<vscale x 4 x i32> %acc, <vscale x 16 x i32> %ext)
+ ret <vscale x 4 x i32> %dot
+}
+
+define <16 x i8> @sabs_v16i8(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: sabs_v16i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: sabd v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: ret
+ %smax = tail call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a, <16 x i8> %b)
+ %smin = tail call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a, <16 x i8> %b)
+ %sabs = sub <16 x i8> %smax, %smin
+ ret <16 x i8> %sabs
+}
+
+define <16 x i8> @uabs_v16i8(<16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: uabs_v16i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: uabd v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: ret
+ %umax = tail call <16 x i8> @llvm.umax.v16i8(<16 x i8> %a, <16 x i8> %b)
+ %umin = tail call <16 x i8> @llvm.umin.v16i8(<16 x i8> %a, <16 x i8> %b)
+ %uabs = sub <16 x i8> %umax, %umin
+ ret <16 x i8> %uabs
+}
+
+define <4 x i32> @uabs_v16i8_dot(<4 x i32> %acc, <16 x i8> %a, <16 x i8> %b) {
+; CHECK-LABEL: uabs_v16i8_dot:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov z3.b, #1 // =0x1
+; CHECK-NEXT: uabd v1.16b, v1.16b, v2.16b
+; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0
+; CHECK-NEXT: udot z0.s, z1.b, z3.b
+; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0
+; CHECK-NEXT: ret
+ %umax = tail call <16 x i8> @llvm.umax.v16i8(<16 x i8> %a, <16 x i8> %b)
+ %umin = tail call <16 x i8> @llvm.umin.v16i8(<16 x i8> %a, <16 x i8> %b)
+ %uabs = sub <16 x i8> %umax, %umin
+ %ext = zext <16 x i8> %uabs to <16 x i32>
+ %dot = call <4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<4 x i32> %acc, <16 x i32> %ext)
+ ret <4 x i32> %dot
+}
>From ccf7d366672ae2af385277385d280fe6aab8985a Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Wed, 15 Apr 2026 09:23:02 +0000
Subject: [PATCH 2/2] Add wide add cases
---
.../AArch64/inreg-absolute-difference.ll | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll b/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll
index 027697fc56729..bebf1cb00e6a9 100644
--- a/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll
+++ b/llvm/test/CodeGen/AArch64/inreg-absolute-difference.ll
@@ -27,6 +27,23 @@ define <vscale x 16 x i8> @uabs_nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8
ret <vscale x 16 x i8> %uabs
}
+; TODO: This case could be lowered to a sabal[bt] pair.
+define <vscale x 8 x i16> @sabs_nxv16i8_wide_add(<vscale x 8 x i16> %acc, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
+; CHECK-LABEL: sabs_nxv16i8_wide_add:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.b
+; CHECK-NEXT: sabd z1.b, p0/m, z1.b, z2.b
+; CHECK-NEXT: uaddwb z0.h, z0.h, z1.b
+; CHECK-NEXT: uaddwt z0.h, z0.h, z1.b
+; CHECK-NEXT: ret
+ %smax = tail call <vscale x 16 x i8> @llvm.smax.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %smin = tail call <vscale x 16 x i8> @llvm.smin.nxv16i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b)
+ %sabs = sub <vscale x 16 x i8> %smax, %smin
+ %ext = zext <vscale x 16 x i8> %sabs to <vscale x 16 x i16>
+ %reduce = call <vscale x 8 x i16> @llvm.vector.partial.reduce.add.v4i32.v16i32(<vscale x 8 x i16> %acc, <vscale x 16 x i16> %ext)
+ ret <vscale x 8 x i16> %reduce
+}
+
define <vscale x 4 x i32> @sabs_nxv16i8_dot(<vscale x 4 x i32> %acc, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
; CHECK-LABEL: sabs_nxv16i8_dot:
; CHECK: // %bb.0:
@@ -65,6 +82,23 @@ define <16 x i8> @uabs_v16i8(<16 x i8> %a, <16 x i8> %b) {
ret <16 x i8> %uabs
}
+; TODO: This case could be lowered to a uabal[bt] pair.
+define <vscale x 4 x i32> @uabs_nxv16i8_wide_add(<vscale x 4 x i32> %acc, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b) {
+; CHECK-LABEL: uabs_nxv16i8_wide_add:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.h
+; CHECK-NEXT: uabd z1.h, p0/m, z1.h, z2.h
+; CHECK-NEXT: uaddwb z0.s, z0.s, z1.h
+; CHECK-NEXT: uaddwt z0.s, z0.s, z1.h
+; CHECK-NEXT: ret
+ %umax = tail call <vscale x 8 x i16> @llvm.umax.nxv8i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b)
+ %umin = tail call <vscale x 8 x i16> @llvm.umin.nxv8i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b)
+ %uabs = sub <vscale x 8 x i16> %umax, %umin
+ %ext = zext <vscale x 8 x i16> %uabs to <vscale x 8 x i32>
+ %reduce = call <vscale x 4 x i32> @llvm.vector.partial.reduce.add.v4i32.v16i32(<vscale x 4 x i32> %acc, <vscale x 8 x i32> %ext)
+ ret <vscale x 4 x i32> %reduce
+}
+
define <4 x i32> @uabs_v16i8_dot(<4 x i32> %acc, <16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: uabs_v16i8_dot:
; CHECK: // %bb.0:
More information about the llvm-commits
mailing list