[llvm] [AArch64] Extend addp pattern to add_like(xtn, uzp2) in 128 bit result type (PR #194064)
Weiwen He via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 29 04:13:37 PDT 2026
https://github.com/he-weiwen updated https://github.com/llvm/llvm-project/pull/194064
>From 08260baf4573d498a69775ff35cc3d47ed13e468 Mon Sep 17 00:00:00 2001
From: he-weiwen <he.weiwen at outlook.com>
Date: Fri, 24 Apr 2026 20:48:06 +0100
Subject: [PATCH] [AArch64] Extend addp pattern to add_like(xtn, uzp2) in 128
bit result type
---
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 14 +++++
llvm/test/CodeGen/AArch64/addp-shuffle.ll | 67 +++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index f20f978fe7e8a..4df1f897fb612 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -11056,6 +11056,20 @@ def : Pat<(v8i8 (add_like (trunc (v8i16 (bitconvert FPR128:$Rn))),
(extract_subvector (AArch64uzp2 (v16i8 FPR128:$Rn), undef), (i64 0)))),
(EXTRACT_SUBREG (ADDPv16i8 $Rn, $Rn), dsub)>;
+multiclass PairwiseXtnUzp2BinOpWide<SDPatternOperator Op, ValueType VT,
+ ValueType HalfVT, ValueType WideEltVT,
+ Instruction Inst> {
+ def : Pat<(VT (Op (VT (concat_vectors
+ (HalfVT (trunc (WideEltVT (bitconvert (VT FPR128:$Rn))))),
+ (HalfVT undef))),
+ (VT (AArch64uzp2 (VT FPR128:$Rn), (VT undef))))),
+ (Inst $Rn, $Rn)>;
+}
+
+defm : PairwiseXtnUzp2BinOpWide<add_like, v16i8, v8i8, v8i16, ADDPv16i8>;
+defm : PairwiseXtnUzp2BinOpWide<add_like, v8i16, v4i16, v4i32, ADDPv8i16>;
+defm : PairwiseXtnUzp2BinOpWide<add_like, v4i32, v2i32, v2i64, ADDPv4i32>;
+
defm : PairwiseZIPBinOp<fadd, v2f64, FPR128, FADDPv2f64>;
defm : PairwiseZIPBinOp<fadd, v2f32, FPR64, FADDPv2f32>;
defm : PairwiseUZPBinOp<fadd, v4f32, FPR128, FADDPv4f32>;
diff --git a/llvm/test/CodeGen/AArch64/addp-shuffle.ll b/llvm/test/CodeGen/AArch64/addp-shuffle.ll
index b565bfe14c2ed..1f313e7ca1e7e 100644
--- a/llvm/test/CodeGen/AArch64/addp-shuffle.ll
+++ b/llvm/test/CodeGen/AArch64/addp-shuffle.ll
@@ -562,3 +562,70 @@ entry:
%1 = extractelement <2 x i64> %0, i32 0
ret i64 %1
}
+
+define <16 x i8> @xtn_uzp2_v16i8_add(<16 x i8> %x) {
+; CHECK-LABEL: xtn_uzp2_v16i8_add:
+; CHECK: // %bb.0:
+; CHECK-NEXT: addp v0.16b, v0.16b, v0.16b
+; CHECK-NEXT: ret
+ %e = shufflevector <16 x i8> %x, <16 x i8> poison, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+ %o = shufflevector <16 x i8> %x, <16 x i8> poison, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+ %r = add <16 x i8> %e, %o
+ ret <16 x i8> %r
+}
+
+define <16 x i8> @xtn_uzp2_v16i8_or(<16 x i8> %x) {
+; CHECK-LABEL: xtn_uzp2_v16i8_or:
+; CHECK: // %bb.0:
+; CHECK-NEXT: addp v0.16b, v0.16b, v0.16b
+; CHECK-NEXT: ret
+ %e = shufflevector <16 x i8> %x, <16 x i8> poison, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+ %o = shufflevector <16 x i8> %x, <16 x i8> poison, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+ %r = or disjoint <16 x i8> %e, %o
+ ret <16 x i8> %r
+}
+
+define <8 x i16> @xtn_uzp2_v8i16_add(<8 x i16> %x) {
+; CHECK-LABEL: xtn_uzp2_v8i16_add:
+; CHECK: // %bb.0:
+; CHECK-NEXT: addp v0.8h, v0.8h, v0.8h
+; CHECK-NEXT: ret
+ %e = shufflevector <8 x i16> %x, <8 x i16> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 poison, i32 poison, i32 poison, i32 poison>
+ %o = shufflevector <8 x i16> %x, <8 x i16> poison, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 poison, i32 poison, i32 poison, i32 poison>
+ %r = add <8 x i16> %e, %o
+ ret <8 x i16> %r
+}
+
+define <8 x i16> @xtn_uzp2_v8i16_or(<8 x i16> %x) {
+; CHECK-LABEL: xtn_uzp2_v8i16_or:
+; CHECK: // %bb.0:
+; CHECK-NEXT: addp v0.8h, v0.8h, v0.8h
+; CHECK-NEXT: ret
+ %e = shufflevector <8 x i16> %x, <8 x i16> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 poison, i32 poison, i32 poison, i32 poison>
+ %o = shufflevector <8 x i16> %x, <8 x i16> poison, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 poison, i32 poison, i32 poison, i32 poison>
+ %r = or disjoint <8 x i16> %e, %o
+ ret <8 x i16> %r
+}
+
+define <4 x i32> @xtn_uzp2_v4i32_add(<4 x i32> %x) {
+; CHECK-LABEL: xtn_uzp2_v4i32_add:
+; CHECK: // %bb.0:
+; CHECK-NEXT: addp v0.4s, v0.4s, v0.4s
+; CHECK-NEXT: ret
+ %e = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 0, i32 2, i32 poison, i32 poison>
+ %o = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 1, i32 3, i32 poison, i32 poison>
+ %r = add <4 x i32> %e, %o
+ ret <4 x i32> %r
+}
+
+define <4 x i32> @xtn_uzp2_v4i32_or(<4 x i32> %x) {
+; CHECK-LABEL: xtn_uzp2_v4i32_or:
+; CHECK: // %bb.0:
+; CHECK-NEXT: addp v0.4s, v0.4s, v0.4s
+; CHECK-NEXT: ret
+ %e = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 0, i32 2, i32 poison, i32 poison>
+ %o = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> <i32 1, i32 3, i32 poison, i32 poison>
+ %r = or disjoint <4 x i32> %e, %o
+ ret <4 x i32> %r
+}
+
More information about the llvm-commits
mailing list