Files
TheRock/compiler/amd-llvm/llvm/test/CodeGen/AArch64/arm64-vadd.ll
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

1354 lines
48 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s --check-prefixes=CHECK,CHECK-SD
; RUN: llc < %s -mtriple=arm64-eabi -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI
define <8 x i8> @addhn8b(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn8b:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addhn v0.8b, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%tmp3 = call <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16> %tmp1, <8 x i16> %tmp2)
ret <8 x i8> %tmp3
}
define <4 x i16> @addhn4h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addhn v0.4h, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%tmp3 = call <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32> %tmp1, <4 x i32> %tmp2)
ret <4 x i16> %tmp3
}
define <2 x i32> @addhn2s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addhn v0.2s, v0.2d, v1.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%tmp3 = call <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64> %tmp1, <2 x i64> %tmp2)
ret <2 x i32> %tmp3
}
define <16 x i8> @addhn2_16b(<8 x i16> %a, <8 x i16> %b) nounwind {
; CHECK-LABEL: addhn2_16b:
; CHECK: // %bb.0:
; CHECK-NEXT: addhn v2.8b, v0.8h, v1.8h
; CHECK-NEXT: addhn2 v2.16b, v0.8h, v1.8h
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%vaddhn2.i = tail call <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind
%vaddhn_high2.i = tail call <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind
%res = shufflevector <8 x i8> %vaddhn2.i, <8 x i8> %vaddhn_high2.i, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
ret <16 x i8> %res
}
define <8 x i16> @addhn2_8h(<4 x i32> %a, <4 x i32> %b) nounwind {
; CHECK-LABEL: addhn2_8h:
; CHECK: // %bb.0:
; CHECK-NEXT: addhn v2.4h, v0.4s, v1.4s
; CHECK-NEXT: addhn2 v2.8h, v0.4s, v1.4s
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%vaddhn2.i = tail call <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind
%vaddhn_high3.i = tail call <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind
%res = shufflevector <4 x i16> %vaddhn2.i, <4 x i16> %vaddhn_high3.i, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
ret <8 x i16> %res
}
define <4 x i32> @addhn2_4s(<2 x i64> %a, <2 x i64> %b) nounwind {
; CHECK-LABEL: addhn2_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: addhn v2.2s, v0.2d, v1.2d
; CHECK-NEXT: addhn2 v2.4s, v0.2d, v1.2d
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%vaddhn2.i = tail call <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind
%vaddhn_high3.i = tail call <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind
%res = shufflevector <2 x i32> %vaddhn2.i, <2 x i32> %vaddhn_high3.i, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res
}
declare <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64>, <2 x i64>) nounwind readnone
declare <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32>, <4 x i32>) nounwind readnone
declare <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16>, <8 x i16>) nounwind readnone
define <8 x i8> @raddhn8b(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: raddhn8b:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: raddhn v0.8b, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%tmp3 = call <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16> %tmp1, <8 x i16> %tmp2)
ret <8 x i8> %tmp3
}
define <4 x i16> @raddhn4h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: raddhn4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: raddhn v0.4h, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%tmp3 = call <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32> %tmp1, <4 x i32> %tmp2)
ret <4 x i16> %tmp3
}
define <2 x i32> @raddhn2s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: raddhn2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: raddhn v0.2s, v0.2d, v1.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%tmp3 = call <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64> %tmp1, <2 x i64> %tmp2)
ret <2 x i32> %tmp3
}
define <16 x i8> @raddhn2_16b(<8 x i16> %a, <8 x i16> %b) nounwind {
; CHECK-LABEL: raddhn2_16b:
; CHECK: // %bb.0:
; CHECK-NEXT: raddhn v2.8b, v0.8h, v1.8h
; CHECK-NEXT: raddhn2 v2.16b, v0.8h, v1.8h
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%vraddhn2.i = tail call <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind
%vraddhn_high2.i = tail call <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind
%res = shufflevector <8 x i8> %vraddhn2.i, <8 x i8> %vraddhn_high2.i, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
ret <16 x i8> %res
}
define <8 x i16> @raddhn2_8h(<4 x i32> %a, <4 x i32> %b) nounwind {
; CHECK-LABEL: raddhn2_8h:
; CHECK: // %bb.0:
; CHECK-NEXT: raddhn v2.4h, v0.4s, v1.4s
; CHECK-NEXT: raddhn2 v2.8h, v0.4s, v1.4s
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%vraddhn2.i = tail call <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind
%vraddhn_high3.i = tail call <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind
%res = shufflevector <4 x i16> %vraddhn2.i, <4 x i16> %vraddhn_high3.i, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
ret <8 x i16> %res
}
define <4 x i32> @raddhn2_4s(<2 x i64> %a, <2 x i64> %b) nounwind {
; CHECK-LABEL: raddhn2_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: raddhn v2.2s, v0.2d, v1.2d
; CHECK-NEXT: raddhn2 v2.4s, v0.2d, v1.2d
; CHECK-NEXT: mov v0.16b, v2.16b
; CHECK-NEXT: ret
%vraddhn2.i = tail call <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind
%vraddhn_high3.i = tail call <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind
%res = shufflevector <2 x i32> %vraddhn2.i, <2 x i32> %vraddhn_high3.i, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res
}
declare <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64>, <2 x i64>) nounwind readnone
declare <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32>, <4 x i32>) nounwind readnone
declare <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16>, <8 x i16>) nounwind readnone
define <8 x i16> @saddl2_8h(<16 x i8> %a, <16 x i8> %b) nounwind {
; CHECK-LABEL: saddl2_8h:
; CHECK: // %bb.0:
; CHECK-NEXT: saddl2 v0.8h, v0.16b, v1.16b
; CHECK-NEXT: ret
%tmp = bitcast <16 x i8> %a to <2 x i64>
%shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>
%tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <8 x i8>
%vmovl.i.i.i = sext <8 x i8> %tmp1 to <8 x i16>
%tmp2 = bitcast <16 x i8> %b to <2 x i64>
%shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>
%tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <8 x i8>
%vmovl.i.i5.i = sext <8 x i8> %tmp3 to <8 x i16>
%add.i = add <8 x i16> %vmovl.i.i.i, %vmovl.i.i5.i
ret <8 x i16> %add.i
}
define <4 x i32> @saddl2_4s(<8 x i16> %a, <8 x i16> %b) nounwind {
; CHECK-LABEL: saddl2_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: saddl2 v0.4s, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp = bitcast <8 x i16> %a to <2 x i64>
%shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>
%tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <4 x i16>
%vmovl.i.i.i = sext <4 x i16> %tmp1 to <4 x i32>
%tmp2 = bitcast <8 x i16> %b to <2 x i64>
%shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>
%tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <4 x i16>
%vmovl.i.i5.i = sext <4 x i16> %tmp3 to <4 x i32>
%add.i = add <4 x i32> %vmovl.i.i.i, %vmovl.i.i5.i
ret <4 x i32> %add.i
}
define <2 x i64> @saddl2_2d(<4 x i32> %a, <4 x i32> %b) nounwind {
; CHECK-LABEL: saddl2_2d:
; CHECK: // %bb.0:
; CHECK-NEXT: saddl2 v0.2d, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp = bitcast <4 x i32> %a to <2 x i64>
%shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>
%tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <2 x i32>
%vmovl.i.i.i = sext <2 x i32> %tmp1 to <2 x i64>
%tmp2 = bitcast <4 x i32> %b to <2 x i64>
%shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>
%tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <2 x i32>
%vmovl.i.i5.i = sext <2 x i32> %tmp3 to <2 x i64>
%add.i = add <2 x i64> %vmovl.i.i.i, %vmovl.i.i5.i
ret <2 x i64> %add.i
}
define <8 x i16> @uaddl2_8h(<16 x i8> %a, <16 x i8> %b) nounwind {
; CHECK-LABEL: uaddl2_8h:
; CHECK: // %bb.0:
; CHECK-NEXT: uaddl2 v0.8h, v0.16b, v1.16b
; CHECK-NEXT: ret
%tmp = bitcast <16 x i8> %a to <2 x i64>
%shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>
%tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <8 x i8>
%vmovl.i.i.i = zext <8 x i8> %tmp1 to <8 x i16>
%tmp2 = bitcast <16 x i8> %b to <2 x i64>
%shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>
%tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <8 x i8>
%vmovl.i.i5.i = zext <8 x i8> %tmp3 to <8 x i16>
%add.i = add <8 x i16> %vmovl.i.i.i, %vmovl.i.i5.i
ret <8 x i16> %add.i
}
define <4 x i32> @uaddl2_4s(<8 x i16> %a, <8 x i16> %b) nounwind {
; CHECK-LABEL: uaddl2_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: uaddl2 v0.4s, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp = bitcast <8 x i16> %a to <2 x i64>
%shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>
%tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <4 x i16>
%vmovl.i.i.i = zext <4 x i16> %tmp1 to <4 x i32>
%tmp2 = bitcast <8 x i16> %b to <2 x i64>
%shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>
%tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <4 x i16>
%vmovl.i.i5.i = zext <4 x i16> %tmp3 to <4 x i32>
%add.i = add <4 x i32> %vmovl.i.i.i, %vmovl.i.i5.i
ret <4 x i32> %add.i
}
define <2 x i64> @uaddl2_2d(<4 x i32> %a, <4 x i32> %b) nounwind {
; CHECK-LABEL: uaddl2_2d:
; CHECK: // %bb.0:
; CHECK-NEXT: uaddl2 v0.2d, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp = bitcast <4 x i32> %a to <2 x i64>
%shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>
%tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <2 x i32>
%vmovl.i.i.i = zext <2 x i32> %tmp1 to <2 x i64>
%tmp2 = bitcast <4 x i32> %b to <2 x i64>
%shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>
%tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <2 x i32>
%vmovl.i.i5.i = zext <2 x i32> %tmp3 to <2 x i64>
%add.i = add <2 x i64> %vmovl.i.i.i, %vmovl.i.i5.i
ret <2 x i64> %add.i
}
define <8 x i16> @uaddw8h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uaddw8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: uaddw v0.8h, v0.8h, v1.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i8>, ptr %B
%tmp3 = zext <8 x i8> %tmp2 to <8 x i16>
%tmp4 = add <8 x i16> %tmp1, %tmp3
ret <8 x i16> %tmp4
}
define <4 x i32> @uaddw4s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uaddw4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: uaddw v0.4s, v0.4s, v1.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i16>, ptr %B
%tmp3 = zext <4 x i16> %tmp2 to <4 x i32>
%tmp4 = add <4 x i32> %tmp1, %tmp3
ret <4 x i32> %tmp4
}
define <2 x i64> @uaddw2d(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uaddw2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: uaddw v0.2d, v0.2d, v1.2s
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i32>, ptr %B
%tmp3 = zext <2 x i32> %tmp2 to <2 x i64>
%tmp4 = add <2 x i64> %tmp1, %tmp3
ret <2 x i64> %tmp4
}
define <8 x i16> @uaddw2_8h(ptr %A, ptr %B) nounwind {
; CHECK-SD-LABEL: uaddw2_8h:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ldr d1, [x1, #8]
; CHECK-SD-NEXT: uaddw v0.8h, v0.8h, v1.8b
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: uaddw2_8h:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q0, [x0]
; CHECK-GI-NEXT: ldr q1, [x1]
; CHECK-GI-NEXT: uaddw2 v0.8h, v0.8h, v1.16b
; CHECK-GI-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <16 x i8>, ptr %B
%high2 = shufflevector <16 x i8> %tmp2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
%ext2 = zext <8 x i8> %high2 to <8 x i16>
%res = add <8 x i16> %tmp1, %ext2
ret <8 x i16> %res
}
define <4 x i32> @uaddw2_4s(ptr %A, ptr %B) nounwind {
; CHECK-SD-LABEL: uaddw2_4s:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ldr d1, [x1, #8]
; CHECK-SD-NEXT: uaddw v0.4s, v0.4s, v1.4h
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: uaddw2_4s:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q0, [x0]
; CHECK-GI-NEXT: ldr q1, [x1]
; CHECK-GI-NEXT: uaddw2 v0.4s, v0.4s, v1.8h
; CHECK-GI-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%high2 = shufflevector <8 x i16> %tmp2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
%ext2 = zext <4 x i16> %high2 to <4 x i32>
%res = add <4 x i32> %tmp1, %ext2
ret <4 x i32> %res
}
define <2 x i64> @uaddw2_2d(ptr %A, ptr %B) nounwind {
; CHECK-SD-LABEL: uaddw2_2d:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ldr d1, [x1, #8]
; CHECK-SD-NEXT: uaddw v0.2d, v0.2d, v1.2s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: uaddw2_2d:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q0, [x0]
; CHECK-GI-NEXT: ldr q1, [x1]
; CHECK-GI-NEXT: uaddw2 v0.2d, v0.2d, v1.4s
; CHECK-GI-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%high2 = shufflevector <4 x i32> %tmp2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%ext2 = zext <2 x i32> %high2 to <2 x i64>
%res = add <2 x i64> %tmp1, %ext2
ret <2 x i64> %res
}
define <8 x i16> @saddw8h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: saddw8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: saddw v0.8h, v0.8h, v1.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i8>, ptr %B
%tmp3 = sext <8 x i8> %tmp2 to <8 x i16>
%tmp4 = add <8 x i16> %tmp1, %tmp3
ret <8 x i16> %tmp4
}
define <4 x i32> @saddw4s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: saddw4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: saddw v0.4s, v0.4s, v1.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i16>, ptr %B
%tmp3 = sext <4 x i16> %tmp2 to <4 x i32>
%tmp4 = add <4 x i32> %tmp1, %tmp3
ret <4 x i32> %tmp4
}
define <2 x i64> @saddw2d(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: saddw2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: saddw v0.2d, v0.2d, v1.2s
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i32>, ptr %B
%tmp3 = sext <2 x i32> %tmp2 to <2 x i64>
%tmp4 = add <2 x i64> %tmp1, %tmp3
ret <2 x i64> %tmp4
}
define <8 x i16> @saddw2_8h(ptr %A, ptr %B) nounwind {
; CHECK-SD-LABEL: saddw2_8h:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ldr d1, [x1, #8]
; CHECK-SD-NEXT: saddw v0.8h, v0.8h, v1.8b
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: saddw2_8h:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q0, [x0]
; CHECK-GI-NEXT: ldr q1, [x1]
; CHECK-GI-NEXT: saddw2 v0.8h, v0.8h, v1.16b
; CHECK-GI-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <16 x i8>, ptr %B
%high2 = shufflevector <16 x i8> %tmp2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
%ext2 = sext <8 x i8> %high2 to <8 x i16>
%res = add <8 x i16> %tmp1, %ext2
ret <8 x i16> %res
}
define <4 x i32> @saddw2_4s(ptr %A, ptr %B) nounwind {
; CHECK-SD-LABEL: saddw2_4s:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ldr d1, [x1, #8]
; CHECK-SD-NEXT: saddw v0.4s, v0.4s, v1.4h
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: saddw2_4s:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q0, [x0]
; CHECK-GI-NEXT: ldr q1, [x1]
; CHECK-GI-NEXT: saddw2 v0.4s, v0.4s, v1.8h
; CHECK-GI-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%high2 = shufflevector <8 x i16> %tmp2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
%ext2 = sext <4 x i16> %high2 to <4 x i32>
%res = add <4 x i32> %tmp1, %ext2
ret <4 x i32> %res
}
define <2 x i64> @saddw2_2d(ptr %A, ptr %B) nounwind {
; CHECK-SD-LABEL: saddw2_2d:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ldr d1, [x1, #8]
; CHECK-SD-NEXT: saddw v0.2d, v0.2d, v1.2s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: saddw2_2d:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q0, [x0]
; CHECK-GI-NEXT: ldr q1, [x1]
; CHECK-GI-NEXT: saddw2 v0.2d, v0.2d, v1.4s
; CHECK-GI-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%high2 = shufflevector <4 x i32> %tmp2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%ext2 = sext <2 x i32> %high2 to <2 x i64>
%res = add <2 x i64> %tmp1, %ext2
ret <2 x i64> %res
}
define <4 x i16> @saddlp4h(ptr %A) nounwind {
; CHECK-LABEL: saddlp4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: saddlp v0.4h, v0.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
%tmp3 = call <4 x i16> @llvm.aarch64.neon.saddlp.v4i16.v8i8(<8 x i8> %tmp1)
ret <4 x i16> %tmp3
}
define <2 x i32> @saddlp2s(ptr %A) nounwind {
; CHECK-LABEL: saddlp2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: saddlp v0.2s, v0.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i16>, ptr %A
%tmp3 = call <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16> %tmp1)
ret <2 x i32> %tmp3
}
define <1 x i64> @saddlp1d(ptr %A) nounwind {
; CHECK-LABEL: saddlp1d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: saddlp v0.1d, v0.2s
; CHECK-NEXT: ret
%tmp1 = load <2 x i32>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.saddlp.v1i64.v2i32(<2 x i32> %tmp1)
ret <1 x i64> %tmp3
}
define <8 x i16> @saddlp8h(ptr %A) nounwind {
; CHECK-LABEL: saddlp8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: saddlp v0.8h, v0.16b
; CHECK-NEXT: ret
%tmp1 = load <16 x i8>, ptr %A
%tmp3 = call <8 x i16> @llvm.aarch64.neon.saddlp.v8i16.v16i8(<16 x i8> %tmp1)
ret <8 x i16> %tmp3
}
define <4 x i32> @saddlp4s(ptr %A) nounwind {
; CHECK-LABEL: saddlp4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: saddlp v0.4s, v0.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp3 = call <4 x i32> @llvm.aarch64.neon.saddlp.v4i32.v8i16(<8 x i16> %tmp1)
ret <4 x i32> %tmp3
}
define <2 x i64> @saddlp2d(ptr %A) nounwind {
; CHECK-LABEL: saddlp2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: saddlp v0.2d, v0.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp3 = call <2 x i64> @llvm.aarch64.neon.saddlp.v2i64.v4i32(<4 x i32> %tmp1)
ret <2 x i64> %tmp3
}
declare <4 x i16> @llvm.aarch64.neon.saddlp.v4i16.v8i8(<8 x i8>) nounwind readnone
declare <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>) nounwind readnone
declare <1 x i64> @llvm.aarch64.neon.saddlp.v1i64.v2i32(<2 x i32>) nounwind readnone
declare <8 x i16> @llvm.aarch64.neon.saddlp.v8i16.v16i8(<16 x i8>) nounwind readnone
declare <4 x i32> @llvm.aarch64.neon.saddlp.v4i32.v8i16(<8 x i16>) nounwind readnone
declare <2 x i64> @llvm.aarch64.neon.saddlp.v2i64.v4i32(<4 x i32>) nounwind readnone
define <4 x i16> @uaddlp4h(ptr %A) nounwind {
; CHECK-LABEL: uaddlp4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: uaddlp v0.4h, v0.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
%tmp3 = call <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8> %tmp1)
ret <4 x i16> %tmp3
}
define <2 x i32> @uaddlp2s(ptr %A) nounwind {
; CHECK-LABEL: uaddlp2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: uaddlp v0.2s, v0.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i16>, ptr %A
%tmp3 = call <2 x i32> @llvm.aarch64.neon.uaddlp.v2i32.v4i16(<4 x i16> %tmp1)
ret <2 x i32> %tmp3
}
define <1 x i64> @uaddlp1d(ptr %A) nounwind {
; CHECK-LABEL: uaddlp1d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: uaddlp v0.1d, v0.2s
; CHECK-NEXT: ret
%tmp1 = load <2 x i32>, ptr %A
%tmp3 = call <1 x i64> @llvm.aarch64.neon.uaddlp.v1i64.v2i32(<2 x i32> %tmp1)
ret <1 x i64> %tmp3
}
define <8 x i16> @uaddlp8h(ptr %A) nounwind {
; CHECK-LABEL: uaddlp8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: uaddlp v0.8h, v0.16b
; CHECK-NEXT: ret
%tmp1 = load <16 x i8>, ptr %A
%tmp3 = call <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8> %tmp1)
ret <8 x i16> %tmp3
}
define <4 x i32> @uaddlp4s(ptr %A) nounwind {
; CHECK-LABEL: uaddlp4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: uaddlp v0.4s, v0.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp3 = call <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16> %tmp1)
ret <4 x i32> %tmp3
}
define <2 x i64> @uaddlp2d(ptr %A) nounwind {
; CHECK-LABEL: uaddlp2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: uaddlp v0.2d, v0.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp3 = call <2 x i64> @llvm.aarch64.neon.uaddlp.v2i64.v4i32(<4 x i32> %tmp1)
ret <2 x i64> %tmp3
}
declare <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8>) nounwind readnone
declare <2 x i32> @llvm.aarch64.neon.uaddlp.v2i32.v4i16(<4 x i16>) nounwind readnone
declare <1 x i64> @llvm.aarch64.neon.uaddlp.v1i64.v2i32(<2 x i32>) nounwind readnone
declare <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8>) nounwind readnone
declare <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16>) nounwind readnone
declare <2 x i64> @llvm.aarch64.neon.uaddlp.v2i64.v4i32(<4 x i32>) nounwind readnone
define <4 x i16> @sadalp4h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: sadalp4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d1, [x0]
; CHECK-NEXT: ldr d0, [x1]
; CHECK-NEXT: sadalp v0.4h, v1.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
%tmp3 = call <4 x i16> @llvm.aarch64.neon.saddlp.v4i16.v8i8(<8 x i8> %tmp1)
%tmp4 = load <4 x i16>, ptr %B
%tmp5 = add <4 x i16> %tmp3, %tmp4
ret <4 x i16> %tmp5
}
define <2 x i32> @sadalp2s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: sadalp2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d1, [x0]
; CHECK-NEXT: ldr d0, [x1]
; CHECK-NEXT: sadalp v0.2s, v1.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i16>, ptr %A
%tmp3 = call <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16> %tmp1)
%tmp4 = load <2 x i32>, ptr %B
%tmp5 = add <2 x i32> %tmp3, %tmp4
ret <2 x i32> %tmp5
}
define <8 x i16> @sadalp8h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: sadalp8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q0, [x1]
; CHECK-NEXT: sadalp v0.8h, v1.16b
; CHECK-NEXT: ret
%tmp1 = load <16 x i8>, ptr %A
%tmp3 = call <8 x i16> @llvm.aarch64.neon.saddlp.v8i16.v16i8(<16 x i8> %tmp1)
%tmp4 = load <8 x i16>, ptr %B
%tmp5 = add <8 x i16> %tmp3, %tmp4
ret <8 x i16> %tmp5
}
define <4 x i32> @sadalp4s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: sadalp4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q0, [x1]
; CHECK-NEXT: sadalp v0.4s, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp3 = call <4 x i32> @llvm.aarch64.neon.saddlp.v4i32.v8i16(<8 x i16> %tmp1)
%tmp4 = load <4 x i32>, ptr %B
%tmp5 = add <4 x i32> %tmp3, %tmp4
ret <4 x i32> %tmp5
}
define <2 x i64> @sadalp2d(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: sadalp2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q0, [x1]
; CHECK-NEXT: sadalp v0.2d, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp3 = call <2 x i64> @llvm.aarch64.neon.saddlp.v2i64.v4i32(<4 x i32> %tmp1)
%tmp4 = load <2 x i64>, ptr %B
%tmp5 = add <2 x i64> %tmp3, %tmp4
ret <2 x i64> %tmp5
}
define <4 x i16> @uadalp4h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uadalp4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d1, [x0]
; CHECK-NEXT: ldr d0, [x1]
; CHECK-NEXT: uadalp v0.4h, v1.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
%tmp3 = call <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8> %tmp1)
%tmp4 = load <4 x i16>, ptr %B
%tmp5 = add <4 x i16> %tmp3, %tmp4
ret <4 x i16> %tmp5
}
define <2 x i32> @uadalp2s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uadalp2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d1, [x0]
; CHECK-NEXT: ldr d0, [x1]
; CHECK-NEXT: uadalp v0.2s, v1.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i16>, ptr %A
%tmp3 = call <2 x i32> @llvm.aarch64.neon.uaddlp.v2i32.v4i16(<4 x i16> %tmp1)
%tmp4 = load <2 x i32>, ptr %B
%tmp5 = add <2 x i32> %tmp3, %tmp4
ret <2 x i32> %tmp5
}
define <8 x i16> @uadalp8h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uadalp8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q0, [x1]
; CHECK-NEXT: uadalp v0.8h, v1.16b
; CHECK-NEXT: ret
%tmp1 = load <16 x i8>, ptr %A
%tmp3 = call <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8> %tmp1)
%tmp4 = load <8 x i16>, ptr %B
%tmp5 = add <8 x i16> %tmp3, %tmp4
ret <8 x i16> %tmp5
}
define <4 x i32> @uadalp4s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uadalp4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q0, [x1]
; CHECK-NEXT: uadalp v0.4s, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp3 = call <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16> %tmp1)
%tmp4 = load <4 x i32>, ptr %B
%tmp5 = add <4 x i32> %tmp3, %tmp4
ret <4 x i32> %tmp5
}
define <2 x i64> @uadalp2d(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: uadalp2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q0, [x1]
; CHECK-NEXT: uadalp v0.2d, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp3 = call <2 x i64> @llvm.aarch64.neon.uaddlp.v2i64.v4i32(<4 x i32> %tmp1)
%tmp4 = load <2 x i64>, ptr %B
%tmp5 = add <2 x i64> %tmp3, %tmp4
ret <2 x i64> %tmp5
}
define <8 x i8> @addp_8b(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_8b:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: addp v0.8b, v0.8b, v1.8b
; CHECK-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
%tmp2 = load <8 x i8>, ptr %B
%tmp3 = call <8 x i8> @llvm.aarch64.neon.addp.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)
ret <8 x i8> %tmp3
}
define <16 x i8> @addp_16b(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_16b:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addp v0.16b, v0.16b, v1.16b
; CHECK-NEXT: ret
%tmp1 = load <16 x i8>, ptr %A
%tmp2 = load <16 x i8>, ptr %B
%tmp3 = call <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2)
ret <16 x i8> %tmp3
}
define <4 x i16> @addp_4h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_4h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: addp v0.4h, v0.4h, v1.4h
; CHECK-NEXT: ret
%tmp1 = load <4 x i16>, ptr %A
%tmp2 = load <4 x i16>, ptr %B
%tmp3 = call <4 x i16> @llvm.aarch64.neon.addp.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)
ret <4 x i16> %tmp3
}
define <8 x i16> @addp_8h(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_8h:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addp v0.8h, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%tmp3 = call <8 x i16> @llvm.aarch64.neon.addp.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2)
ret <8 x i16> %tmp3
}
define <2 x i32> @addp_2s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: addp v0.2s, v0.2s, v1.2s
; CHECK-NEXT: ret
%tmp1 = load <2 x i32>, ptr %A
%tmp2 = load <2 x i32>, ptr %B
%tmp3 = call <2 x i32> @llvm.aarch64.neon.addp.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)
ret <2 x i32> %tmp3
}
define <4 x i32> @addp_4s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addp v0.4s, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%tmp3 = call <4 x i32> @llvm.aarch64.neon.addp.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2)
ret <4 x i32> %tmp3
}
define <2 x i64> @addp_2d(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addp_2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addp v0.2d, v0.2d, v1.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%tmp3 = call <2 x i64> @llvm.aarch64.neon.addp.v2i64(<2 x i64> %tmp1, <2 x i64> %tmp2)
ret <2 x i64> %tmp3
}
declare <8 x i8> @llvm.aarch64.neon.addp.v8i8(<8 x i8>, <8 x i8>) nounwind readnone
declare <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>) nounwind readnone
declare <4 x i16> @llvm.aarch64.neon.addp.v4i16(<4 x i16>, <4 x i16>) nounwind readnone
declare <8 x i16> @llvm.aarch64.neon.addp.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
declare <2 x i32> @llvm.aarch64.neon.addp.v2i32(<2 x i32>, <2 x i32>) nounwind readnone
declare <4 x i32> @llvm.aarch64.neon.addp.v4i32(<4 x i32>, <4 x i32>) nounwind readnone
declare <2 x i64> @llvm.aarch64.neon.addp.v2i64(<2 x i64>, <2 x i64>) nounwind readnone
define <2 x float> @faddp_2s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: faddp_2s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ldr d1, [x1]
; CHECK-NEXT: faddp v0.2s, v0.2s, v1.2s
; CHECK-NEXT: ret
%tmp1 = load <2 x float>, ptr %A
%tmp2 = load <2 x float>, ptr %B
%tmp3 = call <2 x float> @llvm.aarch64.neon.faddp.v2f32(<2 x float> %tmp1, <2 x float> %tmp2)
ret <2 x float> %tmp3
}
define <4 x float> @faddp_4s(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: faddp_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: faddp v0.4s, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x float>, ptr %A
%tmp2 = load <4 x float>, ptr %B
%tmp3 = call <4 x float> @llvm.aarch64.neon.faddp.v4f32(<4 x float> %tmp1, <4 x float> %tmp2)
ret <4 x float> %tmp3
}
define <2 x double> @faddp_2d(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: faddp_2d:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: faddp v0.2d, v0.2d, v1.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x double>, ptr %A
%tmp2 = load <2 x double>, ptr %B
%tmp3 = call <2 x double> @llvm.aarch64.neon.faddp.v2f64(<2 x double> %tmp1, <2 x double> %tmp2)
ret <2 x double> %tmp3
}
declare <2 x float> @llvm.aarch64.neon.faddp.v2f32(<2 x float>, <2 x float>) nounwind readnone
declare <4 x float> @llvm.aarch64.neon.faddp.v4f32(<4 x float>, <4 x float>) nounwind readnone
declare <2 x double> @llvm.aarch64.neon.faddp.v2f64(<2 x double>, <2 x double>) nounwind readnone
define <2 x i64> @uaddl_duprhs(<4 x i32> %lhs, i32 %rhs) {
; CHECK-LABEL: uaddl_duprhs:
; CHECK: // %bb.0:
; CHECK-NEXT: dup v1.2s, w0
; CHECK-NEXT: uaddl v0.2d, v0.2s, v1.2s
; CHECK-NEXT: ret
%rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
%rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
%lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
%lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>
%rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>
%res = add <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @uaddl2_duprhs(<4 x i32> %lhs, i32 %rhs) {
; CHECK-SD-LABEL: uaddl2_duprhs:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: dup v1.4s, w0
; CHECK-SD-NEXT: uaddl2 v0.2d, v0.4s, v1.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: uaddl2_duprhs:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: dup v1.2s, w0
; CHECK-GI-NEXT: ushll v1.2d, v1.2s, #0
; CHECK-GI-NEXT: uaddw2 v0.2d, v1.2d, v0.4s
; CHECK-GI-NEXT: ret
%rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
%rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
%lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>
%rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>
%res = add <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @saddl_duplhs(i32 %lhs, <4 x i32> %rhs) {
; CHECK-LABEL: saddl_duplhs:
; CHECK: // %bb.0:
; CHECK-NEXT: dup v1.2s, w0
; CHECK-NEXT: saddl v0.2d, v1.2s, v0.2s
; CHECK-NEXT: ret
%lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 0
%lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 1
%rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
%lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>
%rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>
%res = add <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @saddl2_duplhs(i32 %lhs, <4 x i32> %rhs) {
; CHECK-SD-LABEL: saddl2_duplhs:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: dup v1.4s, w0
; CHECK-SD-NEXT: saddl2 v0.2d, v1.4s, v0.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: saddl2_duplhs:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: dup v1.2s, w0
; CHECK-GI-NEXT: sshll v1.2d, v1.2s, #0
; CHECK-GI-NEXT: saddw2 v0.2d, v1.2d, v0.4s
; CHECK-GI-NEXT: ret
%lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 0
%lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 1
%rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>
%rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>
%res = add <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @usubl_duprhs(<4 x i32> %lhs, i32 %rhs) {
; CHECK-LABEL: usubl_duprhs:
; CHECK: // %bb.0:
; CHECK-NEXT: dup v1.2s, w0
; CHECK-NEXT: usubl v0.2d, v0.2s, v1.2s
; CHECK-NEXT: ret
%rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
%rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
%lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
%lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>
%rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>
%res = sub <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @usubl2_duprhs(<4 x i32> %lhs, i32 %rhs) {
; CHECK-SD-LABEL: usubl2_duprhs:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: dup v1.4s, w0
; CHECK-SD-NEXT: usubl2 v0.2d, v0.4s, v1.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: usubl2_duprhs:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: dup v1.2s, w0
; CHECK-GI-NEXT: mov d0, v0.d[1]
; CHECK-GI-NEXT: usubl v0.2d, v0.2s, v1.2s
; CHECK-GI-NEXT: ret
%rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0
%rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1
%lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>
%rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>
%res = sub <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @ssubl_duplhs(i32 %lhs, <4 x i32> %rhs) {
; CHECK-LABEL: ssubl_duplhs:
; CHECK: // %bb.0:
; CHECK-NEXT: dup v1.2s, w0
; CHECK-NEXT: ssubl v0.2d, v1.2s, v0.2s
; CHECK-NEXT: ret
%lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 0
%lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 1
%rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
%lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>
%rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>
%res = sub <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <2 x i64> @ssubl2_duplhs(i32 %lhs, <4 x i32> %rhs) {
; CHECK-SD-LABEL: ssubl2_duplhs:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: dup v1.4s, w0
; CHECK-SD-NEXT: ssubl2 v0.2d, v1.4s, v0.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: ssubl2_duplhs:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: dup v1.2s, w0
; CHECK-GI-NEXT: sshll v1.2d, v1.2s, #0
; CHECK-GI-NEXT: ssubw2 v0.2d, v1.2d, v0.4s
; CHECK-GI-NEXT: ret
%lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 0
%lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 1
%rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>
%lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>
%rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>
%res = sub <2 x i64> %lhs.ext, %rhs.ext
ret <2 x i64> %res
}
define <8 x i8> @addhn8b_natural(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn8b_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addhn v0.8b, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%sum = add <8 x i16> %tmp1, %tmp2
%high_bits = lshr <8 x i16> %sum, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
%narrowed = trunc <8 x i16> %high_bits to <8 x i8>
ret <8 x i8> %narrowed
}
define <4 x i16> @addhn4h_natural(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn4h_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addhn v0.4h, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%sum = add <4 x i32> %tmp1, %tmp2
%high_bits = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
%narrowed = trunc <4 x i32> %high_bits to <4 x i16>
ret <4 x i16> %narrowed
}
define <2 x i32> @addhn2s_natural(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn2s_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: addhn v0.2s, v0.2d, v1.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%sum = add <2 x i64> %tmp1, %tmp2
%high_bits = lshr <2 x i64> %sum, <i64 32, i64 32>
%narrowed = trunc <2 x i64> %high_bits to <2 x i32>
ret <2 x i32> %narrowed
}
define <16 x i8> @addhn2_16b_natural(<8 x i8> %low, ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn2_16b_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: addhn2 v0.16b, v1.8h, v2.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%sum = add <8 x i16> %tmp1, %tmp2
%high_bits = lshr <8 x i16> %sum, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
%narrowed = trunc <8 x i16> %high_bits to <8 x i8>
%res = shufflevector <8 x i8> %low, <8 x i8> %narrowed, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
ret <16 x i8> %res
}
define <8 x i16> @addhn2_8h_natural(<4 x i16> %low, ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn2_8h_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: addhn2 v0.8h, v1.4s, v2.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%sum = add <4 x i32> %tmp1, %tmp2
%high_bits = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
%narrowed = trunc <4 x i32> %high_bits to <4 x i16>
%res = shufflevector <4 x i16> %low, <4 x i16> %narrowed, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
ret <8 x i16> %res
}
define <4 x i32> @addhn2_4s_natural(<2 x i32> %low, ptr %A, ptr %B) nounwind {
; CHECK-LABEL: addhn2_4s_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: addhn2 v0.4s, v1.2d, v2.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%sum = add <2 x i64> %tmp1, %tmp2
%high_bits = lshr <2 x i64> %sum, <i64 32, i64 32>
%narrowed = trunc <2 x i64> %high_bits to <2 x i32>
%res = shufflevector <2 x i32> %low, <2 x i32> %narrowed, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res
}
define <4 x i32> @addhn_addhn2_4s(ptr %A, ptr %B, ptr %C, ptr %D) nounwind {
; CHECK-LABEL: addhn_addhn2_4s:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: addhn v0.2s, v1.2d, v2.2d
; CHECK-NEXT: addhn2 v0.4s, v1.2d, v2.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%sum1 = add <2 x i64> %tmp1, %tmp2
%low_bits = lshr <2 x i64> %sum1, <i64 32, i64 32>
%narrowed1 = trunc <2 x i64> %low_bits to <2 x i32>
%tmp3 = load <2 x i64>, ptr %C
%tmp4 = load <2 x i64>, ptr %D
%sum2 = add <2 x i64> %tmp3, %tmp4
%high_bits = lshr <2 x i64> %sum1, <i64 32, i64 32>
%narrowed2 = trunc <2 x i64> %high_bits to <2 x i32>
%res = shufflevector <2 x i32> %narrowed1, <2 x i32> %narrowed2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res
}
define <8 x i8> @subhn8b_natural(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: subhn8b_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: subhn v0.8b, v0.8h, v1.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%diff = sub <8 x i16> %tmp1, %tmp2
%high_bits = lshr <8 x i16> %diff, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
%narrowed = trunc <8 x i16> %high_bits to <8 x i8>
ret <8 x i8> %narrowed
}
define <4 x i16> @subhn4h_natural(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: subhn4h_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: subhn v0.4h, v0.4s, v1.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%diff = sub <4 x i32> %tmp1, %tmp2
%high_bits = lshr <4 x i32> %diff, <i32 16, i32 16, i32 16, i32 16>
%narrowed = trunc <4 x i32> %high_bits to <4 x i16>
ret <4 x i16> %narrowed
}
define <2 x i32> @subhn2s_natural(ptr %A, ptr %B) nounwind {
; CHECK-LABEL: subhn2s_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ldr q1, [x1]
; CHECK-NEXT: subhn v0.2s, v0.2d, v1.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%diff = sub <2 x i64> %tmp1, %tmp2
%high_bits = lshr <2 x i64> %diff, <i64 32, i64 32>
%narrowed = trunc <2 x i64> %high_bits to <2 x i32>
ret <2 x i32> %narrowed
}
define <16 x i8> @subhn2_16b_natural(<8 x i8> %low, ptr %A, ptr %B) nounwind {
; CHECK-LABEL: subhn2_16b_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: subhn2 v0.16b, v1.8h, v2.8h
; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp2 = load <8 x i16>, ptr %B
%diff = sub <8 x i16> %tmp1, %tmp2
%high_bits = lshr <8 x i16> %diff, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
%narrowed = trunc <8 x i16> %high_bits to <8 x i8>
%res = shufflevector <8 x i8> %low, <8 x i8> %narrowed, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
ret <16 x i8> %res
}
define <8 x i16> @subhn2_8h_natural(<4 x i16> %low, ptr %A, ptr %B) nounwind {
; CHECK-LABEL: subhn2_8h_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: subhn2 v0.8h, v1.4s, v2.4s
; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp2 = load <4 x i32>, ptr %B
%diff = sub <4 x i32> %tmp1, %tmp2
%high_bits = lshr <4 x i32> %diff, <i32 16, i32 16, i32 16, i32 16>
%narrowed = trunc <4 x i32> %high_bits to <4 x i16>
%res = shufflevector <4 x i16> %low, <4 x i16> %narrowed, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
ret <8 x i16> %res
}
define <4 x i32> @subhn2_4s_natural(<2 x i32> %low, ptr %A, ptr %B) nounwind {
; CHECK-LABEL: subhn2_4s_natural:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q1, [x0]
; CHECK-NEXT: ldr q2, [x1]
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: subhn2 v0.4s, v1.2d, v2.2d
; CHECK-NEXT: ret
%tmp1 = load <2 x i64>, ptr %A
%tmp2 = load <2 x i64>, ptr %B
%diff = sub <2 x i64> %tmp1, %tmp2
%high_bits = lshr <2 x i64> %diff, <i64 32, i64 32>
%narrowed = trunc <2 x i64> %high_bits to <2 x i32>
%res = shufflevector <2 x i32> %low, <2 x i32> %narrowed, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res
}
define <16 x i8> @neg_narrow_i8(<16 x i16> %a) {
; CHECK-LABEL: neg_narrow_i8:
; CHECK: // %bb.0:
; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff
; CHECK-NEXT: subhn v0.8b, v2.8h, v0.8h
; CHECK-NEXT: subhn2 v0.16b, v2.8h, v1.8h
; CHECK-NEXT: ret
%not.i = xor <16 x i16> %a, splat (i16 -1)
%s = lshr <16 x i16> %not.i, splat (i16 8)
%vshrn_n = trunc nuw <16 x i16> %s to <16 x i8>
ret <16 x i8> %vshrn_n
}
define <8 x i16> @neg_narrow_i16(<8 x i32> %a) {
; CHECK-LABEL: neg_narrow_i16:
; CHECK: // %bb.0:
; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff
; CHECK-NEXT: subhn v0.4h, v2.4s, v0.4s
; CHECK-NEXT: subhn2 v0.8h, v2.4s, v1.4s
; CHECK-NEXT: ret
%not.i = xor <8 x i32> %a, splat (i32 -1)
%s = lshr <8 x i32> %not.i, splat (i32 16)
%vshrn_n = trunc nuw <8 x i32> %s to <8 x i16>
ret <8 x i16> %vshrn_n
}
define <4 x i32> @neg_narrow_i32(<4 x i64> %a) {
; CHECK-LABEL: neg_narrow_i32:
; CHECK: // %bb.0:
; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff
; CHECK-NEXT: subhn v0.2s, v2.2d, v0.2d
; CHECK-NEXT: subhn2 v0.4s, v2.2d, v1.2d
; CHECK-NEXT: ret
%not.i = xor <4 x i64> %a, splat (i64 -1)
%s = lshr <4 x i64> %not.i, splat (i64 32)
%vshrn_n = trunc nuw <4 x i64> %s to <4 x i32>
ret <4 x i32> %vshrn_n
}