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
852 lines
37 KiB
LLVM
852 lines
37 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=aarch64-none-elf -verify-machineinstrs -global-isel=0 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
|
; RUN: llc -mtriple=aarch64-none-elf -verify-machineinstrs -global-isel=1 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
|
|
|
define <4 x i16> @vqmovni32_smaxmin(<4 x i32> %s0) {
|
|
; CHECK-LABEL: vqmovni32_smaxmin:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp slt <4 x i32> %s0, <i32 32767, i32 32767, i32 32767, i32 32767>
|
|
%s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>
|
|
%c2 = icmp sgt <4 x i32> %s1, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
|
|
%s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
|
|
%t = trunc <4 x i32> %s2 to <4 x i16>
|
|
ret <4 x i16> %t
|
|
}
|
|
|
|
define <4 x i16> @vqmovni32_sminmax(<4 x i32> %s0) {
|
|
; CHECK-LABEL: vqmovni32_sminmax:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp sgt <4 x i32> %s0, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
|
|
%s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
|
|
%c2 = icmp slt <4 x i32> %s1, <i32 32767, i32 32767, i32 32767, i32 32767>
|
|
%s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>
|
|
%t = trunc <4 x i32> %s2 to <4 x i16>
|
|
ret <4 x i16> %t
|
|
}
|
|
|
|
define <4 x i16> @vqmovni32_umaxmin(<4 x i32> %s0) {
|
|
; CHECK-LABEL: vqmovni32_umaxmin:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: uqxtn v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp ult <4 x i32> %s0, <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%t = trunc <4 x i32> %s1 to <4 x i16>
|
|
ret <4 x i16> %t
|
|
}
|
|
|
|
define <8 x i8> @vqmovni16_smaxmin(<8 x i16> %s0) {
|
|
; CHECK-LABEL: vqmovni16_smaxmin:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.8b, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp slt <8 x i16> %s0, <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
|
|
%s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
|
|
%c2 = icmp sgt <8 x i16> %s1, <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
|
|
%s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
|
|
%t = trunc <8 x i16> %s2 to <8 x i8>
|
|
ret <8 x i8> %t
|
|
}
|
|
|
|
define <8 x i8> @vqmovni16_sminmax(<8 x i16> %s0) {
|
|
; CHECK-LABEL: vqmovni16_sminmax:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.8b, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp sgt <8 x i16> %s0, <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
|
|
%s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
|
|
%c2 = icmp slt <8 x i16> %s1, <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
|
|
%s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
|
|
%t = trunc <8 x i16> %s2 to <8 x i8>
|
|
ret <8 x i8> %t
|
|
}
|
|
|
|
define <8 x i8> @vqmovni16_umaxmin(<8 x i16> %s0) {
|
|
; CHECK-LABEL: vqmovni16_umaxmin:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: uqxtn v0.8b, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp ult <8 x i16> %s0, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
|
|
%s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
|
|
%t = trunc <8 x i16> %s1 to <8 x i8>
|
|
ret <8 x i8> %t
|
|
}
|
|
|
|
define <2 x i32> @vqmovni64_smaxmin(<2 x i64> %s0) {
|
|
; CHECK-LABEL: vqmovni64_smaxmin:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.2s, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp slt <2 x i64> %s0, <i64 2147483647, i64 2147483647>
|
|
%s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 2147483647, i64 2147483647>
|
|
%c2 = icmp sgt <2 x i64> %s1, <i64 -2147483648, i64 -2147483648>
|
|
%s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 -2147483648, i64 -2147483648>
|
|
%t = trunc <2 x i64> %s2 to <2 x i32>
|
|
ret <2 x i32> %t
|
|
}
|
|
|
|
define <2 x i32> @vqmovni64_sminmax(<2 x i64> %s0) {
|
|
; CHECK-LABEL: vqmovni64_sminmax:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.2s, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp sgt <2 x i64> %s0, <i64 -2147483648, i64 -2147483648>
|
|
%s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 -2147483648, i64 -2147483648>
|
|
%c2 = icmp slt <2 x i64> %s1, <i64 2147483647, i64 2147483647>
|
|
%s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 2147483647, i64 2147483647>
|
|
%t = trunc <2 x i64> %s2 to <2 x i32>
|
|
ret <2 x i32> %t
|
|
}
|
|
|
|
define <2 x i32> @vqmovni64_smaxmin_u(<2 x i64> %s0) {
|
|
; CHECK-LABEL: vqmovni64_smaxmin_u:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.2s, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp slt <2 x i64> %s0, <i64 4294967295, i64 4294967295>
|
|
%s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 4294967295, i64 4294967295>
|
|
%c2 = icmp sgt <2 x i64> %s1, zeroinitializer
|
|
%s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> zeroinitializer
|
|
%t = trunc <2 x i64> %s2 to <2 x i32>
|
|
ret <2 x i32> %t
|
|
}
|
|
|
|
define <2 x i32> @vqmovni64_sminmax_u(<2 x i64> %s0) {
|
|
; CHECK-LABEL: vqmovni64_sminmax_u:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.2s, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp sgt <2 x i64> %s0, zeroinitializer
|
|
%s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> zeroinitializer
|
|
%c2 = icmp slt <2 x i64> %s1, <i64 4294967295, i64 4294967295>
|
|
%s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 4294967295, i64 4294967295>
|
|
%t = trunc <2 x i64> %s2 to <2 x i32>
|
|
ret <2 x i32> %t
|
|
}
|
|
|
|
define <4 x i16> @vqmovni32_smaxmin_u(<4 x i32> %s0) {
|
|
; CHECK-LABEL: vqmovni32_smaxmin_u:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp slt <4 x i32> %s0, <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%c2 = icmp sgt <4 x i32> %s1, zeroinitializer
|
|
%s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> zeroinitializer
|
|
%t = trunc <4 x i32> %s2 to <4 x i16>
|
|
ret <4 x i16> %t
|
|
}
|
|
|
|
define <4 x i16> @vqmovni32_sminmax_u(<4 x i32> %s0) {
|
|
; CHECK-LABEL: vqmovni32_sminmax_u:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp sgt <4 x i32> %s0, zeroinitializer
|
|
%s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> zeroinitializer
|
|
%c2 = icmp slt <4 x i32> %s1, <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%t = trunc <4 x i32> %s2 to <4 x i16>
|
|
ret <4 x i16> %t
|
|
}
|
|
|
|
define <8 x i8> @vqmovni16_smaxmin_u(<8 x i16> %s0) {
|
|
; CHECK-LABEL: vqmovni16_smaxmin_u:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.8b, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp slt <8 x i16> %s0, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
|
|
%s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
|
|
%c2 = icmp sgt <8 x i16> %s1, zeroinitializer
|
|
%s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> zeroinitializer
|
|
%t = trunc <8 x i16> %s2 to <8 x i8>
|
|
ret <8 x i8> %t
|
|
}
|
|
|
|
define <8 x i8> @vqmovni16_sminmax_u(<8 x i16> %s0) {
|
|
; CHECK-LABEL: vqmovni16_sminmax_u:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.8b, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp sgt <8 x i16> %s0, zeroinitializer
|
|
%s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> zeroinitializer
|
|
%c2 = icmp slt <8 x i16> %s1, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
|
|
%s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
|
|
%t = trunc <8 x i16> %s2 to <8 x i8>
|
|
ret <8 x i8> %t
|
|
}
|
|
|
|
define <2 x i32> @vqmovni64_umaxmin(<2 x i64> %s0) {
|
|
; CHECK-LABEL: vqmovni64_umaxmin:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: uqxtn v0.2s, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c1 = icmp ult <2 x i64> %s0, <i64 4294967295, i64 4294967295>
|
|
%s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 4294967295, i64 4294967295>
|
|
%t = trunc <2 x i64> %s1 to <2 x i32>
|
|
ret <2 x i32> %t
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(smin(smax(Y, -2^n), 2^n-1))) pattern.
|
|
|
|
define <16 x i8> @signed_minmax_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
|
|
; CHECK-LABEL: signed_minmax_v8i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtn2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %y, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
|
|
%max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %min, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
|
|
%trunc = trunc <8 x i16> %max to <8 x i8>
|
|
%shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <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> %shuffle
|
|
}
|
|
|
|
define <8 x i16> @signed_minmax_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: signed_minmax_v4i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %y, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
|
|
%max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
|
|
%trunc = trunc <4 x i32> %max to <4 x i16>
|
|
%shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i32> @signed_minmax_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
|
|
; CHECK-LABEL: signed_minmax_v2i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %y, <2 x i64> <i64 2147483647, i64 2147483647>)
|
|
%max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> <i64 -2147483648, i64 -2147483648>)
|
|
%trunc = trunc <2 x i64> %max to <2 x i32>
|
|
%shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i32> %shuffle
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(smax(smin(Y, 2^n-1), -2^n))) pattern.
|
|
|
|
define <16 x i8> @signed_maxmin_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
|
|
; CHECK-LABEL: signed_maxmin_v8i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtn2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
|
|
%min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %max, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
|
|
%trunc = trunc <8 x i16> %min to <8 x i8>
|
|
%shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <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> %shuffle
|
|
}
|
|
|
|
define <8 x i16> @signed_maxmin_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: signed_maxmin_v4i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
|
|
%min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %max, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
|
|
%trunc = trunc <4 x i32> %min to <4 x i16>
|
|
%shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i32> @signed_maxmin_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
|
|
; CHECK-LABEL: signed_maxmin_v2i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> <i64 -2147483648, i64 -2147483648>)
|
|
%min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %max, <2 x i64> <i64 2147483647, i64 2147483647>)
|
|
%trunc = trunc <2 x i64> %min to <2 x i32>
|
|
%shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i32> %shuffle
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(umin(Y, 2^n)))) pattern.
|
|
|
|
define <16 x i8> @unsigned_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
|
|
; CHECK-LABEL: unsigned_v8i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: uqxtn2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %y, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
|
|
%trunc = trunc <8 x i16> %min to <8 x i8>
|
|
%shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <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> %shuffle
|
|
}
|
|
|
|
define <8 x i16> @unsigned_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: unsigned_v4i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: uqxtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %y, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
|
|
%trunc = trunc <4 x i32> %min to <4 x i16>
|
|
%shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i32> @unsigned_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
|
|
; CHECK-LABEL: unsigned_v2i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: uqxtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %y, <2 x i64> <i64 4294967295, i64 4294967295>)
|
|
%trunc = trunc <2 x i64> %min to <2 x i32>
|
|
%shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i32> %shuffle
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(umin(smax(Y, 0), 2^n))))) pattern.
|
|
|
|
define <16 x i8> @us_maxmin_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
|
|
; CHECK-LABEL: us_maxmin_v8i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtun2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> zeroinitializer)
|
|
%min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %max, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
|
|
%trunc = trunc <8 x i16> %min to <8 x i8>
|
|
%shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <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> %shuffle
|
|
}
|
|
|
|
define <8 x i16> @us_maxmin_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: us_maxmin_v4i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtun2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)
|
|
%min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %max, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
|
|
%trunc = trunc <4 x i32> %min to <4 x i16>
|
|
%shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i32> @us_maxmin_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
|
|
; CHECK-LABEL: us_maxmin_v2i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtun2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)
|
|
%min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %max, <2 x i64> <i64 4294967295, i64 4294967295>)
|
|
%trunc = trunc <2 x i64> %min to <2 x i32>
|
|
%shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i32> %shuffle
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(smin(smax(Y, 0), 2^n))))) pattern.
|
|
|
|
define <16 x i8> @sminsmax_range_unsigned_i16_to_i8(<8 x i8> %x, <8 x i16> %y) {
|
|
; CHECK-LABEL: sminsmax_range_unsigned_i16_to_i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtun2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> zeroinitializer)
|
|
%max = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %min, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
|
|
%trunc = trunc <8 x i16> %max to <8 x i8>
|
|
%shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <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> %shuffle
|
|
}
|
|
|
|
define <8 x i16> @sminsmax_range_unsigned_i32_to_i16(<4 x i16> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: sminsmax_range_unsigned_i32_to_i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtun2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)
|
|
%smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
|
|
%trunc = trunc <4 x i32> %smin to <4 x i16>
|
|
%shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i32> @sminsmax_range_unsigned_i64_to_i32(<2 x i32> %x, <2 x i64> %y) {
|
|
; CHECK-LABEL: sminsmax_range_unsigned_i64_to_i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: sqxtun2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)
|
|
%smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 4294967295, i64 4294967295>)
|
|
%trunc = trunc <2 x i64> %smin to <2 x i32>
|
|
%shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i32> %shuffle
|
|
}
|
|
|
|
|
|
|
|
; Test the (concat_vectors (X), (trunc(smin(smax(Y, -2^n), 2^n-1))) pattern.
|
|
|
|
define <16 x i8> @signed_minmax_v16i16_to_v16i8(<16 x i16> %y) {
|
|
; CHECK-LABEL: signed_minmax_v16i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.8b, v0.8h
|
|
; CHECK-NEXT: sqxtn2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <16 x i16> @llvm.smin.v16i16(<16 x i16> %y, <16 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
|
|
%max = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %min, <16 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
|
|
%trunc = trunc <16 x i16> %max to <16 x i8>
|
|
ret <16 x i8> %trunc
|
|
}
|
|
|
|
define <8 x i16> @signed_minmax_v8i32_to_v8i16(<8 x i32> %y) {
|
|
; CHECK-LABEL: signed_minmax_v8i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.4h, v0.4s
|
|
; CHECK-NEXT: sqxtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %y, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)
|
|
%max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
|
|
%trunc = trunc <8 x i32> %max to <8 x i16>
|
|
ret <8 x i16> %trunc
|
|
}
|
|
|
|
define <4 x i32> @signed_minmax_v4i64_to_v4i32(<4 x i64> %y) {
|
|
; CHECK-LABEL: signed_minmax_v4i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.2s, v0.2d
|
|
; CHECK-NEXT: sqxtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %y, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
|
|
%max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %min, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
|
|
%trunc = trunc <4 x i64> %max to <4 x i32>
|
|
ret <4 x i32> %trunc
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(smax(smin(Y, 2^n-1), -2^n))) pattern.
|
|
|
|
define <16 x i8> @signed_maxmin_v16i16_to_v16i8(<16 x i16> %y) {
|
|
; CHECK-LABEL: signed_maxmin_v16i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.8b, v0.8h
|
|
; CHECK-NEXT: sqxtn2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %y, <16 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
|
|
%min = call <16 x i16> @llvm.smin.v16i16(<16 x i16> %max, <16 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
|
|
%trunc = trunc <16 x i16> %min to <16 x i8>
|
|
ret <16 x i8> %trunc
|
|
}
|
|
|
|
define <8 x i16> @signed_maxmin_v8i32_to_v8i16(<8 x i32> %y) {
|
|
; CHECK-LABEL: signed_maxmin_v8i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.4h, v0.4s
|
|
; CHECK-NEXT: sqxtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %y, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
|
|
%min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)
|
|
%trunc = trunc <8 x i32> %min to <8 x i16>
|
|
ret <8 x i16> %trunc
|
|
}
|
|
|
|
define <4 x i32> @signed_maxmin_v4i64_to_v4i32(<4 x i64> %y) {
|
|
; CHECK-LABEL: signed_maxmin_v4i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtn v0.2s, v0.2d
|
|
; CHECK-NEXT: sqxtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %y, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
|
|
%min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %max, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
|
|
%trunc = trunc <4 x i64> %min to <4 x i32>
|
|
ret <4 x i32> %trunc
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(umin(Y, 2^n)))) pattern.
|
|
|
|
define <16 x i8> @unsigned_v16i16_to_v16i8(<16 x i16> %y) {
|
|
; CHECK-LABEL: unsigned_v16i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: uqxtn v0.8b, v0.8h
|
|
; CHECK-NEXT: uqxtn2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <16 x i16> @llvm.umin.v8i16(<16 x i16> %y, <16 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
|
|
%trunc = trunc <16 x i16> %min to <16 x i8>
|
|
ret <16 x i8> %trunc
|
|
}
|
|
|
|
define <8 x i16> @unsigned_v8i32_to_v8i16(<8 x i32> %y) {
|
|
; CHECK-LABEL: unsigned_v8i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: uqxtn v0.4h, v0.4s
|
|
; CHECK-NEXT: uqxtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <8 x i32> @llvm.umin.v4i32(<8 x i32> %y, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
|
|
%trunc = trunc <8 x i32> %min to <8 x i16>
|
|
ret <8 x i16> %trunc
|
|
}
|
|
|
|
define <4 x i32> @unsigned_v4i64_to_v4i32(<4 x i64> %y) {
|
|
; CHECK-LABEL: unsigned_v4i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: uqxtn v0.2s, v0.2d
|
|
; CHECK-NEXT: uqxtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <4 x i64> @llvm.umin.v2i64(<4 x i64> %y, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
|
|
%trunc = trunc <4 x i64> %min to <4 x i32>
|
|
ret <4 x i32> %trunc
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(umin(smax(Y, 0), 2^n))))) pattern.
|
|
|
|
define <16 x i8> @us_maxmin_v16i16_to_v16i8(<16 x i16> %y) {
|
|
; CHECK-LABEL: us_maxmin_v16i16_to_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.8b, v0.8h
|
|
; CHECK-NEXT: sqxtun2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %y, <16 x i16> zeroinitializer)
|
|
%min = call <16 x i16> @llvm.umin.v16i16(<16 x i16> %max, <16 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
|
|
%trunc = trunc <16 x i16> %min to <16 x i8>
|
|
ret <16 x i8> %trunc
|
|
}
|
|
|
|
define <8 x i16> @us_maxmin_v8i32_to_v8i16(<8 x i32> %y) {
|
|
; CHECK-LABEL: us_maxmin_v8i32_to_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.4h, v0.4s
|
|
; CHECK-NEXT: sqxtun2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %y, <8 x i32> zeroinitializer)
|
|
%min = call <8 x i32> @llvm.umin.v8i32(<8 x i32> %max, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
|
|
%trunc = trunc <8 x i32> %min to <8 x i16>
|
|
ret <8 x i16> %trunc
|
|
}
|
|
|
|
define <4 x i32> @us_maxmin_v4i64_to_v4i32(<4 x i64> %y) {
|
|
; CHECK-LABEL: us_maxmin_v4i64_to_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.2s, v0.2d
|
|
; CHECK-NEXT: sqxtun2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %y, <4 x i64> zeroinitializer)
|
|
%min = call <4 x i64> @llvm.umin.v4i64(<4 x i64> %max, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
|
|
%trunc = trunc <4 x i64> %min to <4 x i32>
|
|
ret <4 x i32> %trunc
|
|
}
|
|
|
|
; Test the (concat_vectors (X), (trunc(smin(smax(Y, 0), 2^n))))) pattern.
|
|
|
|
define <16 x i8> @sminsmax_range_unsig16ed_i16_to_i8(<16 x i16> %y) {
|
|
; CHECK-LABEL: sminsmax_range_unsig16ed_i16_to_i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.8b, v0.8h
|
|
; CHECK-NEXT: sqxtun2 v0.16b, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%min = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %y, <16 x i16> zeroinitializer)
|
|
%max = call <16 x i16> @llvm.smin.v16i16(<16 x i16> %min, <16 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
|
|
%trunc = trunc <16 x i16> %max to <16 x i8>
|
|
ret <16 x i8> %trunc
|
|
}
|
|
|
|
define <8 x i16> @sminsmax_range_unsign8d_i32_to_i16(<8 x i32> %y) {
|
|
; CHECK-LABEL: sminsmax_range_unsign8d_i32_to_i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.4h, v0.4s
|
|
; CHECK-NEXT: sqxtun2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%smax = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %y, <8 x i32> zeroinitializer)
|
|
%smin = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %smax, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
|
|
%trunc = trunc <8 x i32> %smin to <8 x i16>
|
|
ret <8 x i16> %trunc
|
|
}
|
|
|
|
define <4 x i32> @sminsmax_range_unsign4d_i64_to_i32(<4 x i64> %y) {
|
|
; CHECK-LABEL: sminsmax_range_unsign4d_i64_to_i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: sqxtun v0.2s, v0.2d
|
|
; CHECK-NEXT: sqxtun2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%smax = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %y, <4 x i64> zeroinitializer)
|
|
%smin = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %smax, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
|
|
%trunc = trunc <4 x i64> %smin to <4 x i32>
|
|
ret <4 x i32> %trunc
|
|
}
|
|
|
|
|
|
|
|
; Type support varification - not supported with saturated value
|
|
; i64 -> i16
|
|
define <4 x i16> @sminsmax_range_unsigned_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {
|
|
; CHECK-SD-LABEL: sminsmax_range_unsigned_i64_to_i16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: cmgt v2.2d, v1.2d, #0
|
|
; CHECK-SD-NEXT: movi v3.2d, #0x0000000000ffff
|
|
; CHECK-SD-NEXT: and v1.16b, v1.16b, v2.16b
|
|
; CHECK-SD-NEXT: cmgt v2.2d, v3.2d, v1.2d
|
|
; CHECK-SD-NEXT: bif v1.16b, v3.16b, v2.16b
|
|
; CHECK-SD-NEXT: xtn v1.2s, v1.2d
|
|
; CHECK-SD-NEXT: uzp1 v0.4h, v0.4h, v1.4h
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: sminsmax_range_unsigned_i64_to_i16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: cmgt v3.2d, v1.2d, #0
|
|
; CHECK-GI-NEXT: movi v2.2d, #0x0000000000ffff
|
|
; CHECK-GI-NEXT: uzp1 v0.4h, v0.4h, v0.4h
|
|
; CHECK-GI-NEXT: and v1.16b, v1.16b, v3.16b
|
|
; CHECK-GI-NEXT: cmgt v3.2d, v2.2d, v1.2d
|
|
; CHECK-GI-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-GI-NEXT: xtn v1.2s, v1.2d
|
|
; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)
|
|
%smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 65535, i64 65535>)
|
|
%trunc = trunc <2 x i64> %smin to <2 x i16>
|
|
%shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i16> @sminsmax_range_signed_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {
|
|
; CHECK-SD-LABEL: sminsmax_range_signed_i64_to_i16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: mov x8, #-32768 // =0xffffffffffff8000
|
|
; CHECK-SD-NEXT: dup v2.2d, x8
|
|
; CHECK-SD-NEXT: mov w8, #32767 // =0x7fff
|
|
; CHECK-SD-NEXT: cmgt v3.2d, v1.2d, v2.2d
|
|
; CHECK-SD-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-SD-NEXT: dup v2.2d, x8
|
|
; CHECK-SD-NEXT: cmgt v3.2d, v2.2d, v1.2d
|
|
; CHECK-SD-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-SD-NEXT: xtn v1.2s, v1.2d
|
|
; CHECK-SD-NEXT: uzp1 v0.4h, v0.4h, v1.4h
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: sminsmax_range_signed_i64_to_i16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: adrp x8, .LCPI46_1
|
|
; CHECK-GI-NEXT: uzp1 v0.4h, v0.4h, v0.4h
|
|
; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI46_1]
|
|
; CHECK-GI-NEXT: adrp x8, .LCPI46_0
|
|
; CHECK-GI-NEXT: cmgt v3.2d, v1.2d, v2.2d
|
|
; CHECK-GI-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI46_0]
|
|
; CHECK-GI-NEXT: cmgt v3.2d, v2.2d, v1.2d
|
|
; CHECK-GI-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-GI-NEXT: xtn v1.2s, v1.2d
|
|
; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> <i64 -32768, i64 -32768>)
|
|
%smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 32767, i64 32767>)
|
|
%trunc = trunc <2 x i64> %smin to <2 x i16>
|
|
%shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i16> %shuffle
|
|
}
|
|
|
|
define <4 x i16> @umin_range_unsigned_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {
|
|
; CHECK-SD-LABEL: umin_range_unsigned_i64_to_i16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: movi v2.2d, #0x0000000000ffff
|
|
; CHECK-SD-NEXT: cmhi v3.2d, v2.2d, v1.2d
|
|
; CHECK-SD-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-SD-NEXT: xtn v1.2s, v1.2d
|
|
; CHECK-SD-NEXT: uzp1 v0.4h, v0.4h, v1.4h
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: umin_range_unsigned_i64_to_i16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: movi v2.2d, #0x0000000000ffff
|
|
; CHECK-GI-NEXT: uzp1 v0.4h, v0.4h, v0.4h
|
|
; CHECK-GI-NEXT: cmhi v3.2d, v2.2d, v1.2d
|
|
; CHECK-GI-NEXT: bif v1.16b, v2.16b, v3.16b
|
|
; CHECK-GI-NEXT: xtn v1.2s, v1.2d
|
|
; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%umin = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %y, <2 x i64> <i64 65535, i64 65535>)
|
|
%trunc = trunc <2 x i64> %umin to <2 x i16>
|
|
%shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
ret <4 x i16> %shuffle
|
|
}
|
|
|
|
; i32 -> i8
|
|
define <8 x i8> @sminsmax_range_unsigned_i64_to_i8(<4 x i8> %x, <4 x i32> %y) {
|
|
; CHECK-SD-LABEL: sminsmax_range_unsigned_i64_to_i8:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: movi v2.2d, #0000000000000000
|
|
; CHECK-SD-NEXT: movi v3.2d, #0x0000ff000000ff
|
|
; CHECK-SD-NEXT: smax v1.4s, v1.4s, v2.4s
|
|
; CHECK-SD-NEXT: smin v1.4s, v1.4s, v3.4s
|
|
; CHECK-SD-NEXT: xtn v1.4h, v1.4s
|
|
; CHECK-SD-NEXT: uzp1 v0.8b, v0.8b, v1.8b
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: sminsmax_range_unsigned_i64_to_i8:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: movi v2.2d, #0000000000000000
|
|
; CHECK-GI-NEXT: movi v3.2d, #0x0000ff000000ff
|
|
; CHECK-GI-NEXT: uzp1 v0.8b, v0.8b, v0.8b
|
|
; CHECK-GI-NEXT: smax v1.4s, v1.4s, v2.4s
|
|
; CHECK-GI-NEXT: smin v1.4s, v1.4s, v3.4s
|
|
; CHECK-GI-NEXT: xtn v1.4h, v1.4s
|
|
; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)
|
|
%smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 255, i32 255, i32 255, i32 255>)
|
|
%trunc = trunc <4 x i32> %smin to <4 x i8>
|
|
%shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i8> %shuffle
|
|
}
|
|
|
|
define <8 x i8> @sminsmax_range_signed_i32_to_i8(<4 x i8> %x, <4 x i32> %y) {
|
|
; CHECK-SD-LABEL: sminsmax_range_signed_i32_to_i8:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: mvni v2.4s, #127
|
|
; CHECK-SD-NEXT: movi v3.4s, #127
|
|
; CHECK-SD-NEXT: smax v1.4s, v1.4s, v2.4s
|
|
; CHECK-SD-NEXT: smin v1.4s, v1.4s, v3.4s
|
|
; CHECK-SD-NEXT: xtn v1.4h, v1.4s
|
|
; CHECK-SD-NEXT: uzp1 v0.8b, v0.8b, v1.8b
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: sminsmax_range_signed_i32_to_i8:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: mvni v2.4s, #127
|
|
; CHECK-GI-NEXT: movi v3.4s, #127
|
|
; CHECK-GI-NEXT: uzp1 v0.8b, v0.8b, v0.8b
|
|
; CHECK-GI-NEXT: smax v1.4s, v1.4s, v2.4s
|
|
; CHECK-GI-NEXT: smin v1.4s, v1.4s, v3.4s
|
|
; CHECK-GI-NEXT: xtn v1.4h, v1.4s
|
|
; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> <i32 -128, i32 -128, i32 -128, i32 -128>)
|
|
%smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 127, i32 127, i32 127, i32 127>)
|
|
%trunc = trunc <4 x i32> %smin to <4 x i8>
|
|
%shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i8> %shuffle
|
|
}
|
|
|
|
define <8 x i8> @umin_range_unsigned_i32_to_i8(<4 x i8> %x, <4 x i32> %y) {
|
|
; CHECK-SD-LABEL: umin_range_unsigned_i32_to_i8:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: movi v2.2d, #0x0000ff000000ff
|
|
; CHECK-SD-NEXT: umin v1.4s, v1.4s, v2.4s
|
|
; CHECK-SD-NEXT: xtn v1.4h, v1.4s
|
|
; CHECK-SD-NEXT: uzp1 v0.8b, v0.8b, v1.8b
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: umin_range_unsigned_i32_to_i8:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: movi v2.2d, #0x0000ff000000ff
|
|
; CHECK-GI-NEXT: uzp1 v0.8b, v0.8b, v0.8b
|
|
; CHECK-GI-NEXT: umin v1.4s, v1.4s, v2.4s
|
|
; CHECK-GI-NEXT: xtn v1.4h, v1.4s
|
|
; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%umin = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %y, <4 x i32> <i32 255, i32 255, i32 255, i32 255>)
|
|
%trunc = trunc <4 x i32> %umin to <4 x i8>
|
|
%shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
ret <8 x i8> %shuffle
|
|
}
|
|
|
|
define <16 x i8> @uqxtn_i32_i8(<16 x i32> %0) {
|
|
; CHECK-SD-LABEL: uqxtn_i32_i8:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: movi v4.2d, #0x0000ff000000ff
|
|
; CHECK-SD-NEXT: umin v1.4s, v1.4s, v4.4s
|
|
; CHECK-SD-NEXT: umin v0.4s, v0.4s, v4.4s
|
|
; CHECK-SD-NEXT: umin v3.4s, v3.4s, v4.4s
|
|
; CHECK-SD-NEXT: umin v2.4s, v2.4s, v4.4s
|
|
; CHECK-SD-NEXT: uzp1 v0.8h, v0.8h, v1.8h
|
|
; CHECK-SD-NEXT: uzp1 v2.8h, v2.8h, v3.8h
|
|
; CHECK-SD-NEXT: uzp1 v0.16b, v0.16b, v2.16b
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: uqxtn_i32_i8:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: movi v4.2d, #0x0000ff000000ff
|
|
; CHECK-GI-NEXT: umin v0.4s, v0.4s, v4.4s
|
|
; CHECK-GI-NEXT: umin v1.4s, v1.4s, v4.4s
|
|
; CHECK-GI-NEXT: umin v2.4s, v2.4s, v4.4s
|
|
; CHECK-GI-NEXT: umin v3.4s, v3.4s, v4.4s
|
|
; CHECK-GI-NEXT: uzp1 v0.8h, v0.8h, v1.8h
|
|
; CHECK-GI-NEXT: uzp1 v1.8h, v2.8h, v3.8h
|
|
; CHECK-GI-NEXT: uzp1 v0.16b, v0.16b, v1.16b
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%1 = tail call <16 x i32> @llvm.umin.v16i32(<16 x i32> %0, <16 x i32> splat (i32 255))
|
|
%2 = trunc <16 x i32> %1 to <16 x i8>
|
|
ret <16 x i8> %2
|
|
}
|