[llvm] [AArch64] Avoid ld4 lowering for deinterleave4 feeding uitofp (PR #200763)
Kamlesh Kumar via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 03:56:57 PDT 2026
https://github.com/kamleshbhalui updated https://github.com/llvm/llvm-project/pull/200763
>From 76b891e722f2800405d73c12ed1b89ffc64f3393 Mon Sep 17 00:00:00 2001
From: Kamlesh Kumar <kamlesh.kumar at arm.com>
Date: Mon, 1 Jun 2026 10:18:42 +0000
Subject: [PATCH 1/3] [AArch64] Add deinterleave4 uitofp tests
---
.../aarch64-deinterleave4-i16-to-fp64.ll | 153 +++++++++++++++
.../aarch64-deinterleave4-i8-to-fp32.ll | 179 ++++++++++++++++++
2 files changed, 332 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
create mode 100644 llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
diff --git a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
new file mode 100644
index 0000000000000..0b9b89b29cdfd
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
@@ -0,0 +1,153 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple aarch64-none-linux-gnu -mattr=+sve | FileCheck %s
+
+
+define <8 x double> @uitofp_fadd_02(ptr %p) {
+; CHECK-LABEL: uitofp_fadd_02:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ld4 { v0.8h, v1.8h, v2.8h, v3.8h }, [x0]
+; CHECK-NEXT: ushll2 v4.4s, v0.8h, #0
+; CHECK-NEXT: ushll v5.4s, v0.4h, #0
+; CHECK-NEXT: ushll2 v6.4s, v1.8h, #0
+; CHECK-NEXT: ushll v7.4s, v1.4h, #0
+; CHECK-NEXT: ushll2 v16.4s, v2.8h, #0
+; CHECK-NEXT: ushll v17.4s, v2.4h, #0
+; CHECK-NEXT: ushll2 v18.4s, v3.8h, #0
+; CHECK-NEXT: ushll v0.4s, v3.4h, #0
+; CHECK-NEXT: ushll2 v1.2d, v4.4s, #0
+; CHECK-NEXT: ushll2 v2.2d, v5.4s, #0
+; CHECK-NEXT: ushll v3.2d, v4.2s, #0
+; CHECK-NEXT: ushll v4.2d, v5.2s, #0
+; CHECK-NEXT: ushll2 v5.2d, v6.4s, #0
+; CHECK-NEXT: ushll2 v19.2d, v7.4s, #0
+; CHECK-NEXT: ushll v6.2d, v6.2s, #0
+; CHECK-NEXT: ushll v7.2d, v7.2s, #0
+; CHECK-NEXT: ushll2 v20.2d, v16.4s, #0
+; CHECK-NEXT: ushll2 v21.2d, v17.4s, #0
+; CHECK-NEXT: ushll v16.2d, v16.2s, #0
+; CHECK-NEXT: ushll v17.2d, v17.2s, #0
+; CHECK-NEXT: ushll v22.2d, v0.2s, #0
+; CHECK-NEXT: ushll2 v23.2d, v18.4s, #0
+; CHECK-NEXT: ushll2 v0.2d, v0.4s, #0
+; CHECK-NEXT: ushll v18.2d, v18.2s, #0
+; CHECK-NEXT: ucvtf v1.2d, v1.2d
+; CHECK-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-NEXT: ucvtf v3.2d, v3.2d
+; CHECK-NEXT: ucvtf v4.2d, v4.2d
+; CHECK-NEXT: ucvtf v5.2d, v5.2d
+; CHECK-NEXT: ucvtf v19.2d, v19.2d
+; CHECK-NEXT: ucvtf v6.2d, v6.2d
+; CHECK-NEXT: ucvtf v7.2d, v7.2d
+; CHECK-NEXT: ucvtf v20.2d, v20.2d
+; CHECK-NEXT: ucvtf v21.2d, v21.2d
+; CHECK-NEXT: ucvtf v16.2d, v16.2d
+; CHECK-NEXT: ucvtf v17.2d, v17.2d
+; CHECK-NEXT: ucvtf v22.2d, v22.2d
+; CHECK-NEXT: ucvtf v23.2d, v23.2d
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: ucvtf v18.2d, v18.2d
+; CHECK-NEXT: fadd v1.2d, v1.2d, v5.2d
+; CHECK-NEXT: fadd v4.2d, v4.2d, v7.2d
+; CHECK-NEXT: fadd v6.2d, v3.2d, v6.2d
+; CHECK-NEXT: fadd v2.2d, v2.2d, v19.2d
+; CHECK-NEXT: fadd v3.2d, v17.2d, v22.2d
+; CHECK-NEXT: fadd v5.2d, v16.2d, v18.2d
+; CHECK-NEXT: fadd v7.2d, v21.2d, v0.2d
+; CHECK-NEXT: fadd v16.2d, v20.2d, v23.2d
+; CHECK-NEXT: fadd v0.2d, v4.2d, v3.2d
+; CHECK-NEXT: fadd v3.2d, v1.2d, v16.2d
+; CHECK-NEXT: fadd v1.2d, v2.2d, v7.2d
+; CHECK-NEXT: fadd v2.2d, v6.2d, v5.2d
+; CHECK-NEXT: ret
+ %l = load <32 x i16>, ptr %p
+ %deint = call {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.vector.deinterleave4(<32 x i16> %l)
+ %s1 = extractvalue {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deint, 0
+ %s2 = extractvalue {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deint, 1
+ %s3 = extractvalue {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deint, 2
+ %s4 = extractvalue {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } %deint, 3
+ %z1 = uitofp <8 x i16> %s1 to <8 x double>
+ %z2 = uitofp <8 x i16> %s2 to <8 x double>
+ %z3 = uitofp <8 x i16> %s3 to <8 x double>
+ %z4 = uitofp <8 x i16> %s4 to <8 x double>
+ %a = fadd <8 x double> %z1, %z2
+ %b = fadd <8 x double> %z3, %z4
+ %c = fadd <8 x double> %a, %b
+ ret <8 x double> %c
+}
+
+define <8 x double> @uitofp_load_fadd(ptr %p) {
+; CHECK-LABEL: uitofp_load_fadd:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldp q3, q2, [x0]
+; CHECK-NEXT: ldp q1, q0, [x0, #32]
+; CHECK-NEXT: ushr v5.2d, v3.2d, #16
+; CHECK-NEXT: ushr v6.2d, v2.2d, #16
+; CHECK-NEXT: ushr v20.2d, v3.2d, #32
+; CHECK-NEXT: ushr v7.2d, v1.2d, #16
+; CHECK-NEXT: ushr v19.2d, v0.2d, #16
+; CHECK-NEXT: ushr v21.2d, v2.2d, #32
+; CHECK-NEXT: ushr v22.2d, v1.2d, #32
+; CHECK-NEXT: ushr v23.2d, v0.2d, #32
+; CHECK-NEXT: movprfx z4, z3
+; CHECK-NEXT: and z4.d, z4.d, #0xffff
+; CHECK-NEXT: movprfx z16, z2
+; CHECK-NEXT: and z16.d, z16.d, #0xffff
+; CHECK-NEXT: movprfx z17, z1
+; CHECK-NEXT: and z17.d, z17.d, #0xffff
+; CHECK-NEXT: movprfx z18, z0
+; CHECK-NEXT: and z18.d, z18.d, #0xffff
+; CHECK-NEXT: and z5.d, z5.d, #0xffff
+; CHECK-NEXT: and z6.d, z6.d, #0xffff
+; CHECK-NEXT: and z7.d, z7.d, #0xffff
+; CHECK-NEXT: and z19.d, z19.d, #0xffff
+; CHECK-NEXT: and z20.d, z20.d, #0xffff
+; CHECK-NEXT: and z21.d, z21.d, #0xffff
+; CHECK-NEXT: and z22.d, z22.d, #0xffff
+; CHECK-NEXT: and z23.d, z23.d, #0xffff
+; CHECK-NEXT: ushr v3.2d, v3.2d, #48
+; CHECK-NEXT: ushr v2.2d, v2.2d, #48
+; CHECK-NEXT: ushr v1.2d, v1.2d, #48
+; CHECK-NEXT: ushr v0.2d, v0.2d, #48
+; CHECK-NEXT: ucvtf v4.2d, v4.2d
+; CHECK-NEXT: ucvtf v16.2d, v16.2d
+; CHECK-NEXT: ucvtf v17.2d, v17.2d
+; CHECK-NEXT: ucvtf v18.2d, v18.2d
+; CHECK-NEXT: ucvtf v5.2d, v5.2d
+; CHECK-NEXT: ucvtf v6.2d, v6.2d
+; CHECK-NEXT: ucvtf v7.2d, v7.2d
+; CHECK-NEXT: ucvtf v19.2d, v19.2d
+; CHECK-NEXT: ucvtf v20.2d, v20.2d
+; CHECK-NEXT: ucvtf v21.2d, v21.2d
+; CHECK-NEXT: ucvtf v22.2d, v22.2d
+; CHECK-NEXT: ucvtf v23.2d, v23.2d
+; CHECK-NEXT: ucvtf v3.2d, v3.2d
+; CHECK-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-NEXT: ucvtf v1.2d, v1.2d
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: fadd v6.2d, v16.2d, v6.2d
+; CHECK-NEXT: fadd v4.2d, v4.2d, v5.2d
+; CHECK-NEXT: fadd v18.2d, v18.2d, v19.2d
+; CHECK-NEXT: fadd v7.2d, v17.2d, v7.2d
+; CHECK-NEXT: fadd v3.2d, v20.2d, v3.2d
+; CHECK-NEXT: fadd v16.2d, v22.2d, v1.2d
+; CHECK-NEXT: fadd v1.2d, v21.2d, v2.2d
+; CHECK-NEXT: fadd v5.2d, v23.2d, v0.2d
+; CHECK-NEXT: fadd v0.2d, v4.2d, v3.2d
+; CHECK-NEXT: fadd v1.2d, v6.2d, v1.2d
+; CHECK-NEXT: fadd v2.2d, v7.2d, v16.2d
+; CHECK-NEXT: fadd v3.2d, v18.2d, v5.2d
+; CHECK-NEXT: ret
+ %l = load <32 x i16>, ptr %p
+ %s1 = shufflevector <32 x i16> %l, <32 x i16> poison, <8 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28>
+ %s2 = shufflevector <32 x i16> %l, <32 x i16> poison, <8 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 29>
+ %s3 = shufflevector <32 x i16> %l, <32 x i16> poison, <8 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30>
+ %s4 = shufflevector <32 x i16> %l, <32 x i16> poison, <8 x i32> <i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 31>
+ %z1 = uitofp <8 x i16> %s1 to <8 x double>
+ %z2 = uitofp <8 x i16> %s2 to <8 x double>
+ %z3 = uitofp <8 x i16> %s3 to <8 x double>
+ %z4 = uitofp <8 x i16> %s4 to <8 x double>
+ %a = fadd <8 x double> %z1, %z2
+ %b = fadd <8 x double> %z3, %z4
+ %c = fadd <8 x double> %a, %b
+ ret <8 x double> %c
+}
diff --git a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
new file mode 100644
index 0000000000000..fe0a7d3fdb373
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
@@ -0,0 +1,179 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple aarch64-none-linux-gnu -mattr=+sve | FileCheck %s
+
+define void @deinterleave_intrinsic_uitofp(ptr %src, ptr %dst0, ptr %dst1,
+; CHECK-LABEL: deinterleave_intrinsic_uitofp:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: cbz x5, .LBB0_3
+; CHECK-NEXT: // %bb.1: // %loop.preheader
+; CHECK-NEXT: adrp x8, .LCPI0_0
+; CHECK-NEXT: adrp x9, .LCPI0_1
+; CHECK-NEXT: ldr q0, [x8, :lo12:.LCPI0_0]
+; CHECK-NEXT: ldr q1, [x9, :lo12:.LCPI0_1]
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB0_2: // %loop
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lsl x9, x8, #5
+; CHECK-NEXT: add x8, x8, #1
+; CHECK-NEXT: cmp x8, x5
+; CHECK-NEXT: add x10, x0, x9
+; CHECK-NEXT: add x11, x2, x9
+; CHECK-NEXT: ld4 { v2.8b, v3.8b, v4.8b, v5.8b }, [x10]
+; CHECK-NEXT: add x10, x1, x9
+; CHECK-NEXT: tbl v6.16b, { v2.16b }, v0.16b
+; CHECK-NEXT: tbl v7.16b, { v2.16b }, v1.16b
+; CHECK-NEXT: tbl v16.16b, { v3.16b }, v0.16b
+; CHECK-NEXT: tbl v17.16b, { v3.16b }, v1.16b
+; CHECK-NEXT: tbl v18.16b, { v4.16b }, v0.16b
+; CHECK-NEXT: tbl v19.16b, { v4.16b }, v1.16b
+; CHECK-NEXT: tbl v20.16b, { v5.16b }, v0.16b
+; CHECK-NEXT: tbl v2.16b, { v5.16b }, v1.16b
+; CHECK-NEXT: ucvtf v6.4s, v6.4s
+; CHECK-NEXT: ucvtf v7.4s, v7.4s
+; CHECK-NEXT: ucvtf v16.4s, v16.4s
+; CHECK-NEXT: ucvtf v3.4s, v17.4s
+; CHECK-NEXT: ucvtf v4.4s, v18.4s
+; CHECK-NEXT: ucvtf v5.4s, v19.4s
+; CHECK-NEXT: ucvtf v2.4s, v2.4s
+; CHECK-NEXT: stp q7, q6, [x10]
+; CHECK-NEXT: ucvtf v6.4s, v20.4s
+; CHECK-NEXT: add x10, x3, x9
+; CHECK-NEXT: add x9, x4, x9
+; CHECK-NEXT: stp q3, q16, [x11]
+; CHECK-NEXT: stp q5, q4, [x10]
+; CHECK-NEXT: stp q2, q6, [x9]
+; CHECK-NEXT: b.lo .LBB0_2
+; CHECK-NEXT: .LBB0_3: // %exit
+; CHECK-NEXT: ret
+ptr %dst2, ptr %dst3, i64 %n) {
+entry:
+%empty = icmp eq i64 %n, 0
+br i1 %empty, label %exit, label %loop
+
+loop:
+%i = phi i64 [ 0, %entry ], [ %next, %loop ]
+%src.off = mul i64 %i, 32
+%dst.off = mul i64 %i, 8
+%src.ptr = getelementptr i8, ptr %src, i64 %src.off
+%p0 = getelementptr float, ptr %dst0, i64 %dst.off
+%p1 = getelementptr float, ptr %dst1, i64 %dst.off
+%p2 = getelementptr float, ptr %dst2, i64 %dst.off
+%p3 = getelementptr float, ptr %dst3, i64 %dst.off
+
+%wide = load <32 x i8>, ptr %src.ptr, align 1
+%di = call { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } @llvm.vector.deinterleave4.v32i8(<32 x i8> %wide)
+
+%v0 = extractvalue { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } %di, 0
+%v1 = extractvalue { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } %di, 1
+%v2 = extractvalue { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } %di, 2
+%v3 = extractvalue { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } %di, 3
+
+%f0 = uitofp <8 x i8> %v0 to <8 x float>
+%f1 = uitofp <8 x i8> %v1 to <8 x float>
+%f2 = uitofp <8 x i8> %v2 to <8 x float>
+%f3 = uitofp <8 x i8> %v3 to <8 x float>
+
+store <8 x float> %f0, ptr %p0, align 4
+store <8 x float> %f1, ptr %p1, align 4
+store <8 x float> %f2, ptr %p2, align 4
+store <8 x float> %f3, ptr %p3, align 4
+
+%next = add i64 %i, 1
+%more = icmp ult i64 %next, %n
+br i1 %more, label %loop, label %exit
+
+exit:
+ret void
+}
+
+define void @shuffle_uitofp(ptr %src, ptr %dst0, ptr %dst1,
+; CHECK-LABEL: shuffle_uitofp:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: cbz x5, .LBB1_3
+; CHECK-NEXT: // %bb.1: // %loop.preheader
+; CHECK-NEXT: adrp x8, .LCPI1_0
+; CHECK-NEXT: adrp x9, .LCPI1_1
+; CHECK-NEXT: adrp x10, .LCPI1_2
+; CHECK-NEXT: adrp x11, .LCPI1_3
+; CHECK-NEXT: ldr q0, [x8, :lo12:.LCPI1_0]
+; CHECK-NEXT: ldr q1, [x9, :lo12:.LCPI1_1]
+; CHECK-NEXT: ldr q2, [x10, :lo12:.LCPI1_2]
+; CHECK-NEXT: ldr q3, [x11, :lo12:.LCPI1_3]
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB1_2: // %loop
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lsl x9, x8, #5
+; CHECK-NEXT: add x8, x8, #1
+; CHECK-NEXT: cmp x8, x5
+; CHECK-NEXT: add x10, x0, x9
+; CHECK-NEXT: add x11, x2, x9
+; CHECK-NEXT: ldp q5, q4, [x10]
+; CHECK-NEXT: add x10, x1, x9
+; CHECK-NEXT: tbl v6.16b, { v4.16b }, v0.16b
+; CHECK-NEXT: tbl v7.16b, { v5.16b }, v0.16b
+; CHECK-NEXT: tbl v16.16b, { v4.16b }, v1.16b
+; CHECK-NEXT: tbl v17.16b, { v5.16b }, v1.16b
+; CHECK-NEXT: tbl v18.16b, { v4.16b }, v2.16b
+; CHECK-NEXT: tbl v19.16b, { v5.16b }, v2.16b
+; CHECK-NEXT: tbl v4.16b, { v4.16b }, v3.16b
+; CHECK-NEXT: tbl v5.16b, { v5.16b }, v3.16b
+; CHECK-NEXT: ucvtf v6.4s, v6.4s
+; CHECK-NEXT: ucvtf v7.4s, v7.4s
+; CHECK-NEXT: ucvtf v16.4s, v16.4s
+; CHECK-NEXT: ucvtf v17.4s, v17.4s
+; CHECK-NEXT: ucvtf v18.4s, v18.4s
+; CHECK-NEXT: ucvtf v4.4s, v4.4s
+; CHECK-NEXT: ucvtf v5.4s, v5.4s
+; CHECK-NEXT: stp q7, q6, [x10]
+; CHECK-NEXT: ucvtf v6.4s, v19.4s
+; CHECK-NEXT: add x10, x3, x9
+; CHECK-NEXT: add x9, x4, x9
+; CHECK-NEXT: stp q17, q16, [x11]
+; CHECK-NEXT: stp q6, q18, [x10]
+; CHECK-NEXT: stp q5, q4, [x9]
+; CHECK-NEXT: b.lo .LBB1_2
+; CHECK-NEXT: .LBB1_3: // %exit
+; CHECK-NEXT: ret
+ptr %dst2, ptr %dst3, i64 %n) {
+entry:
+%empty = icmp eq i64 %n, 0
+br i1 %empty, label %exit, label %loop
+
+loop:
+%i = phi i64 [ 0, %entry ], [ %next, %loop ]
+%src.off = mul i64 %i, 32
+%dst.off = mul i64 %i, 8
+%src.ptr = getelementptr i8, ptr %src, i64 %src.off
+%p0 = getelementptr float, ptr %dst0, i64 %dst.off
+%p1 = getelementptr float, ptr %dst1, i64 %dst.off
+%p2 = getelementptr float, ptr %dst2, i64 %dst.off
+%p3 = getelementptr float, ptr %dst3, i64 %dst.off
+
+%wide = load <32 x i8>, ptr %src.ptr, align 1
+
+%v0 = shufflevector <32 x i8> %wide, <32 x i8> poison,
+<8 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28>
+%v1 = shufflevector <32 x i8> %wide, <32 x i8> poison,
+<8 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 29>
+%v2 = shufflevector <32 x i8> %wide, <32 x i8> poison,
+<8 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30>
+%v3 = shufflevector <32 x i8> %wide, <32 x i8> poison,
+<8 x i32> <i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 31>
+
+%f0 = uitofp <8 x i8> %v0 to <8 x float>
+%f1 = uitofp <8 x i8> %v1 to <8 x float>
+%f2 = uitofp <8 x i8> %v2 to <8 x float>
+%f3 = uitofp <8 x i8> %v3 to <8 x float>
+
+store <8 x float> %f0, ptr %p0, align 4
+store <8 x float> %f1, ptr %p1, align 4
+store <8 x float> %f2, ptr %p2, align 4
+store <8 x float> %f3, ptr %p3, align 4
+
+%next = add i64 %i, 1
+%more = icmp ult i64 %next, %n
+br i1 %more, label %loop, label %exit
+
+exit:
+ret void
+}
>From e6a4c24258e280c26b64138720f0d70a2b9658b2 Mon Sep 17 00:00:00 2001
From: Kamlesh Kumar <kamlesh.kumar at arm.com>
Date: Mon, 1 Jun 2026 10:40:01 +0000
Subject: [PATCH 2/3] [AArch64] Avoid ld4 lowering for deinterleave4 feeding
uitofp
ld4 appears to be significantly slower than ldp for widening uitofp
---
.../Target/AArch64/AArch64ISelLowering.cpp | 24 +++++
.../aarch64-deinterleave4-i16-to-fp64.ll | 87 ++++++++++---------
.../aarch64-deinterleave4-i8-to-fp32.ll | 43 +++++----
3 files changed, 98 insertions(+), 56 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index aa137b8f675af..0994341cdb7a1 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -19011,6 +19011,24 @@ bool AArch64TargetLowering::lowerInterleavedStore(Instruction *Store,
return true;
}
+static bool hasSingleWideningUIToFPUse(Value *V) {
+ using namespace llvm::PatternMatch;
+ if (!V->hasOneUse())
+ return false;
+ auto *UserInst = dyn_cast<Instruction>(V->user_back());
+ return UserInst && match(UserInst, m_UIToFP(m_Specific(V))) &&
+ V->getType()->getScalarSizeInBits() * 4 ==
+ UserInst->getType()->getScalarSizeInBits();
+}
+
+static bool areAllDeinterleaveUsersWideningUIToFP(IntrinsicInst *DI,
+ VectorType *VTy) {
+ return all_of(DI->users(), [VTy](User *U) {
+ auto *EV = dyn_cast<ExtractValueInst>(U);
+ return EV && EV->getType() == VTy && hasSingleWideningUIToFPUse(EV);
+ });
+}
+
bool AArch64TargetLowering::lowerDeinterleaveIntrinsicToLoad(
Instruction *Load, Value *Mask, IntrinsicInst *DI,
const APInt &GapMask) const {
@@ -19041,6 +19059,12 @@ bool AArch64TargetLowering::lowerDeinterleaveIntrinsicToLoad(
if (UseScalable && !VTy->isScalableTy())
return false;
+ // When all deinterleaved results feed into widening uitofp operations,
+ // avoid lowering through ld4 so existing shuffle lowering can optimize them.
+ if (Factor == 4 && !VTy->isScalableTy() &&
+ areAllDeinterleaveUsersWideningUIToFP(DI, VTy))
+ return false;
+
unsigned NumLoads = getNumInterleavedAccesses(VTy, DL, UseScalable);
VectorType *LdTy =
VectorType::get(VTy->getElementType(),
diff --git a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
index 0b9b89b29cdfd..b9e15ca107b8a 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
@@ -5,59 +5,68 @@
define <8 x double> @uitofp_fadd_02(ptr %p) {
; CHECK-LABEL: uitofp_fadd_02:
; CHECK: // %bb.0:
-; CHECK-NEXT: ld4 { v0.8h, v1.8h, v2.8h, v3.8h }, [x0]
-; CHECK-NEXT: ushll2 v4.4s, v0.8h, #0
-; CHECK-NEXT: ushll v5.4s, v0.4h, #0
-; CHECK-NEXT: ushll2 v6.4s, v1.8h, #0
-; CHECK-NEXT: ushll v7.4s, v1.4h, #0
-; CHECK-NEXT: ushll2 v16.4s, v2.8h, #0
-; CHECK-NEXT: ushll v17.4s, v2.4h, #0
-; CHECK-NEXT: ushll2 v18.4s, v3.8h, #0
-; CHECK-NEXT: ushll v0.4s, v3.4h, #0
-; CHECK-NEXT: ushll2 v1.2d, v4.4s, #0
-; CHECK-NEXT: ushll2 v2.2d, v5.4s, #0
-; CHECK-NEXT: ushll v3.2d, v4.2s, #0
-; CHECK-NEXT: ushll v4.2d, v5.2s, #0
-; CHECK-NEXT: ushll2 v5.2d, v6.4s, #0
+; CHECK-NEXT: ldp q1, q0, [x0]
+; CHECK-NEXT: ldp q3, q2, [x0, #32]
+; CHECK-NEXT: uzp1 v5.8h, v1.8h, v0.8h
+; CHECK-NEXT: uzp2 v0.8h, v1.8h, v0.8h
+; CHECK-NEXT: uzp1 v4.8h, v3.8h, v2.8h
+; CHECK-NEXT: uzp2 v2.8h, v3.8h, v2.8h
+; CHECK-NEXT: movprfx z1, z5
+; CHECK-NEXT: and z1.s, z1.s, #0xffff
+; CHECK-NEXT: movprfx z6, z0
+; CHECK-NEXT: and z6.s, z6.s, #0xffff
+; CHECK-NEXT: ushr v5.4s, v5.4s, #16
+; CHECK-NEXT: movprfx z3, z4
+; CHECK-NEXT: and z3.s, z3.s, #0xffff
+; CHECK-NEXT: movprfx z7, z2
+; CHECK-NEXT: and z7.s, z7.s, #0xffff
+; CHECK-NEXT: ushr v4.4s, v4.4s, #16
+; CHECK-NEXT: ushr v0.4s, v0.4s, #16
+; CHECK-NEXT: ushr v2.4s, v2.4s, #16
+; CHECK-NEXT: ushll2 v16.2d, v1.4s, #0
+; CHECK-NEXT: ushll v1.2d, v1.2s, #0
+; CHECK-NEXT: ushll2 v18.2d, v6.4s, #0
+; CHECK-NEXT: ushll2 v17.2d, v3.4s, #0
+; CHECK-NEXT: ushll v3.2d, v3.2s, #0
; CHECK-NEXT: ushll2 v19.2d, v7.4s, #0
; CHECK-NEXT: ushll v6.2d, v6.2s, #0
; CHECK-NEXT: ushll v7.2d, v7.2s, #0
-; CHECK-NEXT: ushll2 v20.2d, v16.4s, #0
-; CHECK-NEXT: ushll2 v21.2d, v17.4s, #0
-; CHECK-NEXT: ushll v16.2d, v16.2s, #0
-; CHECK-NEXT: ushll v17.2d, v17.2s, #0
+; CHECK-NEXT: ushll2 v20.2d, v5.4s, #0
+; CHECK-NEXT: ushll2 v21.2d, v4.4s, #0
+; CHECK-NEXT: ushll v5.2d, v5.2s, #0
+; CHECK-NEXT: ushll v4.2d, v4.2s, #0
; CHECK-NEXT: ushll v22.2d, v0.2s, #0
-; CHECK-NEXT: ushll2 v23.2d, v18.4s, #0
; CHECK-NEXT: ushll2 v0.2d, v0.4s, #0
-; CHECK-NEXT: ushll v18.2d, v18.2s, #0
+; CHECK-NEXT: ushll2 v23.2d, v2.4s, #0
+; CHECK-NEXT: ushll v2.2d, v2.2s, #0
+; CHECK-NEXT: ucvtf v16.2d, v16.2d
+; CHECK-NEXT: ucvtf v17.2d, v17.2d
; CHECK-NEXT: ucvtf v1.2d, v1.2d
-; CHECK-NEXT: ucvtf v2.2d, v2.2d
; CHECK-NEXT: ucvtf v3.2d, v3.2d
-; CHECK-NEXT: ucvtf v4.2d, v4.2d
-; CHECK-NEXT: ucvtf v5.2d, v5.2d
+; CHECK-NEXT: ucvtf v18.2d, v18.2d
; CHECK-NEXT: ucvtf v19.2d, v19.2d
; CHECK-NEXT: ucvtf v6.2d, v6.2d
; CHECK-NEXT: ucvtf v7.2d, v7.2d
; CHECK-NEXT: ucvtf v20.2d, v20.2d
; CHECK-NEXT: ucvtf v21.2d, v21.2d
-; CHECK-NEXT: ucvtf v16.2d, v16.2d
-; CHECK-NEXT: ucvtf v17.2d, v17.2d
+; CHECK-NEXT: ucvtf v5.2d, v5.2d
+; CHECK-NEXT: ucvtf v4.2d, v4.2d
; CHECK-NEXT: ucvtf v22.2d, v22.2d
-; CHECK-NEXT: ucvtf v23.2d, v23.2d
; CHECK-NEXT: ucvtf v0.2d, v0.2d
-; CHECK-NEXT: ucvtf v18.2d, v18.2d
-; CHECK-NEXT: fadd v1.2d, v1.2d, v5.2d
-; CHECK-NEXT: fadd v4.2d, v4.2d, v7.2d
-; CHECK-NEXT: fadd v6.2d, v3.2d, v6.2d
-; CHECK-NEXT: fadd v2.2d, v2.2d, v19.2d
-; CHECK-NEXT: fadd v3.2d, v17.2d, v22.2d
-; CHECK-NEXT: fadd v5.2d, v16.2d, v18.2d
-; CHECK-NEXT: fadd v7.2d, v21.2d, v0.2d
-; CHECK-NEXT: fadd v16.2d, v20.2d, v23.2d
-; CHECK-NEXT: fadd v0.2d, v4.2d, v3.2d
-; CHECK-NEXT: fadd v3.2d, v1.2d, v16.2d
-; CHECK-NEXT: fadd v1.2d, v2.2d, v7.2d
-; CHECK-NEXT: fadd v2.2d, v6.2d, v5.2d
+; CHECK-NEXT: ucvtf v23.2d, v23.2d
+; CHECK-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-NEXT: fadd v7.2d, v3.2d, v7.2d
+; CHECK-NEXT: fadd v1.2d, v1.2d, v6.2d
+; CHECK-NEXT: fadd v3.2d, v17.2d, v19.2d
+; CHECK-NEXT: fadd v6.2d, v16.2d, v18.2d
+; CHECK-NEXT: fadd v5.2d, v5.2d, v22.2d
+; CHECK-NEXT: fadd v16.2d, v20.2d, v0.2d
+; CHECK-NEXT: fadd v2.2d, v4.2d, v2.2d
+; CHECK-NEXT: fadd v4.2d, v21.2d, v23.2d
+; CHECK-NEXT: fadd v0.2d, v1.2d, v5.2d
+; CHECK-NEXT: fadd v1.2d, v6.2d, v16.2d
+; CHECK-NEXT: fadd v3.2d, v3.2d, v4.2d
+; CHECK-NEXT: fadd v2.2d, v7.2d, v2.2d
; CHECK-NEXT: ret
%l = load <32 x i16>, ptr %p
%deint = call {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.vector.deinterleave4(<32 x i16> %l)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
index fe0a7d3fdb373..f6e540d10cadc 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
@@ -18,30 +18,39 @@ define void @deinterleave_intrinsic_uitofp(ptr %src, ptr %dst0, ptr %dst1,
; CHECK-NEXT: cmp x8, x5
; CHECK-NEXT: add x10, x0, x9
; CHECK-NEXT: add x11, x2, x9
-; CHECK-NEXT: ld4 { v2.8b, v3.8b, v4.8b, v5.8b }, [x10]
+; CHECK-NEXT: ldp q2, q3, [x10]
; CHECK-NEXT: add x10, x1, x9
-; CHECK-NEXT: tbl v6.16b, { v2.16b }, v0.16b
-; CHECK-NEXT: tbl v7.16b, { v2.16b }, v1.16b
-; CHECK-NEXT: tbl v16.16b, { v3.16b }, v0.16b
-; CHECK-NEXT: tbl v17.16b, { v3.16b }, v1.16b
-; CHECK-NEXT: tbl v18.16b, { v4.16b }, v0.16b
-; CHECK-NEXT: tbl v19.16b, { v4.16b }, v1.16b
-; CHECK-NEXT: tbl v20.16b, { v5.16b }, v0.16b
-; CHECK-NEXT: tbl v2.16b, { v5.16b }, v1.16b
+; CHECK-NEXT: uzp1 v4.16b, v2.16b, v3.16b
+; CHECK-NEXT: uzp2 v5.16b, v3.16b, v0.16b
+; CHECK-NEXT: uzp2 v6.16b, v2.16b, v0.16b
+; CHECK-NEXT: xtn v3.8b, v3.8h
+; CHECK-NEXT: xtn v2.8b, v2.8h
+; CHECK-NEXT: xtn v4.8b, v4.8h
+; CHECK-NEXT: uzp1 v7.8b, v6.8b, v5.8b
+; CHECK-NEXT: uzp2 v5.8b, v6.8b, v5.8b
+; CHECK-NEXT: uzp2 v2.8b, v2.8b, v3.8b
+; CHECK-NEXT: tbl v3.16b, { v4.16b }, v0.16b
+; CHECK-NEXT: tbl v4.16b, { v4.16b }, v1.16b
+; CHECK-NEXT: tbl v6.16b, { v7.16b }, v0.16b
+; CHECK-NEXT: tbl v7.16b, { v7.16b }, v1.16b
+; CHECK-NEXT: tbl v16.16b, { v2.16b }, v0.16b
+; CHECK-NEXT: tbl v2.16b, { v2.16b }, v1.16b
+; CHECK-NEXT: tbl v17.16b, { v5.16b }, v0.16b
+; CHECK-NEXT: tbl v5.16b, { v5.16b }, v1.16b
+; CHECK-NEXT: ucvtf v3.4s, v3.4s
+; CHECK-NEXT: ucvtf v4.4s, v4.4s
; CHECK-NEXT: ucvtf v6.4s, v6.4s
; CHECK-NEXT: ucvtf v7.4s, v7.4s
; CHECK-NEXT: ucvtf v16.4s, v16.4s
-; CHECK-NEXT: ucvtf v3.4s, v17.4s
-; CHECK-NEXT: ucvtf v4.4s, v18.4s
-; CHECK-NEXT: ucvtf v5.4s, v19.4s
; CHECK-NEXT: ucvtf v2.4s, v2.4s
-; CHECK-NEXT: stp q7, q6, [x10]
-; CHECK-NEXT: ucvtf v6.4s, v20.4s
+; CHECK-NEXT: stp q4, q3, [x10]
+; CHECK-NEXT: ucvtf v3.4s, v17.4s
+; CHECK-NEXT: ucvtf v4.4s, v5.4s
; CHECK-NEXT: add x10, x3, x9
; CHECK-NEXT: add x9, x4, x9
-; CHECK-NEXT: stp q3, q16, [x11]
-; CHECK-NEXT: stp q5, q4, [x10]
-; CHECK-NEXT: stp q2, q6, [x9]
+; CHECK-NEXT: stp q7, q6, [x11]
+; CHECK-NEXT: stp q2, q16, [x10]
+; CHECK-NEXT: stp q4, q3, [x9]
; CHECK-NEXT: b.lo .LBB0_2
; CHECK-NEXT: .LBB0_3: // %exit
; CHECK-NEXT: ret
>From 78f43a9ac0dd1a084955005a2031a627571eafed Mon Sep 17 00:00:00 2001
From: Kamlesh Kumar <kamlesh.kumar at arm.com>
Date: Mon, 1 Jun 2026 10:41:47 +0000
Subject: [PATCH 3/3] [AArch64] Lower deinterleave4 load to shuffles
Convert fixed-width vector.deinterleave4 load to an equivalent
wide load and shuffles when all users are widening uitofp,
to benefit from existing shufflevector optimizations.
---
.../Target/AArch64/AArch64ISelLowering.cpp | 38 ++++++-
.../aarch64-deinterleave4-i16-to-fp64.ll | 100 +++++++++---------
.../aarch64-deinterleave4-i8-to-fp32.ll | 49 ++++-----
3 files changed, 104 insertions(+), 83 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 0994341cdb7a1..59c0440ffb7d0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -19029,6 +19029,35 @@ static bool areAllDeinterleaveUsersWideningUIToFP(IntrinsicInst *DI,
});
}
+static bool tryLowerDeinterleave4UIToFPLoadToShuffle(LoadInst *LI,
+ IntrinsicInst *DI,
+ VectorType *VTy) {
+ if (!areAllDeinterleaveUsersWideningUIToFP(DI, VTy))
+ return false;
+
+ constexpr unsigned Factor = 4;
+ auto *FVTy = cast<FixedVectorType>(VTy);
+ unsigned SubElts = FVTy->getNumElements();
+ unsigned WideElts = SubElts * Factor;
+ auto *WideTy = FixedVectorType::get(FVTy->getElementType(), WideElts);
+ assert(LI->getType() == WideTy &&
+ "Unexpected load type for deinterleave intrinsic");
+
+ IRBuilder<> Builder(LI);
+ LoadInst *ClonedLI = cast<LoadInst>(LI->clone());
+ Builder.Insert(ClonedLI);
+ Value *Result = PoisonValue::get(DI->getType());
+ for (unsigned I = 0; I < Factor; ++I) {
+ SmallVector<int, 16> Mask(SubElts);
+ for (unsigned J = 0; J < SubElts; ++J)
+ Mask[J] = I + J * Factor;
+ Value *Shuf = Builder.CreateShuffleVector(ClonedLI, Mask);
+ Result = Builder.CreateInsertValue(Result, Shuf, I);
+ }
+ DI->replaceAllUsesWith(Result);
+ return true;
+}
+
bool AArch64TargetLowering::lowerDeinterleaveIntrinsicToLoad(
Instruction *Load, Value *Mask, IntrinsicInst *DI,
const APInt &GapMask) const {
@@ -19059,11 +19088,12 @@ bool AArch64TargetLowering::lowerDeinterleaveIntrinsicToLoad(
if (UseScalable && !VTy->isScalableTy())
return false;
- // When all deinterleaved results feed into widening uitofp operations,
- // avoid lowering through ld4 so existing shuffle lowering can optimize them.
+ // When all deinterleaved results feed into uitofp,
+ // Convert the deinterleaved intrinsic load to wider load + shuffle
+ // to benefit from existing shufflevector optimizations.
if (Factor == 4 && !VTy->isScalableTy() &&
- areAllDeinterleaveUsersWideningUIToFP(DI, VTy))
- return false;
+ tryLowerDeinterleave4UIToFPLoadToShuffle(LI, DI, VTy))
+ return true;
unsigned NumLoads = getNumInterleavedAccesses(VTy, DL, UseScalable);
VectorType *LdTy =
diff --git a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
index b9e15ca107b8a..32d85cdbf3745 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i16-to-fp64.ll
@@ -5,68 +5,64 @@
define <8 x double> @uitofp_fadd_02(ptr %p) {
; CHECK-LABEL: uitofp_fadd_02:
; CHECK: // %bb.0:
-; CHECK-NEXT: ldp q1, q0, [x0]
-; CHECK-NEXT: ldp q3, q2, [x0, #32]
-; CHECK-NEXT: uzp1 v5.8h, v1.8h, v0.8h
-; CHECK-NEXT: uzp2 v0.8h, v1.8h, v0.8h
-; CHECK-NEXT: uzp1 v4.8h, v3.8h, v2.8h
-; CHECK-NEXT: uzp2 v2.8h, v3.8h, v2.8h
-; CHECK-NEXT: movprfx z1, z5
-; CHECK-NEXT: and z1.s, z1.s, #0xffff
-; CHECK-NEXT: movprfx z6, z0
-; CHECK-NEXT: and z6.s, z6.s, #0xffff
-; CHECK-NEXT: ushr v5.4s, v5.4s, #16
-; CHECK-NEXT: movprfx z3, z4
-; CHECK-NEXT: and z3.s, z3.s, #0xffff
-; CHECK-NEXT: movprfx z7, z2
-; CHECK-NEXT: and z7.s, z7.s, #0xffff
-; CHECK-NEXT: ushr v4.4s, v4.4s, #16
-; CHECK-NEXT: ushr v0.4s, v0.4s, #16
-; CHECK-NEXT: ushr v2.4s, v2.4s, #16
-; CHECK-NEXT: ushll2 v16.2d, v1.4s, #0
-; CHECK-NEXT: ushll v1.2d, v1.2s, #0
-; CHECK-NEXT: ushll2 v18.2d, v6.4s, #0
-; CHECK-NEXT: ushll2 v17.2d, v3.4s, #0
-; CHECK-NEXT: ushll v3.2d, v3.2s, #0
-; CHECK-NEXT: ushll2 v19.2d, v7.4s, #0
-; CHECK-NEXT: ushll v6.2d, v6.2s, #0
-; CHECK-NEXT: ushll v7.2d, v7.2s, #0
-; CHECK-NEXT: ushll2 v20.2d, v5.4s, #0
-; CHECK-NEXT: ushll2 v21.2d, v4.4s, #0
-; CHECK-NEXT: ushll v5.2d, v5.2s, #0
-; CHECK-NEXT: ushll v4.2d, v4.2s, #0
-; CHECK-NEXT: ushll v22.2d, v0.2s, #0
-; CHECK-NEXT: ushll2 v0.2d, v0.4s, #0
-; CHECK-NEXT: ushll2 v23.2d, v2.4s, #0
-; CHECK-NEXT: ushll v2.2d, v2.2s, #0
+; CHECK-NEXT: ldp q3, q2, [x0]
+; CHECK-NEXT: ldp q1, q0, [x0, #32]
+; CHECK-NEXT: ushr v5.2d, v3.2d, #16
+; CHECK-NEXT: ushr v6.2d, v2.2d, #16
+; CHECK-NEXT: ushr v20.2d, v3.2d, #32
+; CHECK-NEXT: ushr v7.2d, v1.2d, #16
+; CHECK-NEXT: ushr v19.2d, v0.2d, #16
+; CHECK-NEXT: ushr v21.2d, v2.2d, #32
+; CHECK-NEXT: ushr v22.2d, v1.2d, #32
+; CHECK-NEXT: ushr v23.2d, v0.2d, #32
+; CHECK-NEXT: movprfx z4, z3
+; CHECK-NEXT: and z4.d, z4.d, #0xffff
+; CHECK-NEXT: movprfx z16, z2
+; CHECK-NEXT: and z16.d, z16.d, #0xffff
+; CHECK-NEXT: movprfx z17, z1
+; CHECK-NEXT: and z17.d, z17.d, #0xffff
+; CHECK-NEXT: movprfx z18, z0
+; CHECK-NEXT: and z18.d, z18.d, #0xffff
+; CHECK-NEXT: and z5.d, z5.d, #0xffff
+; CHECK-NEXT: and z6.d, z6.d, #0xffff
+; CHECK-NEXT: and z7.d, z7.d, #0xffff
+; CHECK-NEXT: and z19.d, z19.d, #0xffff
+; CHECK-NEXT: and z20.d, z20.d, #0xffff
+; CHECK-NEXT: and z21.d, z21.d, #0xffff
+; CHECK-NEXT: and z22.d, z22.d, #0xffff
+; CHECK-NEXT: and z23.d, z23.d, #0xffff
+; CHECK-NEXT: ushr v3.2d, v3.2d, #48
+; CHECK-NEXT: ushr v2.2d, v2.2d, #48
+; CHECK-NEXT: ushr v1.2d, v1.2d, #48
+; CHECK-NEXT: ushr v0.2d, v0.2d, #48
+; CHECK-NEXT: ucvtf v4.2d, v4.2d
; CHECK-NEXT: ucvtf v16.2d, v16.2d
; CHECK-NEXT: ucvtf v17.2d, v17.2d
-; CHECK-NEXT: ucvtf v1.2d, v1.2d
-; CHECK-NEXT: ucvtf v3.2d, v3.2d
; CHECK-NEXT: ucvtf v18.2d, v18.2d
-; CHECK-NEXT: ucvtf v19.2d, v19.2d
+; CHECK-NEXT: ucvtf v5.2d, v5.2d
; CHECK-NEXT: ucvtf v6.2d, v6.2d
; CHECK-NEXT: ucvtf v7.2d, v7.2d
+; CHECK-NEXT: ucvtf v19.2d, v19.2d
; CHECK-NEXT: ucvtf v20.2d, v20.2d
; CHECK-NEXT: ucvtf v21.2d, v21.2d
-; CHECK-NEXT: ucvtf v5.2d, v5.2d
-; CHECK-NEXT: ucvtf v4.2d, v4.2d
; CHECK-NEXT: ucvtf v22.2d, v22.2d
-; CHECK-NEXT: ucvtf v0.2d, v0.2d
; CHECK-NEXT: ucvtf v23.2d, v23.2d
+; CHECK-NEXT: ucvtf v3.2d, v3.2d
; CHECK-NEXT: ucvtf v2.2d, v2.2d
-; CHECK-NEXT: fadd v7.2d, v3.2d, v7.2d
-; CHECK-NEXT: fadd v1.2d, v1.2d, v6.2d
-; CHECK-NEXT: fadd v3.2d, v17.2d, v19.2d
-; CHECK-NEXT: fadd v6.2d, v16.2d, v18.2d
-; CHECK-NEXT: fadd v5.2d, v5.2d, v22.2d
-; CHECK-NEXT: fadd v16.2d, v20.2d, v0.2d
-; CHECK-NEXT: fadd v2.2d, v4.2d, v2.2d
-; CHECK-NEXT: fadd v4.2d, v21.2d, v23.2d
-; CHECK-NEXT: fadd v0.2d, v1.2d, v5.2d
-; CHECK-NEXT: fadd v1.2d, v6.2d, v16.2d
-; CHECK-NEXT: fadd v3.2d, v3.2d, v4.2d
-; CHECK-NEXT: fadd v2.2d, v7.2d, v2.2d
+; CHECK-NEXT: ucvtf v1.2d, v1.2d
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: fadd v6.2d, v16.2d, v6.2d
+; CHECK-NEXT: fadd v4.2d, v4.2d, v5.2d
+; CHECK-NEXT: fadd v18.2d, v18.2d, v19.2d
+; CHECK-NEXT: fadd v7.2d, v17.2d, v7.2d
+; CHECK-NEXT: fadd v3.2d, v20.2d, v3.2d
+; CHECK-NEXT: fadd v16.2d, v22.2d, v1.2d
+; CHECK-NEXT: fadd v1.2d, v21.2d, v2.2d
+; CHECK-NEXT: fadd v5.2d, v23.2d, v0.2d
+; CHECK-NEXT: fadd v0.2d, v4.2d, v3.2d
+; CHECK-NEXT: fadd v1.2d, v6.2d, v1.2d
+; CHECK-NEXT: fadd v2.2d, v7.2d, v16.2d
+; CHECK-NEXT: fadd v3.2d, v18.2d, v5.2d
; CHECK-NEXT: ret
%l = load <32 x i16>, ptr %p
%deint = call {<8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.vector.deinterleave4(<32 x i16> %l)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
index f6e540d10cadc..1acc08e7e9ed7 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-deinterleave4-i8-to-fp32.ll
@@ -8,8 +8,12 @@ define void @deinterleave_intrinsic_uitofp(ptr %src, ptr %dst0, ptr %dst1,
; CHECK-NEXT: // %bb.1: // %loop.preheader
; CHECK-NEXT: adrp x8, .LCPI0_0
; CHECK-NEXT: adrp x9, .LCPI0_1
+; CHECK-NEXT: adrp x10, .LCPI0_2
+; CHECK-NEXT: adrp x11, .LCPI0_3
; CHECK-NEXT: ldr q0, [x8, :lo12:.LCPI0_0]
; CHECK-NEXT: ldr q1, [x9, :lo12:.LCPI0_1]
+; CHECK-NEXT: ldr q2, [x10, :lo12:.LCPI0_2]
+; CHECK-NEXT: ldr q3, [x11, :lo12:.LCPI0_3]
; CHECK-NEXT: mov x8, xzr
; CHECK-NEXT: .LBB0_2: // %loop
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
@@ -18,39 +22,30 @@ define void @deinterleave_intrinsic_uitofp(ptr %src, ptr %dst0, ptr %dst1,
; CHECK-NEXT: cmp x8, x5
; CHECK-NEXT: add x10, x0, x9
; CHECK-NEXT: add x11, x2, x9
-; CHECK-NEXT: ldp q2, q3, [x10]
+; CHECK-NEXT: ldp q5, q4, [x10]
; CHECK-NEXT: add x10, x1, x9
-; CHECK-NEXT: uzp1 v4.16b, v2.16b, v3.16b
-; CHECK-NEXT: uzp2 v5.16b, v3.16b, v0.16b
-; CHECK-NEXT: uzp2 v6.16b, v2.16b, v0.16b
-; CHECK-NEXT: xtn v3.8b, v3.8h
-; CHECK-NEXT: xtn v2.8b, v2.8h
-; CHECK-NEXT: xtn v4.8b, v4.8h
-; CHECK-NEXT: uzp1 v7.8b, v6.8b, v5.8b
-; CHECK-NEXT: uzp2 v5.8b, v6.8b, v5.8b
-; CHECK-NEXT: uzp2 v2.8b, v2.8b, v3.8b
-; CHECK-NEXT: tbl v3.16b, { v4.16b }, v0.16b
-; CHECK-NEXT: tbl v4.16b, { v4.16b }, v1.16b
-; CHECK-NEXT: tbl v6.16b, { v7.16b }, v0.16b
-; CHECK-NEXT: tbl v7.16b, { v7.16b }, v1.16b
-; CHECK-NEXT: tbl v16.16b, { v2.16b }, v0.16b
-; CHECK-NEXT: tbl v2.16b, { v2.16b }, v1.16b
-; CHECK-NEXT: tbl v17.16b, { v5.16b }, v0.16b
-; CHECK-NEXT: tbl v5.16b, { v5.16b }, v1.16b
-; CHECK-NEXT: ucvtf v3.4s, v3.4s
-; CHECK-NEXT: ucvtf v4.4s, v4.4s
+; CHECK-NEXT: tbl v6.16b, { v4.16b }, v0.16b
+; CHECK-NEXT: tbl v7.16b, { v5.16b }, v0.16b
+; CHECK-NEXT: tbl v16.16b, { v4.16b }, v1.16b
+; CHECK-NEXT: tbl v17.16b, { v5.16b }, v1.16b
+; CHECK-NEXT: tbl v18.16b, { v4.16b }, v2.16b
+; CHECK-NEXT: tbl v19.16b, { v5.16b }, v2.16b
+; CHECK-NEXT: tbl v4.16b, { v4.16b }, v3.16b
+; CHECK-NEXT: tbl v5.16b, { v5.16b }, v3.16b
; CHECK-NEXT: ucvtf v6.4s, v6.4s
; CHECK-NEXT: ucvtf v7.4s, v7.4s
; CHECK-NEXT: ucvtf v16.4s, v16.4s
-; CHECK-NEXT: ucvtf v2.4s, v2.4s
-; CHECK-NEXT: stp q4, q3, [x10]
-; CHECK-NEXT: ucvtf v3.4s, v17.4s
-; CHECK-NEXT: ucvtf v4.4s, v5.4s
+; CHECK-NEXT: ucvtf v17.4s, v17.4s
+; CHECK-NEXT: ucvtf v18.4s, v18.4s
+; CHECK-NEXT: ucvtf v4.4s, v4.4s
+; CHECK-NEXT: ucvtf v5.4s, v5.4s
+; CHECK-NEXT: stp q7, q6, [x10]
+; CHECK-NEXT: ucvtf v6.4s, v19.4s
; CHECK-NEXT: add x10, x3, x9
; CHECK-NEXT: add x9, x4, x9
-; CHECK-NEXT: stp q7, q6, [x11]
-; CHECK-NEXT: stp q2, q16, [x10]
-; CHECK-NEXT: stp q4, q3, [x9]
+; CHECK-NEXT: stp q17, q16, [x11]
+; CHECK-NEXT: stp q6, q18, [x10]
+; CHECK-NEXT: stp q5, q4, [x9]
; CHECK-NEXT: b.lo .LBB0_2
; CHECK-NEXT: .LBB0_3: // %exit
; CHECK-NEXT: ret
More information about the llvm-commits
mailing list