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
6440 lines
312 KiB
C
6440 lines
312 KiB
C
// REQUIRES: aarch64-registered-target || arm-registered-target
|
|
|
|
// RUN: %clang_cc1_cg_arm64_neon -emit-llvm %s -disable-O0-optnone | opt -S -passes=mem2reg,sroa | FileCheck %s --check-prefixes=ALL,LLVM
|
|
// RUN: %if cir-enabled %{%clang_cc1_cg_arm64_neon -fclangir -emit-llvm %s -disable-O0-optnone | opt -S -passes=mem2reg,sroa | FileCheck %s --check-prefixes=ALL,LLVM %}
|
|
// RUN: %if cir-enabled %{%clang_cc1_cg_arm64_neon -fclangir -emit-cir %s -disable-O0-optnone | FileCheck %s --check-prefixes=ALL,CIR %}
|
|
|
|
//=============================================================================
|
|
// NOTES
|
|
//
|
|
// This file contains tests that were originally located in
|
|
// * clang/test/CodeGen/AArch64/neon-intrinsics.c.
|
|
// The main difference is the use of RUN lines that enable ClangIR lowering;
|
|
// therefore only builtins currently supported by ClangIR are tested here.
|
|
// Once ClangIR support is complete, this file is intended to replace the
|
|
// original test file.
|
|
//
|
|
// ACLE section headings based on v2025Q2 of the ACLE specification:
|
|
// * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#bitwise-equal-to-zero
|
|
//
|
|
// Different labels for CIR stem from an additional function call that is
|
|
// present at the AST and CIR levels, but is inlined at the LLVM IR level.
|
|
//
|
|
//=============================================================================
|
|
|
|
#include <arm_neon.h>
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.2.7 Vector saturating rounding shift right and narrow
|
|
// TODO: Implement SISD variants
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vqrshrun_n_s16(
|
|
uint8x8_t test_vqrshrun_n_s16(int16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: {{.*}} = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP:%.*]] = bitcast <16 x i8> {{.*}} to <8 x i16>
|
|
// LLVM: [[VQRSHRUN_N1:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrun.v8i8(<8 x i16> [[TMP]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VQRSHRUN_N1]]
|
|
return vqrshrun_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrun_n_s32(
|
|
uint16x4_t test_vqrshrun_n_s32(int32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[BC1:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[BC2:%.*]] = bitcast <16 x i8> [[BC1]] to <4 x i32>
|
|
// LLVM: [[VQRSHRUN_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrun.v4i16(<4 x i32> [[BC2]], i32 9)
|
|
// LLVM: ret <4 x i16> [[VQRSHRUN_N1]]
|
|
return vqrshrun_n_s32(a, 9);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrun_n_s64(
|
|
uint32x2_t test_vqrshrun_n_s64(int64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[BC1:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[BC2:%.*]] = bitcast <16 x i8> [[BC1]] to <2 x i64>
|
|
// LLVM: [[VQRSHRUN_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.sqrshrun.v2i32(<2 x i64> [[BC2]], i32 19)
|
|
// LLVM: ret <2 x i32> [[VQRSHRUN_N1]]
|
|
return vqrshrun_n_s64(a, 19);
|
|
}
|
|
|
|
//ALL-LABEL: @test_vqrshrund_n_s64(
|
|
uint32_t test_vqrshrund_n_s64(int64_t a) {
|
|
//CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[VQRSHRUND_N_S64:%.*]] = call i32 @llvm.aarch64.neon.sqrshrun.i32(i64 [[A]], i32 32)
|
|
// LLVM: ret i32 [[VQRSHRUND_N_S64]]
|
|
return (uint32_t)vqrshrund_n_s64(a, 32);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_n_s16(
|
|
int8x8_t test_vqrshrn_n_s16(int16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[BC1:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[BC2:%.*]] = bitcast <16 x i8> [[BC1]] to <8 x i16>
|
|
// LLVM: [[VQRSHRN_N1:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrn.v8i8(<8 x i16> [[BC2]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VQRSHRN_N1]]
|
|
return vqrshrn_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_n_s32(
|
|
int16x4_t test_vqrshrn_n_s32(int32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[BC1:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[BC2:%.*]] = bitcast <16 x i8> [[BC1]] to <4 x i32>
|
|
// LLVM: [[VQRSHRN_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrn.v4i16(<4 x i32> [[BC2]], i32 9)
|
|
// LLVM: ret <4 x i16> [[VQRSHRN_N1]]
|
|
return vqrshrn_n_s32(a, 9);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_n_s64(
|
|
int32x2_t test_vqrshrn_n_s64(int64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[BC1:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[BC2:%.*]] = bitcast <16 x i8> [[BC1]] to <2 x i64>
|
|
// LLVM: [[VQRSHRN_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.sqrshrn.v2i32(<2 x i64> [[BC2]], i32 19)
|
|
// LLVM: ret <2 x i32> [[VQRSHRN_N1]]
|
|
return vqrshrn_n_s64(a, 19);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrun_high_n_s16(
|
|
uint8x16_t test_vqrshrun_high_n_s16(uint8x8_t a, int16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRUN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VQRSHRUN_N3:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrun.v8i8(<8 x i16> [[VQRSHRUN_N]], i32 3)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> [[VQRSHRUN_N3]], <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>
|
|
// LLVM: ret <16 x i8> [[SHUFFLE_I]]
|
|
return vqrshrun_high_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrun_high_n_s32(
|
|
uint16x8_t test_vqrshrun_high_n_s32(uint16x4_t a, int32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRUN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VQRSHRUN_N3:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrun.v4i16(<4 x i32> [[VQRSHRUN_N]], i32 9)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[A]], <4 x i16> [[VQRSHRUN_N3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM: ret <8 x i16> [[SHUFFLE_I]]
|
|
return vqrshrun_high_n_s32(a, b, 9);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrun_high_n_s64(
|
|
uint32x4_t test_vqrshrun_high_n_s64(uint32x2_t a, int64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun"
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRUN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VQRSHRUN_N3:%.*]] = call <2 x i32> @llvm.aarch64.neon.sqrshrun.v2i32(<2 x i64> [[VQRSHRUN_N]], i32 19)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> [[VQRSHRUN_N3]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
// LLVM: ret <4 x i32> [[SHUFFLE_I]]
|
|
return vqrshrun_high_n_s64(a, b, 19);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_n_u16(
|
|
uint8x8_t test_vqrshrn_n_u16(uint16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VQRSHRN_N1:%.*]] = call <8 x i8> @llvm.aarch64.neon.uqrshrn.v8i8(<8 x i16> [[VQRSHRN_N]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VQRSHRN_N1]]
|
|
return vqrshrn_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_n_u32(
|
|
uint16x4_t test_vqrshrn_n_u32(uint32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VQRSHRN_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.uqrshrn.v4i16(<4 x i32> [[VQRSHRN_N]], i32 9)
|
|
// LLVM: ret <4 x i16> [[VQRSHRN_N1]]
|
|
return vqrshrn_n_u32(a, 9);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_n_u64(
|
|
uint32x2_t test_vqrshrn_n_u64(uint64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VQRSHRN_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.uqrshrn.v2i32(<2 x i64> [[VQRSHRN_N]], i32 19)
|
|
// LLVM: ret <2 x i32> [[VQRSHRN_N1]]
|
|
return vqrshrn_n_u64(a, 19);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrnd_n_s64(
|
|
int32_t test_vqrshrnd_n_s64(int64_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: i64 noundef [[A:%.*]])
|
|
// LLVM: [[VQRSHRND_N_S64:%.*]] = call i32 @llvm.aarch64.neon.sqrshrn.i32(i64 [[A]], i32 32)
|
|
// LLVM: ret i32 [[VQRSHRND_N_S64]]
|
|
return (int32_t)vqrshrnd_n_s64(a, 32);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrnd_n_u64(
|
|
uint32_t test_vqrshrnd_n_u64(uint64_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: i64 noundef [[A:%.*]])
|
|
// LLVM: [[VQRSHRND_N_U64:%.*]] = call i32 @llvm.aarch64.neon.uqrshrn.i32(i64 [[A]], i32 32)
|
|
// LLVM: ret i32 [[VQRSHRND_N_U64]]
|
|
return (uint32_t)vqrshrnd_n_u64(a, 32);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_high_n_s16(
|
|
int8x16_t test_vqrshrn_high_n_s16(int8x8_t a, int16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VQRSHRN_N3:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrn.v8i8(<8 x i16> [[VQRSHRN_N]], i32 3)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> [[VQRSHRN_N3]], <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>
|
|
// LLVM: ret <16 x i8> [[SHUFFLE_I]]
|
|
return vqrshrn_high_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_high_n_s32(
|
|
int16x8_t test_vqrshrn_high_n_s32(int16x4_t a, int32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VQRSHRN_N3:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrn.v4i16(<4 x i32> [[VQRSHRN_N]], i32 9)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[A]], <4 x i16> [[VQRSHRN_N3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM: ret <8 x i16> [[SHUFFLE_I]]
|
|
return vqrshrn_high_n_s32(a, b, 9);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_high_n_s64(
|
|
int32x4_t test_vqrshrn_high_n_s64(int32x2_t a, int64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrn"
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VQRSHRN_N3:%.*]] = call <2 x i32> @llvm.aarch64.neon.sqrshrn.v2i32(<2 x i64> [[VQRSHRN_N]], i32 19)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> [[VQRSHRN_N3]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
// LLVM: ret <4 x i32> [[SHUFFLE_I]]
|
|
return vqrshrn_high_n_s64(a, b, 19);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_high_n_u16(
|
|
uint8x16_t test_vqrshrn_high_n_u16(uint8x8_t a, uint16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VQRSHRN_N3:%.*]] = call <8 x i8> @llvm.aarch64.neon.uqrshrn.v8i8(<8 x i16> [[VQRSHRN_N]], i32 3)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> [[VQRSHRN_N3]], <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>
|
|
// LLVM: ret <16 x i8> [[SHUFFLE_I]]
|
|
return vqrshrn_high_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_high_n_u32(
|
|
uint16x8_t test_vqrshrn_high_n_u32(uint16x4_t a, uint32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VQRSHRN_N3:%.*]] = call <4 x i16> @llvm.aarch64.neon.uqrshrn.v4i16(<4 x i32> [[VQRSHRN_N]], i32 9)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[A]], <4 x i16> [[VQRSHRN_N3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM: ret <8 x i16> [[SHUFFLE_I]]
|
|
return vqrshrn_high_n_u32(a, b, 9);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqrshrn_high_n_u64(
|
|
uint32x4_t test_vqrshrn_high_n_u64(uint32x2_t a, uint64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uqrshrn"
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VQRSHRN_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VQRSHRN_N3:%.*]] = call <2 x i32> @llvm.aarch64.neon.uqrshrn.v2i32(<2 x i64> [[VQRSHRN_N]], i32 19)
|
|
// LLVM: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[A]], <2 x i32> [[VQRSHRN_N3]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
// LLVM: ret <4 x i32> [[SHUFFLE_I]]
|
|
return vqrshrn_high_n_u64(a, b, 19);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.13.3 Maximum across vector
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vmaxv_s8(
|
|
// CIR-LABEL: @vmaxv_s8(
|
|
int8_t test_vmaxv_s8(int8x8_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxv_s8({{%.*}}) : (!cir.vector<8 x !s8i> {{.*}}) -> !s8i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_S8_I:%.*]] = call i8 @llvm.vector.reduce.smax.v8i8(<8 x i8> [[A]])
|
|
// LLVM: ret i8 [[VMAXV_S8_I]]
|
|
return vmaxv_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_s8(
|
|
// CIR-LABEL: @vmaxvq_s8(
|
|
int8_t test_vmaxvq_s8(int8x16_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxvq_s8({{%.*}}) : (!cir.vector<16 x !s8i> {{.*}}) -> !s8i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_S8_I:%.*]] = call i8 @llvm.vector.reduce.smax.v16i8(<16 x i8> [[A]])
|
|
// LLVM: ret i8 [[VMAXVQ_S8_I]]
|
|
return vmaxvq_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxv_s16(
|
|
// CIR-LABEL: @vmaxv_s16(
|
|
int16_t test_vmaxv_s16(int16x4_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxv_s16({{%.*}}) : (!cir.vector<4 x !s16i> {{.*}}) -> !s16i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_S16_I:%.*]] = call i16 @llvm.vector.reduce.smax.v4i16(<4 x i16> [[A]])
|
|
// LLVM: ret i16 [[VMAXV_S16_I]]
|
|
return vmaxv_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_s16(
|
|
// CIR-LABEL: @vmaxvq_s16(
|
|
int16_t test_vmaxvq_s16(int16x8_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxvq_s16({{%.*}}) : (!cir.vector<8 x !s16i> {{.*}}) -> !s16i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_S16_I:%.*]] = call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[A]])
|
|
// LLVM: ret i16 [[VMAXVQ_S16_I]]
|
|
return vmaxvq_s16(a);
|
|
}
|
|
|
|
//LLVM-LABEL: @test_vmaxv_s32
|
|
//CIR-LABEL : @vmaxv_s32
|
|
int32_t test_vmaxv_s32(int32x2_t a) {
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "vector.reduce.smax" {{%.*}}
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_S32_I:%.*]] = call i32 @llvm.vector.reduce.smax.v2i32(<2 x i32> [[A]])
|
|
// LLVM: ret i32 [[VMAXV_S32_I]]
|
|
return vmaxv_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_s32(
|
|
// CIR-LABEL: @vmaxvq_s32(
|
|
int32_t test_vmaxvq_s32(int32x4_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxvq_s32({{%.*}}) : (!cir.vector<4 x !s32i> {{.*}}) -> !s32i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_S32_I:%.*]] = call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> [[A]])
|
|
// LLVM: ret i32 [[VMAXVQ_S32_I]]
|
|
return vmaxvq_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxv_u8(
|
|
// CIR-LABEL: @vmaxv_u8(
|
|
uint8_t test_vmaxv_u8(uint8x8_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxv_u8({{%.*}}) : (!cir.vector<8 x !u8i> {{.*}}) -> !u8i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_U8_I:%.*]] = call i8 @llvm.vector.reduce.umax.v8i8(<8 x i8> [[A]])
|
|
// LLVM: ret i8 [[VMAXV_U8_I]]
|
|
return vmaxv_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_u8(
|
|
// CIR-LABEL: @vmaxvq_u8(
|
|
uint8_t test_vmaxvq_u8(uint8x16_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxvq_u8({{%.*}}) : (!cir.vector<16 x !u8i> {{.*}}) -> !u8i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_U8_I:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[A]])
|
|
// LLVM: ret i8 [[VMAXVQ_U8_I]]
|
|
return vmaxvq_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxv_u16(
|
|
// CIR-LABEL: @vmaxv_u16(
|
|
uint16_t test_vmaxv_u16(uint16x4_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxv_u16({{%.*}}) : (!cir.vector<4 x !u16i> {{.*}}) -> !u16i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_U16_I:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[A]])
|
|
// LLVM: ret i16 [[VMAXV_U16_I]]
|
|
return vmaxv_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_u16(
|
|
// CIR-LABEL: @vmaxvq_u16(
|
|
uint16_t test_vmaxvq_u16(uint16x8_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxvq_u16({{%.*}}) : (!cir.vector<8 x !u16i> {{.*}}) -> !u16i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_U16_I:%.*]] = call i16 @llvm.vector.reduce.umax.v8i16(<8 x i16> [[A]])
|
|
// LLVM: ret i16 [[VMAXVQ_U16_I]]
|
|
return vmaxvq_u16(a);
|
|
}
|
|
|
|
//LLVM-LABEL: @test_vmaxv_u32(
|
|
//CIR-LABEL : @vmaxv_u32(
|
|
uint32_t test_vmaxv_u32(uint32x2_t a) {
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "vector.reduce.umax" {{%.*}}
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_U32_I:%.*]] = call i32 @llvm.vector.reduce.umax.v2i32(<2 x i32> [[A]])
|
|
// LLVM: ret i32 [[VMAXV_U32_I]]
|
|
return vmaxv_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_u32(
|
|
// CIR-LABEL: @vmaxvq_u32(
|
|
uint32_t test_vmaxvq_u32(uint32x4_t a) {
|
|
// CIR: {{%.*}} = cir.call @vmaxvq_u32({{%.*}}) : (!cir.vector<4 x !u32i> {{.*}}) -> !u32i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_U32_I:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[A]])
|
|
// LLVM: ret i32 [[VMAXVQ_U32_I]]
|
|
return vmaxvq_u32(a);
|
|
}
|
|
|
|
//LLVM-LABEL: @test_vmaxv_f32
|
|
//CIR-LABEL : @vmaxv_f32
|
|
float32_t test_vmaxv_f32(float32x2_t a) {
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmaxv" {{%.*}}
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXV_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxv.f32.v2f32(<2 x float> [[A]])
|
|
// LLVM: ret float [[VMAXV_F32_I]]
|
|
return vmaxv_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxvq_f32(
|
|
// CIR-LABEL: @vmaxvq_f32(
|
|
float32_t test_vmaxvq_f32(float32x4_t a) {
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmaxv" {{%.*}}
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fmaxv.f32.v4f32(<4 x float> [[A]])
|
|
// LLVM: ret float [[VMAXVQ_F32_I]]
|
|
return vmaxvq_f32(a);
|
|
}
|
|
|
|
//LLVM-LABEL: @test_vmaxvq_f64(
|
|
//CIR-LABEL : @vmaxvq_f64(
|
|
float64_t test_vmaxvq_f64(float64x2_t a) {
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmaxv" {{%.*}}
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}}[[A:%.*]])
|
|
// LLVM: [[VMAXVQ_F64_I:%.*]] = call double @llvm.aarch64.neon.fmaxv.f64.v2f64(<2 x double> [[A]])
|
|
// LLVM: ret double [[VMAXVQ_F64_I]]
|
|
return vmaxvq_f64(a);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.2 Vector Saturating Shift Left
|
|
//
|
|
// TODO: Implement the remaining intrinsics from this group.
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vqshlud_n_s64(
|
|
int64_t test_vqshlud_n_s64(int64_t a) {
|
|
// CIR: [[CONST:%.*]] = cir.const #cir.int<63> : !s64i
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.sqshlu" {{%.*}}, [[CONST]] : (!s64i, !s64i) -> !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]])
|
|
// LLVM: [[VQSHLU_N:%.*]] = call i64 @llvm.aarch64.neon.sqshlu.i64(i64 [[A]], i64 63)
|
|
// LLVM: ret i64 [[VQSHLU_N]]
|
|
return (int64_t)vqshlud_n_s64(a, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqshld_n_u64(
|
|
uint64_t test_vqshld_n_u64(uint64_t a) {
|
|
// CIR: [[CONST:%.*]] = cir.const #cir.int<63> : !s64i
|
|
// CIR: [[CAST:%.*]] = cir.cast bitcast [[CONST]] : !s64i -> !u64i
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.uqshl" {{%.*}}, [[CAST]] : (!u64i, !u64i) -> !u64i
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]])
|
|
// LLVM: [[VQSHLD_N_U64:%.*]] = call i64 @llvm.aarch64.neon.uqshl.i64(i64 [[A]], i64 63)
|
|
// LLVM: ret i64 [[VQSHLD_N_U64]]
|
|
return vqshld_n_u64(a, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vqshld_n_s64(
|
|
int64_t test_vqshld_n_s64(int64_t a) {
|
|
// CIR: [[CONST:%.*]] = cir.const #cir.int<63> : !s64i
|
|
// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.sqshl" {{%.*}}, [[CONST]] : (!s64i, !s64i) -> !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]])
|
|
// LLVM: [[VQSHL_N:%.*]] = call i64 @llvm.aarch64.neon.sqshl.i64(i64 [[A]], i64 63)
|
|
// LLVM: ret i64 [[VQSHL_N]]
|
|
return (int64_t)vqshld_n_s64(a, 63);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.7.1 Negate
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#negate
|
|
//
|
|
// TODO: Implement the remaining intrinsics in this group
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vnegd_s64
|
|
// CIR-LABEL: @vnegd_s64
|
|
int64_t test_vnegd_s64(int64_t a) {
|
|
// CIR: cir.minus {{.*}} : !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[VNEGD_I:%.*]] = sub i64 0, [[A]]
|
|
// LLVM-NEXT: ret i64 [[VNEGD_I]]
|
|
return (int64_t)vnegd_s64(a);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.2.2 Bitwise equal to zero
|
|
//===------------------------------------------------------===//
|
|
// LLVM-LABEL: @test_vceqz_s8(
|
|
// CIR-LABEL: @vceqz_s8(
|
|
uint8x8_t test_vceqz_s8(int8x8_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<8 x !s8i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// LLVM: [[TMP0:%.*]] = icmp eq <8 x i8> [[A]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <8 x i1> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: ret <8 x i8> [[VCEQZ_I]]
|
|
return vceqz_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_s16(
|
|
// CIR-LABEL: @vceqz_s16(
|
|
uint16x4_t test_vceqz_s16(int16x4_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<4 x !s16i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <4 x i16> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <4 x i1> [[TMP2]] to <4 x i16>
|
|
// LLVM-NEXT: ret <4 x i16> [[VCEQZ_I]]
|
|
return vceqz_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_s32(
|
|
// CIR-LABEL: @vceqz_s32(
|
|
uint32x2_t test_vceqz_s32(int32x2_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<2 x !s32i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
// LLVM-NEXT: ret <2 x i32> [[VCEQZ_I]]
|
|
return vceqz_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_s64(
|
|
// CIR-LABEL: @vceqz_s64(
|
|
uint64x1_t test_vceqz_s64(int64x1_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<1 x !s64i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<1 x !s64i>, !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <1 x i64> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <1 x i1> [[TMP2]] to <1 x i64>
|
|
// LLVM-NEXT: ret <1 x i64> [[VCEQZ_I]]
|
|
return vceqz_s64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_p64(
|
|
// CIR-LABEL: @vceqz_p64(
|
|
uint64x1_t test_vceqz_p64(poly64x1_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<1 x !s64i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<1 x !s64i>, !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <1 x i64> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <1 x i1> [[TMP2]] to <1 x i64>
|
|
// LLVM-NEXT: ret <1 x i64> [[VCEQZ_I]]
|
|
return vceqz_p64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_s8(
|
|
// CIR-LABEL: @vceqzq_s8(
|
|
uint8x16_t test_vceqzq_s8(int8x16_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<16 x !s8i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = icmp eq <16 x i8> [[A]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <16 x i1> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: ret <16 x i8> [[VCEQZ_I]]
|
|
return vceqzq_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_s16(
|
|
// CIR-LABEL: @vceqzq_s16(
|
|
uint16x8_t test_vceqzq_s16(int16x8_t a) {
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <8 x i16> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <8 x i1> [[TMP2]] to <8 x i16>
|
|
// LLVM-NEXT: ret <8 x i16> [[VCEQZ_I]]
|
|
return vceqzq_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_s32(
|
|
// CIR-LABEL: @vceqzq_s32(
|
|
uint32x4_t test_vceqzq_s32(int32x4_t a) {
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <4 x i1> [[TMP2]] to <4 x i32>
|
|
// LLVM-NEXT: ret <4 x i32> [[VCEQZ_I]]
|
|
return vceqzq_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_s64(
|
|
// CIR-LABEL: @vceqzq_s64(
|
|
uint64x2_t test_vceqzq_s64(int64x2_t a) {
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i64>
|
|
// LLVM-NEXT: ret <2 x i64> [[VCEQZ_I]]
|
|
return vceqzq_s64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_u8(
|
|
// CIR-LABEL: @vceqz_u8(
|
|
uint8x8_t test_vceqz_u8(uint8x8_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<8 x !u8i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = icmp eq <8 x i8> [[A]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <8 x i1> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: ret <8 x i8> [[VCEQZ_I]]
|
|
return vceqz_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_u16(
|
|
// CIR-LABEL: @vceqz_u16(
|
|
uint16x4_t test_vceqz_u16(uint16x4_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<4 x !u16i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<4 x !u16i>, !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <4 x i16> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <4 x i1> [[TMP2]] to <4 x i16>
|
|
// LLVM-NEXT: ret <4 x i16> [[VCEQZ_I]]
|
|
return vceqz_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_u32(
|
|
// CIR-LABEL: @vceqz_u32(
|
|
uint32x2_t test_vceqz_u32(uint32x2_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<2 x !u32i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<2 x !u32i>, !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
// LLVM-NEXT: ret <2 x i32> [[VCEQZ_I]]
|
|
return vceqz_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_u64(
|
|
// CIR-LABEL: @vceqz_u64(
|
|
uint64x1_t test_vceqz_u64(uint64x1_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !u64i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<1 x !u64i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<1 x !u64i>, !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <1 x i64> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <1 x i1> [[TMP2]] to <1 x i64>
|
|
// LLVM-NEXT: ret <1 x i64> [[VCEQZ_I]]
|
|
return vceqz_u64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_u8(
|
|
// CIR-LABEL: @vceqzq_u8(
|
|
uint8x16_t test_vceqzq_u8(uint8x16_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<16 x !u8i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = icmp eq <16 x i8> [[A]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <16 x i1> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: ret <16 x i8> [[VCEQZ_I]]
|
|
return vceqzq_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_u16(
|
|
// CIR-LABEL: @vceqzq_u16(
|
|
uint16x8_t test_vceqzq_u16(uint16x8_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<8 x !u16i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<8 x !u16i>, !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <8 x i16> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <8 x i1> [[TMP2]] to <8 x i16>
|
|
// LLVM-NEXT: ret <8 x i16> [[VCEQZ_I]]
|
|
return vceqzq_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_u32(
|
|
// CIR-LABEL: @vceqzq_u32(
|
|
uint32x4_t test_vceqzq_u32(uint32x4_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<4 x !u32i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<4 x !u32i>, !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <4 x i1> [[TMP2]] to <4 x i32>
|
|
// LLVM-NEXT: ret <4 x i32> [[VCEQZ_I]]
|
|
return vceqzq_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_u64(
|
|
// CIR-LABEL: @vceqzq_u64(
|
|
uint64x2_t test_vceqzq_u64(uint64x2_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !u64i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<2 x !u64i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<2 x !u64i>, !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i64>
|
|
// LLVM-NEXT: ret <2 x i64> [[VCEQZ_I]]
|
|
return vceqzq_u64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_f32(
|
|
// CIR-LABEL: @vceqz_f32(
|
|
uint32x2_t test_vceqz_f32(float32x2_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !cir.float>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<2 x !cir.float>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<2 x !cir.float>, !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = fcmp oeq <2 x float> [[TMP2]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP3]] to <2 x i32>
|
|
// LLVM-NEXT: ret <2 x i32> [[VCEQZ_I]]
|
|
return vceqz_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_f64(
|
|
// CIR-LABEL: @vceqz_f64(
|
|
uint64x1_t test_vceqz_f64(float64x1_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !cir.double>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<1 x !cir.double>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<1 x !cir.double>, !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64
|
|
// LLVM-NEXT: [[__P0_ADDR_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[__P0_ADDR_I_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x double>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = fcmp oeq <1 x double> [[TMP2]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <1 x i1> [[TMP3]] to <1 x i64>
|
|
// LLVM-NEXT: ret <1 x i64> [[VCEQZ_I]]
|
|
return vceqz_f64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_f32(
|
|
// CIR-LABEL: @vceqzq_f32(
|
|
uint32x4_t test_vceqzq_f32(float32x4_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !cir.float>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = fcmp oeq <4 x float> [[TMP2]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <4 x i1> [[TMP3]] to <4 x i32>
|
|
// LLVM-NEXT: ret <4 x i32> [[VCEQZ_I]]
|
|
return vceqzq_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_f64(
|
|
// CIR-LABEL: @vceqzq_f64(
|
|
uint64x2_t test_vceqzq_f64(float64x2_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !cir.double>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<2 x !cir.double>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<2 x !cir.double>, !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = fcmp oeq <2 x double> [[TMP2]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP3]] to <2 x i64>
|
|
// LLVM-NEXT: ret <2 x i64> [[VCEQZ_I]]
|
|
return vceqzq_f64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqz_p8(
|
|
// CIR-LABEL: @vceqz_p8(
|
|
uint8x8_t test_vceqz_p8(poly8x8_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<8 x !s8i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = icmp eq <8 x i8> [[A]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <8 x i1> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: ret <8 x i8> [[VCEQZ_I]]
|
|
return vceqz_p8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_p8(
|
|
// CIR-LABEL: @vceqzq_p8(
|
|
uint8x16_t test_vceqzq_p8(poly8x16_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<16 x !s8i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = icmp eq <16 x i8> [[A]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <16 x i1> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: ret <16 x i8> [[VCEQZ_I]]
|
|
return vceqzq_p8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzq_p64(
|
|
// CIR-LABEL: @vceqzq_p64(
|
|
uint64x2_t test_vceqzq_p64(poly64x2_t a) {
|
|
// CIR: cir.cast bitcast {{%.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.zero : !cir.vector<2 x !s64i>
|
|
// CIR: cir.vec.cmp(eq, {{%.*}}, [[C_0]]) : !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i64>
|
|
// LLVM-NEXT: ret <2 x i64> [[VCEQZ_I]]
|
|
return vceqzq_p64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzd_s64
|
|
// CIR-LABEL: @vceqzd_s64
|
|
uint64_t test_vceqzd_s64(int64_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.int<0>
|
|
// CIR: [[CMP:%.*]] = cir.cmp eq %{{.*}}, [[C_0]] : !s64i
|
|
// CIR: [[RES:%.*]] = cir.cast bool_to_int [[CMP]] : !cir.bool -> !cir.int<s, 1>
|
|
// CIR: cir.cast integral [[RES]] : !cir.int<s, 1> -> !u64i
|
|
|
|
// LLVM-SAME: i64{{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = icmp eq i64 [[A]], 0
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext i1 [[TMP0]] to i64
|
|
// LLVM-NEXT: ret i64 [[VCEQZ_I]]
|
|
return (uint64_t)vceqzd_s64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzd_u64(
|
|
// CIR-LABEL: @vceqzd_u64(
|
|
int64_t test_vceqzd_u64(int64_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.int<0>
|
|
// CIR: [[CMP:%.*]] = cir.cmp eq %{{.*}}, [[C_0]] : !u64i
|
|
// CIR: [[RES:%.*]] = cir.cast bool_to_int [[CMP]] : !cir.bool -> !cir.int<s, 1>
|
|
// CIR: cir.cast integral [[RES]] : !cir.int<s, 1> -> !u64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = icmp eq i64 [[A]], 0
|
|
// LLVM-NEXT: [[VCEQZD_I:%.*]] = sext i1 [[TMP0]] to i64
|
|
// LLVM-NEXT: ret i64 [[VCEQZD_I]]
|
|
return (int64_t)vceqzd_u64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzs_f32(
|
|
// CIR-LABEL: @vceqzs_f32(
|
|
uint32_t test_vceqzs_f32(float32_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.fp<0.000000e+00>
|
|
// CIR: [[CMP:%.*]] = cir.cmp eq %{{.*}}, [[C_0]] : !cir.float
|
|
// CIR: [[RES:%.*]] = cir.cast bool_to_int [[CMP]] : !cir.bool -> !cir.int<s, 1>
|
|
// CIR: cir.cast integral [[RES]] : !cir.int<s, 1> -> !u32i
|
|
|
|
// LLVM-SAME: float {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = fcmp oeq float [[A]], 0.000000e+00
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext i1 [[TMP0]] to i32
|
|
// LLVM-NEXT: ret i32 [[VCEQZ_I]]
|
|
return (uint32_t)vceqzs_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vceqzd_f64(
|
|
// CIR-LABEL: @vceqzd_f64(
|
|
uint64_t test_vceqzd_f64(float64_t a) {
|
|
// CIR: [[C_0:%.*]] = cir.const #cir.fp<0.000000e+00>
|
|
// CIR: [[CMP:%.*]] = cir.cmp eq %{{.*}}, [[C_0]] : !cir.double
|
|
// CIR: [[RES:%.*]] = cir.cast bool_to_int [[CMP]] : !cir.bool -> !cir.int<s, 1>
|
|
// CIR: cir.cast integral [[RES]] : !cir.int<s, 1> -> !u64i
|
|
|
|
|
|
// LLVM-SAME: double {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = fcmp oeq double [[A]], 0.000000e+00
|
|
// LLVM-NEXT: [[VCEQZ_I:%.*]] = sext i1 [[TMP0]] to i64
|
|
// LLVM-NEXT: ret i64 [[VCEQZ_I]]
|
|
return (uint64_t)vceqzd_f64(a);
|
|
}
|
|
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.6.1. Absolute difference
|
|
//===------------------------------------------------------===//
|
|
// LLVM-LABEL: @test_vabd_s8(
|
|
// CIR-LABEL: @vabd_s8(
|
|
int8x8_t test_vabd_s8(int8x8_t v1, int8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sabd" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM-NEXT: ret <8 x i8> [[VABD_I]]
|
|
return vabd_s8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_s16(
|
|
// CIR-LABEL: @vabd_s16(
|
|
int16x4_t test_vabd_s16(int16x4_t v1, int16x4_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> [[VABD_I]], <4 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <4 x i16> [[VABD2_I]]
|
|
return vabd_s16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_s32(
|
|
// CIR-LABEL: @vabd_s32(
|
|
int32x2_t test_vabd_s32(int32x2_t v1, int32x2_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> [[VABD_I]], <2 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <2 x i32> [[VABD2_I]]
|
|
return vabd_s32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_u8(
|
|
// CIR-LABEL: @vabd_u8(
|
|
uint8x8_t test_vabd_u8(uint8x8_t v1, uint8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uabd" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM-NEXT: ret <8 x i8> [[VABD_I]]
|
|
return vabd_u8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_u16(
|
|
// CIR-LABEL: @vabd_u16(
|
|
uint16x4_t test_vabd_u16(uint16x4_t v1, uint16x4_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> [[VABD_I]], <4 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <4 x i16> [[VABD2_I]]
|
|
return vabd_u16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_u32(
|
|
// CIR-LABEL: @vabd_u32(
|
|
uint32x2_t test_vabd_u32(uint32x2_t v1, uint32x2_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> [[VABD_I]], <2 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <2 x i32> [[VABD2_I]]
|
|
return vabd_u32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_f32(
|
|
// CIR-LABEL: @vabd_f32(
|
|
float32x2_t test_vabd_f32(float32x2_t v1, float32x2_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !cir.float>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !cir.float>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[V1:%.*]], <2 x float> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float> [[VABD_I]], <2 x float> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <2 x float> [[VABD2_I]]
|
|
return vabd_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabd_f64(
|
|
// CIR-LABEL: @vabd_f64(
|
|
float64x1_t test_vabd_f64(float64x1_t v1, float64x1_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !cir.double>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !cir.double>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[V1:%.*]], <1 x double> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[V1]] to i64
|
|
// LLVM-NEXT: [[__P0_ADDR_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x double> [[V2]] to i64
|
|
// LLVM-NEXT: [[__P1_ADDR_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP1]], i32 0
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <1 x i64> [[__P0_ADDR_I_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <1 x i64> [[__P1_ADDR_I_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <1 x double>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <1 x double>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <1 x double> @llvm.aarch64.neon.fabd.v1f64(<1 x double> [[VABD_I]], <1 x double> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <1 x double> [[VABD2_I]]
|
|
return vabd_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_s8(
|
|
// CIR-LABEL: @vabdq_s8(
|
|
int8x16_t test_vabdq_s8(int8x16_t v1, int8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sabd" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM-NEXT: ret <16 x i8> [[VABD_I]]
|
|
return vabdq_s8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_s16(
|
|
// CIR-LABEL: @vabdq_s16(
|
|
int16x8_t test_vabdq_s16(int16x8_t v1, int16x8_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> [[VABD_I]], <8 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VABD2_I]]
|
|
return vabdq_s16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_s32(
|
|
// CIR-LABEL: @vabdq_s32(
|
|
int32x4_t test_vabdq_s32(int32x4_t v1, int32x4_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> [[VABD_I]], <4 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VABD2_I]]
|
|
return vabdq_s32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_u8(
|
|
// CIR-LABEL: @vabdq_u8(
|
|
uint8x16_t test_vabdq_u8(uint8x16_t v1, uint8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uabd" %{{.*}}, %{{.*}} : (!cir.vector<16 x !u8i>, !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM-NEXT: ret <16 x i8> [[VABD_I]]
|
|
return vabdq_u8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_u16(
|
|
// CIR-LABEL: @vabdq_u16(
|
|
uint16x8_t test_vabdq_u16(uint16x8_t v1, uint16x8_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> [[VABD_I]], <8 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VABD2_I]]
|
|
return vabdq_u16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_u32(
|
|
// CIR-LABEL: @vabdq_u32(
|
|
uint32x4_t test_vabdq_u32(uint32x4_t v1, uint32x4_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> [[VABD_I]], <4 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VABD2_I]]
|
|
return vabdq_u32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_f32(
|
|
// CIR-LABEL: @vabdq_f32(
|
|
float32x4_t test_vabdq_f32(float32x4_t v1, float32x4_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !cir.float>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !cir.float>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[V1:%.*]], <4 x float> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float> [[VABD_I]], <4 x float> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <4 x float> [[VABD2_I]]
|
|
return vabdq_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdq_f64(
|
|
// CIR-LABEL: @vabdq_f64(
|
|
float64x2_t test_vabdq_f64(float64x2_t v1, float64x2_t v2) {
|
|
// CIR: [[V1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !cir.double>
|
|
// CIR: [[V2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !cir.double>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fabd" [[V1]], [[V2]]
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[V1:%.*]], <2 x double> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double> [[VABD_I]], <2 x double> [[VABD1_I]])
|
|
// LLVM-NEXT: ret <2 x double> [[VABD2_I]]
|
|
return vabdq_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabds_f32(
|
|
// CIR-LABEL: @vabds_f32(
|
|
float32_t test_vabds_f32(float32_t a, float32_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.sisd.fabd"
|
|
|
|
// LLVM-SAME: float {{.*}} [[A:%.*]], float noundef [[B:%.*]])
|
|
// LLVM: [[VABDS_F32_I:%.*]] = call float @llvm.aarch64.sisd.fabd.f32(float [[A]], float [[B]])
|
|
// LLVM-NEXT: ret float [[VABDS_F32_I]]
|
|
return vabds_f32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabdd_f64(
|
|
// CIR-LABEL: @vabdd_f64(
|
|
float64_t test_vabdd_f64(float64_t a, float64_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.sisd.fabd"
|
|
|
|
// LLVM-SAME: double {{.*}} [[A:%.*]], double noundef [[B:%.*]])
|
|
// LLVM: [[VABDD_F64_I:%.*]] = call double @llvm.aarch64.sisd.fabd.f64(double [[A]], double [[B]])
|
|
// LLVM-NEXT: ret double [[VABDD_F64_I]]
|
|
return vabdd_f64(a, b);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.6.3. Absolute difference and accumulate
|
|
//
|
|
// The following builtins expand to a call to vabd_{} builtins,
|
|
// which is reflected in the CIR output.
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vaba_u8(
|
|
// CIR-LABEL: @vaba_u8(
|
|
uint8x8_t test_vaba_u8(uint8x8_t v1, uint8x8_t v2, uint8x8_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabd_u8
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]], <8 x i8> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> [[V2]], <8 x i8> [[V3]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <8 x i8> [[V1]], [[VABD_I]]
|
|
// LLVM-NEXT: ret <8 x i8> [[ADD_I]]
|
|
return vaba_u8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaba_u16(
|
|
// CIR-LABEL: @vaba_u16(
|
|
uint16x4_t test_vaba_u16(uint16x4_t v1, uint16x4_t v2, uint16x4_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabd_u16
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]], <4 x i16> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[V3]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> [[VABD_I]], <4 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <4 x i16> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <4 x i16> [[ADD_I]]
|
|
return vaba_u16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaba_u32(
|
|
// CIR-LABEL: @vaba_u32(
|
|
uint32x2_t test_vaba_u32(uint32x2_t v1, uint32x2_t v2, uint32x2_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabd_u32
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> {{.*}} [[V2:%.*]], <2 x i32> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V3]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> [[VABD_I]], <2 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <2 x i32> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <2 x i32> [[ADD_I]]
|
|
return vaba_u32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaba_s8(
|
|
// CIR-LABEL: @vaba_s8(
|
|
int8x8_t test_vaba_s8(int8x8_t v1, int8x8_t v2, int8x8_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabd_s8
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]], <8 x i8> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> [[V2]], <8 x i8> [[V3]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <8 x i8> [[V1]], [[VABD_I]]
|
|
// LLVM-NEXT: ret <8 x i8> [[ADD_I]]
|
|
return vaba_s8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaba_s16(
|
|
// CIR-LABEL: @vaba_s16(
|
|
int16x4_t test_vaba_s16(int16x4_t v1, int16x4_t v2, int16x4_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabd_s16
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]], <4 x i16> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[V3]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> [[VABD_I]], <4 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <4 x i16> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <4 x i16> [[ADD_I]]
|
|
return vaba_s16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaba_s32(
|
|
// CIR-LABEL: @vaba_s32(
|
|
int32x2_t test_vaba_s32(int32x2_t v1, int32x2_t v2, int32x2_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabd_s32
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> {{.*}} [[V2:%.*]], <2 x i32> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V3]] to <8 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> [[VABD_I]], <2 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <2 x i32> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <2 x i32> [[ADD_I]]
|
|
return vaba_s32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabaq_s8(
|
|
// CIR-LABEL: @vabaq_s8(
|
|
int8x16_t test_vabaq_s8(int8x16_t v1, int8x16_t v2, int8x16_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabdq_s8
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]], <16 x i8> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> [[V2]], <16 x i8> [[V3]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <16 x i8> [[V1]], [[VABD_I]]
|
|
// LLVM-NEXT: ret <16 x i8> [[ADD_I]]
|
|
return vabaq_s8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabaq_s16(
|
|
// CIR-LABEL: @vabaq_s16(
|
|
int16x8_t test_vabaq_s16(int16x8_t v1, int16x8_t v2, int16x8_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabdq_s16
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]], <8 x i16> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[V3]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> [[VABD_I]], <8 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <8 x i16> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <8 x i16> [[ADD_I]]
|
|
return vabaq_s16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabaq_s32(
|
|
// CIR-LABEL: @vabaq_s32(
|
|
int32x4_t test_vabaq_s32(int32x4_t v1, int32x4_t v2, int32x4_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabdq_s32
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> {{.*}} [[V2:%.*]], <4 x i32> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[V3]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> [[VABD_I]], <4 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <4 x i32> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <4 x i32> [[ADD_I]]
|
|
return vabaq_s32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabaq_u8(
|
|
// CIR-LABEL: @vabaq_u8(
|
|
uint8x16_t test_vabaq_u8(uint8x16_t v1, uint8x16_t v2, uint8x16_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabdq_u8
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]], <16 x i8> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[VABD_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> [[V2]], <16 x i8> [[V3]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <16 x i8> [[V1]], [[VABD_I]]
|
|
// LLVM-NEXT: ret <16 x i8> [[ADD_I]]
|
|
return vabaq_u8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabaq_u16(
|
|
// CIR-LABEL: @vabaq_u16(
|
|
uint16x8_t test_vabaq_u16(uint16x8_t v1, uint16x8_t v2, uint16x8_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabdq_u16
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]], <8 x i16> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[V3]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> [[VABD_I]], <8 x i16> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <8 x i16> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <8 x i16> [[ADD_I]]
|
|
return vabaq_u16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vabaq_u32(
|
|
// CIR-LABEL: @vabaq_u32(
|
|
uint32x4_t test_vabaq_u32(uint32x4_t v1, uint32x4_t v2, uint32x4_t v3) {
|
|
// CIR: [[ABD:%.*]] = cir.call @vabdq_u32
|
|
// CIR: [[RES:%.*]] = cir.add {{.*}}, [[ABD]]
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> {{.*}} [[V2:%.*]], <4 x i32> {{.*}} [[V3:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[V3]] to <16 x i8>
|
|
// LLVM-NEXT: [[VABD_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VABD2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> [[VABD_I]], <4 x i32> [[VABD1_I]])
|
|
// LLVM-NEXT: [[ADD_I:%.*]] = add <4 x i32> [[V1]], [[VABD2_I]]
|
|
// LLVM-NEXT: ret <4 x i32> [[ADD_I]]
|
|
return vabaq_u32(v1, v2, v3);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.1.7. Maximum
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#maximum
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vmax_s8
|
|
// CIR-LABEL: @vmax_s8(
|
|
int8x8_t test_vmax_s8(int8x8_t v1, int8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smax" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMAX_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.smax.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM: ret <8 x i8> [[VMAX_V_I]]
|
|
return vmax_s8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_s16
|
|
// CIR-LABEL: @vmax_s16(
|
|
int16x4_t test_vmax_s16(int16x4_t v1, int16x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smax" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMAX_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VMAX_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VMAX_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.smax.v4i16(<4 x i16> [[VMAX_V_I]], <4 x i16> [[VMAX_V1_I]])
|
|
// LLVM: ret <4 x i16> [[VMAX_V2_I]]
|
|
return vmax_s16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_s32
|
|
// CIR-LABEL: @vmax_s32(
|
|
int32x2_t test_vmax_s32(int32x2_t v1, int32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smax" %{{.*}}, %{{.*}} : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMAX_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VMAX_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VMAX_V2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.smax.v2i32(<2 x i32> [[VMAX_V_I]], <2 x i32> [[VMAX_V1_I]])
|
|
// LLVM: ret <2 x i32> [[VMAX_V2_I]]
|
|
return vmax_s32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_u8
|
|
// CIR-LABEL: @vmax_u8(
|
|
uint8x8_t test_vmax_u8(uint8x8_t v1, uint8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umax" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMAX_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.umax.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM: ret <8 x i8> [[VMAX_V_I]]
|
|
return vmax_u8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_u16
|
|
// CIR-LABEL: @vmax_u16(
|
|
uint16x4_t test_vmax_u16(uint16x4_t v1, uint16x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umax" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u16i>, !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMAX_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VMAX_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VMAX_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.umax.v4i16(<4 x i16> [[VMAX_V_I]], <4 x i16> [[VMAX_V1_I]])
|
|
// LLVM: ret <4 x i16> [[VMAX_V2_I]]
|
|
return vmax_u16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_u32
|
|
// CIR-LABEL: @vmax_u32(
|
|
uint32x2_t test_vmax_u32(uint32x2_t v1, uint32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umax" %{{.*}}, %{{.*}} : (!cir.vector<2 x !u32i>, !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMAX_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VMAX_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VMAX_V2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.umax.v2i32(<2 x i32> [[VMAX_V_I]], <2 x i32> [[VMAX_V1_I]])
|
|
// LLVM: ret <2 x i32> [[VMAX_V2_I]]
|
|
return vmax_u32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_s8
|
|
// CIR-LABEL: @vmaxq_s8(
|
|
int8x16_t test_vmaxq_s8(int8x16_t v1, int8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smax" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.smax.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM: ret <16 x i8> [[VMAXQ_V_I]]
|
|
return vmaxq_s8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_s16
|
|
// CIR-LABEL: @vmaxq_s16(
|
|
int16x8_t test_vmaxq_s16(int16x8_t v1, int16x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smax" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VMAXQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VMAXQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.smax.v8i16(<8 x i16> [[VMAXQ_V_I]], <8 x i16> [[VMAXQ_V1_I]])
|
|
// LLVM: ret <8 x i16> [[VMAXQ_V2_I]]
|
|
return vmaxq_s16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_s32
|
|
// CIR-LABEL: @vmaxq_s32(
|
|
int32x4_t test_vmaxq_s32(int32x4_t v1, int32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smax" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VMAXQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VMAXQ_V2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.smax.v4i32(<4 x i32> [[VMAXQ_V_I]], <4 x i32> [[VMAXQ_V1_I]])
|
|
// LLVM: ret <4 x i32> [[VMAXQ_V2_I]]
|
|
return vmaxq_s32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_u8
|
|
// CIR-LABEL: @vmaxq_u8(
|
|
uint8x16_t test_vmaxq_u8(uint8x16_t v1, uint8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umax" %{{.*}}, %{{.*}} : (!cir.vector<16 x !u8i>, !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.umax.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM: ret <16 x i8> [[VMAXQ_V_I]]
|
|
return vmaxq_u8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_u16
|
|
// CIR-LABEL: @vmaxq_u16(
|
|
uint16x8_t test_vmaxq_u16(uint16x8_t v1, uint16x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umax" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u16i>, !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VMAXQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VMAXQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.umax.v8i16(<8 x i16> [[VMAXQ_V_I]], <8 x i16> [[VMAXQ_V1_I]])
|
|
// LLVM: ret <8 x i16> [[VMAXQ_V2_I]]
|
|
return vmaxq_u16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_u32
|
|
// CIR-LABEL: @vmaxq_u32
|
|
uint32x4_t test_vmaxq_u32(uint32x4_t v1, uint32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umax" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u32i>, !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VMAXQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VMAXQ_V2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.umax.v4i32(<4 x i32> [[VMAXQ_V_I]], <4 x i32> [[VMAXQ_V1_I]])
|
|
// LLVM: ret <4 x i32> [[VMAXQ_V2_I]]
|
|
return vmaxq_u32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_f32
|
|
// CIR-LABEL: @vmax_f32
|
|
float32x2_t test_vmax_f32(float32x2_t v1, float32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmax" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[V1:%.*]], <2 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM: [[VMAX_V_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM: [[VMAX_V1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM: [[VMAX_V2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmax.v2f32(<2 x float> [[VMAX_V_I]], <2 x float> [[VMAX_V1_I]])
|
|
// LLVM: ret <2 x float> [[VMAX_V2_I]]
|
|
return vmax_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmax_f64
|
|
// CIR-LABEL: @vmax_f64
|
|
float64x1_t test_vmax_f64(float64x1_t v1, float64x1_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmax" %{{.*}}, %{{.*}} : (!cir.vector<1 x !cir.double>, !cir.vector<1 x !cir.double>) -> !cir.vector<1 x !cir.double>
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[V1:%.*]], <1 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMAX_V_I:%.*]] = call <1 x double> @llvm.aarch64.neon.fmax.v1f64(<1 x double> {{.*}}, <1 x double> {{.*}})
|
|
// LLVM: ret <1 x double> [[VMAX_V_I]]
|
|
return vmax_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_f32
|
|
// CIR-LABEL: @vmaxq_f32
|
|
float32x4_t test_vmaxq_f32(float32x4_t v1, float32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmax" %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[V1:%.*]], <4 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM: [[VMAXQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM: [[VMAXQ_V2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmax.v4f32(<4 x float> [[VMAXQ_V_I]], <4 x float> [[VMAXQ_V1_I]])
|
|
// LLVM: ret <4 x float> [[VMAXQ_V2_I]]
|
|
return vmaxq_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxq_f64
|
|
// CIR-LABEL: @vmaxq_f64
|
|
float64x2_t test_vmaxq_f64(float64x2_t v1, float64x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmax" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[V1:%.*]], <2 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMAXQ_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM: [[VMAXQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM: [[VMAXQ_V2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fmax.v2f64(<2 x double> [[VMAXQ_V_I]], <2 x double> [[VMAXQ_V1_I]])
|
|
// LLVM: ret <2 x double> [[VMAXQ_V2_I]]
|
|
return vmaxq_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxnm_f32
|
|
// CIR-LABEL: @vmaxnm_f32
|
|
float32x2_t test_vmaxnm_f32(float32x2_t v1, float32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmaxnm" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[V1:%.*]], <2 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM: [[VMAXNM_V_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM: [[VMAXNM_V1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM: [[VMAXNM_V2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmaxnm.v2f32(<2 x float> [[VMAXNM_V_I]], <2 x float> [[VMAXNM_V1_I]])
|
|
// LLVM: ret <2 x float> [[VMAXNM_V2_I]]
|
|
return vmaxnm_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxnm_f64
|
|
// CIR-LABEL: @vmaxnm_f64
|
|
float64x1_t test_vmaxnm_f64(float64x1_t v1, float64x1_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmaxnm" %{{.*}}, %{{.*}} : (!cir.vector<1 x !cir.double>, !cir.vector<1 x !cir.double>) -> !cir.vector<1 x !cir.double>
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[V1:%.*]], <1 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMAXNM_V_I:%.*]] = call <1 x double> @llvm.aarch64.neon.fmaxnm.v1f64(<1 x double> {{.*}}, <1 x double> {{.*}})
|
|
// LLVM: ret <1 x double> [[VMAXNM_V_I]]
|
|
return vmaxnm_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxnmq_f32
|
|
// CIR-LABEL: @vmaxnmq_f32
|
|
float32x4_t test_vmaxnmq_f32(float32x4_t v1, float32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmaxnm" %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[V1:%.*]], <4 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMAXNMQ_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM: [[VMAXNMQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM: [[VMAXNMQ_V2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmaxnm.v4f32(<4 x float> [[VMAXNMQ_V_I]], <4 x float> [[VMAXNMQ_V1_I]])
|
|
// LLVM: ret <4 x float> [[VMAXNMQ_V2_I]]
|
|
return vmaxnmq_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmaxnmq_f64
|
|
// CIR-LABEL: @vmaxnmq_f64
|
|
float64x2_t test_vmaxnmq_f64(float64x2_t v1, float64x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmaxnm" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[V1:%.*]], <2 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMAXNMQ_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM: [[VMAXNMQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM: [[VMAXNMQ_V2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fmaxnm.v2f64(<2 x double> [[VMAXNMQ_V_I]], <2 x double> [[VMAXNMQ_V1_I]])
|
|
// LLVM: ret <2 x double> [[VMAXNMQ_V2_I]]
|
|
return vmaxnmq_f64(v1, v2);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.1.11. Square root
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#square-root
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vsqrt_f32(
|
|
// CIR-LABEL: @vsqrt_f32(
|
|
float32x2_t test_vsqrt_f32(float32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "sqrt" %{{.*}} : (!cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// LLVM-NEXT: [[VSQRT_I:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> [[TMP2]])
|
|
// LLVM-NEXT: ret <2 x float> [[VSQRT_I]]
|
|
return vsqrt_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vsqrtq_f32(
|
|
// CIR-LABEL: @vsqrtq_f32(
|
|
float32x4_t test_vsqrtq_f32(float32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "sqrt" %{{.*}} : (!cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// LLVM-NEXT: [[VSQRT_I:%.*]] = call <4 x float> @llvm.sqrt.v4f32(<4 x float> [[TMP2]])
|
|
// LLVM-NEXT: ret <4 x float> [[VSQRT_I]]
|
|
return vsqrtq_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vsqrt_f64(
|
|
// CIR-LABEL: @vsqrt_f64(
|
|
float64x1_t test_vsqrt_f64(float64x1_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "sqrt" %{{.*}} : (!cir.vector<1 x !cir.double>) -> !cir.vector<1 x !cir.double>
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64
|
|
// LLVM-NEXT: [[__P0_ADDR_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[__P0_ADDR_I_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x double>
|
|
// LLVM-NEXT: [[VSQRT_I:%.*]] = call <1 x double> @llvm.sqrt.v1f64(<1 x double> [[TMP2]])
|
|
// LLVM-NEXT: ret <1 x double> [[VSQRT_I]]
|
|
return vsqrt_f64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vsqrtq_f64(
|
|
// CIR-LABEL: @vsqrtq_f64(
|
|
float64x2_t test_vsqrtq_f64(float64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "sqrt" %{{.*}} : (!cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
|
|
// LLVM-NEXT: [[VSQRT_I:%.*]] = call <2 x double> @llvm.sqrt.v2f64(<2 x double> [[TMP2]])
|
|
// LLVM-NEXT: ret <2 x double> [[VSQRT_I]]
|
|
return vsqrtq_f64(a);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.2.8. Widening Multiplication
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vmull_s8(
|
|
// CIR-LABEL: @vmull_s8(
|
|
int16x8_t test_vmull_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smull" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VMULL_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VMULL_I]]
|
|
return vmull_s8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_s16(
|
|
// CIR-LABEL: @vmull_s16(
|
|
int32x4_t test_vmull_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smull" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> [[VMULL_I]], <4 x i16> [[VMULL1_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VMULL2_I]]
|
|
return vmull_s16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_s32(
|
|
// CIR-LABEL: @vmull_s32(
|
|
int64x2_t test_vmull_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smull" %{{.*}}, %{{.*}} : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL2_I:%.*]] = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> [[VMULL_I]], <2 x i32> [[VMULL1_I]])
|
|
// LLVM-NEXT: ret <2 x i64> [[VMULL2_I]]
|
|
return vmull_s32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_u8(
|
|
// CIR-LABEL: @vmull_u8(
|
|
uint16x8_t test_vmull_u8(uint8x8_t a, uint8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umull" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VMULL_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.umull.v8i16(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VMULL_I]]
|
|
return vmull_u8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_u16(
|
|
// CIR-LABEL: @vmull_u16(
|
|
uint32x4_t test_vmull_u16(uint16x4_t a, uint16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umull" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u16i>, !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> [[VMULL_I]], <4 x i16> [[VMULL1_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VMULL2_I]]
|
|
return vmull_u16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_u32(
|
|
// CIR-LABEL: @vmull_u32(
|
|
uint64x2_t test_vmull_u32(uint32x2_t a, uint32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umull" %{{.*}}, %{{.*}} : (!cir.vector<2 x !u32i>, !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u64i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL2_I:%.*]] = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> [[VMULL_I]], <2 x i32> [[VMULL1_I]])
|
|
// LLVM-NEXT: ret <2 x i64> [[VMULL2_I]]
|
|
return vmull_u32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_s8(
|
|
// CIR-LABEL: @vmull_high_s8(
|
|
int16x8_t test_vmull_high_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_s8
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_s8
|
|
// CIR: cir.call @vmull_s8([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
// LLVM-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> [[B]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.smull.v8i16(<8 x i8> [[SHUFFLE_I5_I]], <8 x i8> [[SHUFFLE_I_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VMULL_I_I]]
|
|
return vmull_high_s8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_s16(
|
|
// CIR-LABEL: @vmull_high_s16(
|
|
int32x4_t test_vmull_high_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_s16
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_s16
|
|
// CIR: {{%.*}} = cir.call @vmull_s16([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5_I:%.*]] = shufflevector <8 x i16> [[A]], <8 x i16> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B]], <8 x i16> [[B]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I5_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[SHUFFLE_I_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL1_I_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL2_I_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.smull.v4i32(<4 x i16> [[VMULL_I_I]], <4 x i16> [[VMULL1_I_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VMULL2_I_I]]
|
|
return vmull_high_s16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_s32(
|
|
// CIR-LABEL: @vmull_high_s32(
|
|
int64x2_t test_vmull_high_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_s32
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_s32
|
|
// CIR: {{%.*}} = cir.call @vmull_s32([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5_I:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[A]], <2 x i32> <i32 2, i32 3>
|
|
// LLVM-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> [[B]], <2 x i32> <i32 2, i32 3>
|
|
// LLVM-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I5_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL1_I_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL2_I_I:%.*]] = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> [[VMULL_I_I]], <2 x i32> [[VMULL1_I_I]])
|
|
// LLVM-NEXT: ret <2 x i64> [[VMULL2_I_I]]
|
|
return vmull_high_s32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_u8(
|
|
// CIR-LABEL: @vmull_high_u8(
|
|
uint16x8_t test_vmull_high_u8(uint8x16_t a, uint8x16_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_u8
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_u8
|
|
// CIR: {{%.*}} = cir.call @vmull_u8([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5_I:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
// LLVM-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> [[B]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.umull.v8i16(<8 x i8> [[SHUFFLE_I5_I]], <8 x i8> [[SHUFFLE_I_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VMULL_I_I]]
|
|
return vmull_high_u8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_u16(
|
|
// CIR-LABEL: @vmull_high_u16(
|
|
uint32x4_t test_vmull_high_u16(uint16x8_t a, uint16x8_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_u16
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_u16
|
|
// CIR: {{%.*}} = cir.call @vmull_u16([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5_I:%.*]] = shufflevector <8 x i16> [[A]], <8 x i16> [[A]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <8 x i16> [[B]], <8 x i16> [[B]], <4 x i32> <i32 4, i32 5, i32 6, i32 7>
|
|
// LLVM-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[SHUFFLE_I5_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[SHUFFLE_I_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL1_I_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VMULL2_I_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.umull.v4i32(<4 x i16> [[VMULL_I_I]], <4 x i16> [[VMULL1_I_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VMULL2_I_I]]
|
|
return vmull_high_u16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_u32(
|
|
// CIR-LABEL: @vmull_high_u32(
|
|
uint64x2_t test_vmull_high_u32(uint32x4_t a, uint32x4_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_u32
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_u32
|
|
// CIR: {{%.*}} = cir.call @vmull_u32([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5_I:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[A]], <2 x i32> <i32 2, i32 3>
|
|
// LLVM-NEXT: [[SHUFFLE_I_I:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> [[B]], <2 x i32> <i32 2, i32 3>
|
|
// LLVM-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[SHUFFLE_I5_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHUFFLE_I_I]] to <8 x i8>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL1_I_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VMULL2_I_I:%.*]] = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> [[VMULL_I_I]], <2 x i32> [[VMULL1_I_I]])
|
|
// LLVM-NEXT: ret <2 x i64> [[VMULL2_I_I]]
|
|
return vmull_high_u32(a, b);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.3.1. Polynomial Multiply
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vmul_p8(
|
|
// CIR-LABEL: @vmul_p8(
|
|
poly8x8_t test_vmul_p8(poly8x8_t v1, poly8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.pmul" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[VMUL_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.pmul.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM-NEXT: ret <8 x i8> [[VMUL_V_I]]
|
|
return vmul_p8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmulq_p8(
|
|
// CIR-LABEL: @vmulq_p8(
|
|
poly8x16_t test_vmulq_p8(poly8x16_t v1, poly8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.pmul" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]])
|
|
// LLVM: [[VMULQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmul.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM-NEXT: ret <16 x i8> [[VMULQ_V_I]]
|
|
return vmulq_p8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_p8(
|
|
// CIR-LABEL: @vmull_p8(
|
|
poly16x8_t test_vmull_p8(poly8x8_t a, poly8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.pmull" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VMULL_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VMULL_I]]
|
|
return vmull_p8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmull_high_p8(
|
|
// CIR-LABEL: @vmull_high_p8(
|
|
poly16x8_t test_vmull_high_p8(poly8x16_t a, poly8x16_t b) {
|
|
// CIR: [[HIGH_A:%.*]] = cir.call @vget_high_p8
|
|
// CIR: [[HIGH_B:%.*]] = cir.call @vget_high_p8
|
|
// CIR: {{%.*}} = cir.call @vmull_p8([[HIGH_A]], [[HIGH_B]])
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[SHUFFLE_I5:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> [[A]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
// LLVM-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> [[B]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
|
// LLVM-NEXT: [[VMULL_I_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> [[SHUFFLE_I5]], <8 x i8> [[SHUFFLE_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VMULL_I_I]]
|
|
return vmull_high_p8(a, b);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.8 Minimum
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#minimum
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vmin_s8
|
|
// CIR-LABEL: @vmin_s8(
|
|
int8x8_t test_vmin_s8(int8x8_t v1, int8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smin" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMIN_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.smin.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM: ret <8 x i8> [[VMIN_V_I]]
|
|
return vmin_s8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_s16
|
|
// CIR-LABEL: @vmin_s16(
|
|
int16x4_t test_vmin_s16(int16x4_t v1, int16x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smin" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMIN_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VMIN_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VMIN_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.smin.v4i16(<4 x i16> [[VMIN_V_I]], <4 x i16> [[VMIN_V1_I]])
|
|
// LLVM: ret <4 x i16> [[VMIN_V2_I]]
|
|
return vmin_s16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_s32
|
|
// CIR-LABEL: @vmin_s32(
|
|
int32x2_t test_vmin_s32(int32x2_t v1, int32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smin" %{{.*}}, %{{.*}} : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMIN_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VMIN_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VMIN_V2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.smin.v2i32(<2 x i32> [[VMIN_V_I]], <2 x i32> [[VMIN_V1_I]])
|
|
// LLVM: ret <2 x i32> [[VMIN_V2_I]]
|
|
return vmin_s32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_u8
|
|
// CIR-LABEL: @vmin_u8(
|
|
uint8x8_t test_vmin_u8(uint8x8_t v1, uint8x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umin" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMIN_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.umin.v8i8(<8 x i8> [[V1]], <8 x i8> [[V2]])
|
|
// LLVM: ret <8 x i8> [[VMIN_V_I]]
|
|
return vmin_u8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_u16
|
|
// CIR-LABEL: @vmin_u16(
|
|
uint16x4_t test_vmin_u16(uint16x4_t v1, uint16x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umin" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u16i>, !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMIN_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VMIN_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VMIN_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.umin.v4i16(<4 x i16> [[VMIN_V_I]], <4 x i16> [[VMIN_V1_I]])
|
|
// LLVM: ret <4 x i16> [[VMIN_V2_I]]
|
|
return vmin_u16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_u32
|
|
// CIR-LABEL: @vmin_u32(
|
|
uint32x2_t test_vmin_u32(uint32x2_t v1, uint32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umin" %{{.*}}, %{{.*}} : (!cir.vector<2 x !u32i>, !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM: [[VMIN_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VMIN_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VMIN_V2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.umin.v2i32(<2 x i32> [[VMIN_V_I]], <2 x i32> [[VMIN_V1_I]])
|
|
// LLVM: ret <2 x i32> [[VMIN_V2_I]]
|
|
return vmin_u32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_s8
|
|
// CIR-LABEL: @vminq_s8(
|
|
int8x16_t test_vminq_s8(int8x16_t v1, int8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smin" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMINQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.smin.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM: ret <16 x i8> [[VMINQ_V_I]]
|
|
return vminq_s8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_s16
|
|
// CIR-LABEL: @vminq_s16(
|
|
int16x8_t test_vminq_s16(int16x8_t v1, int16x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smin" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMINQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VMINQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VMINQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.smin.v8i16(<8 x i16> [[VMINQ_V_I]], <8 x i16> [[VMINQ_V1_I]])
|
|
// LLVM: ret <8 x i16> [[VMINQ_V2_I]]
|
|
return vminq_s16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_s32
|
|
// CIR-LABEL: @vminq_s32(
|
|
int32x4_t test_vminq_s32(int32x4_t v1, int32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.smin" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMINQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VMINQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VMINQ_V2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.smin.v4i32(<4 x i32> [[VMINQ_V_I]], <4 x i32> [[VMINQ_V1_I]])
|
|
// LLVM: ret <4 x i32> [[VMINQ_V2_I]]
|
|
return vminq_s32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_u8
|
|
// CIR-LABEL: @vminq_u8(
|
|
uint8x16_t test_vminq_u8(uint8x16_t v1, uint8x16_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umin" %{{.*}}, %{{.*}} : (!cir.vector<16 x !u8i>, !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMINQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.umin.v16i8(<16 x i8> [[V1]], <16 x i8> [[V2]])
|
|
// LLVM: ret <16 x i8> [[VMINQ_V_I]]
|
|
return vminq_u8(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_u16
|
|
// CIR-LABEL: @vminq_u16(
|
|
uint16x8_t test_vminq_u16(uint16x8_t v1, uint16x8_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umin" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u16i>, !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMINQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VMINQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VMINQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.umin.v8i16(<8 x i16> [[VMINQ_V_I]], <8 x i16> [[VMINQ_V1_I]])
|
|
// LLVM: ret <8 x i16> [[VMINQ_V2_I]]
|
|
|
|
return vminq_u16(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_u32
|
|
// CIR-LABEL: @vminq_u32
|
|
uint32x4_t test_vminq_u32(uint32x4_t v1, uint32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.umin" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u32i>, !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM: [[VMINQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VMINQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VMINQ_V2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.umin.v4i32(<4 x i32> [[VMINQ_V_I]], <4 x i32> [[VMINQ_V1_I]])
|
|
// LLVM: ret <4 x i32> [[VMINQ_V2_I]]
|
|
return vminq_u32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_f32
|
|
// CIR-LABEL: @vmin_f32
|
|
float32x2_t test_vmin_f32(float32x2_t v1, float32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmin" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[V1:%.*]], <2 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM: [[VMIN_V_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM: [[VMIN_V1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM: [[VMIN_V2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fmin.v2f32(<2 x float> [[VMIN_V_I]], <2 x float> [[VMIN_V1_I]])
|
|
// LLVM: ret <2 x float> [[VMIN_V2_I]]
|
|
return vmin_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vmin_f64
|
|
// CIR-LABEL: @vmin_f64
|
|
float64x1_t test_vmin_f64(float64x1_t v1, float64x1_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmin" %{{.*}}, %{{.*}} : (!cir.vector<1 x !cir.double>, !cir.vector<1 x !cir.double>) -> !cir.vector<1 x !cir.double>
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[V1:%.*]], <1 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[VMIN_V_I:%.*]] = bitcast <8 x i8> {{.*}} to <1 x double>
|
|
// LLVM: [[VMIN_V1_I:%.*]] = bitcast <8 x i8> {{.*}} to <1 x double>
|
|
// LLVM: [[VMIN_V2_I:%.*]] = call <1 x double> @llvm.aarch64.neon.fmin.v1f64(<1 x double> [[VMIN_V_I]], <1 x double> [[VMIN_V1_I]])
|
|
// LLVM: ret <1 x double> [[VMIN_V2_I]]
|
|
return vmin_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_f32
|
|
// CIR-LABEL: @vminq_f32
|
|
float32x4_t test_vminq_f32(float32x4_t v1, float32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmin" %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[V1:%.*]], <4 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMINQ_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM: [[VMINQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM: [[VMINQ_V2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fmin.v4f32(<4 x float> [[VMINQ_V_I]], <4 x float> [[VMINQ_V1_I]])
|
|
// LLVM: ret <4 x float> [[VMINQ_V2_I]]
|
|
return vminq_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminq_f64
|
|
// CIR-LABEL: @vminq_f64
|
|
float64x2_t test_vminq_f64(float64x2_t v1, float64x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmin" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[V1:%.*]], <2 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMINQ_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM: [[VMINQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM: [[VMINQ_V2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fmin.v2f64(<2 x double> [[VMINQ_V_I]], <2 x double> [[VMINQ_V1_I]])
|
|
// LLVM: ret <2 x double> [[VMINQ_V2_I]]
|
|
return vminq_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminnm_f32
|
|
// CIR-LABEL: @vminnm_f32
|
|
float32x2_t test_vminnm_f32(float32x2_t v1, float32x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnm" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[V1:%.*]], <2 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[V1]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM: [[VMINNM_V_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM: [[VMINNM_V1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM: [[VMINNM_V2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fminnm.v2f32(<2 x float> [[VMINNM_V_I]], <2 x float> [[VMINNM_V1_I]])
|
|
// LLVM: ret <2 x float> [[VMINNM_V2_I]]
|
|
return vminnm_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminnm_f64
|
|
// CIR-LABEL: @vminnm_f64
|
|
float64x1_t test_vminnm_f64(float64x1_t v1, float64x1_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnm" %{{.*}}, %{{.*}} : (!cir.vector<1 x !cir.double>, !cir.vector<1 x !cir.double>) -> !cir.vector<1 x !cir.double>
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[V1:%.*]], <1 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[V1]] to i64
|
|
// LLVM: [[__P0_ADDR_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x double> [[V2]] to i64
|
|
// LLVM: [[__P1_ADDR_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP1]], i32 0
|
|
// LLVM: [[TMP2:%.*]] = bitcast <1 x i64> [[__P0_ADDR_I_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <1 x i64> [[__P1_ADDR_I_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM: [[VMINNM_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <1 x double>
|
|
// LLVM: [[VMINNM1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <1 x double>
|
|
// LLVM: [[VMINNM2_I:%.*]] = call <1 x double> @llvm.aarch64.neon.fminnm.v1f64(<1 x double> [[VMINNM_I]], <1 x double> [[VMINNM1_I]])
|
|
// LLVM: ret <1 x double> [[VMINNM2_I]]
|
|
return vminnm_f64(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminnmq_f32
|
|
// CIR-LABEL: @vminnmq_f32
|
|
float32x4_t test_vminnmq_f32(float32x4_t v1, float32x4_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnm" %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[V1:%.*]], <4 x float> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[V1]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMINNM_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM: [[VMINNM_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM: [[VMINNM_V2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fminnm.v4f32(<4 x float> [[VMINNM_V_I]], <4 x float> [[VMINNM_V1_I]])
|
|
// LLVM: ret <4 x float> [[VMINNM_V2_I]]
|
|
return vminnmq_f32(v1, v2);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminnmq_f64
|
|
// CIR-LABEL: @vminnmq_f64
|
|
float64x2_t test_vminnmq_f64(float64x2_t v1, float64x2_t v2) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnm" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[V1:%.*]], <2 x double> noundef [[V2:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[V1]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VMINNM_V_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM: [[VMINNM_V1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM: [[VMINNM_V2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fminnm.v2f64(<2 x double> [[VMINNM_V_I]], <2 x double> [[VMINNM_V1_I]])
|
|
// LLVM: ret <2 x double> [[VMINNM_V2_I]]
|
|
return vminnmq_f64(v1, v2);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.8.6 Pairwise minimum
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#pairwise-minimum
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vpmin_s8(
|
|
// CIR-LABEL: @vpmin_s8(
|
|
int8x8_t test_vpmin_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sminp" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VPMIN_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.sminp.v8i8(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM-NEXT: ret <8 x i8> [[VPMIN_I]]
|
|
return vpmin_s8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmin_s16(
|
|
// CIR-LABEL: @vpmin_s16(
|
|
int16x4_t test_vpmin_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sminp" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.sminp.v4i16(<4 x i16> [[VPMIN_I]], <4 x i16> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <4 x i16> [[VPMIN2_I]]
|
|
return vpmin_s16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmin_s32(
|
|
// CIR-LABEL: @vpmin_s32(
|
|
int32x2_t test_vpmin_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sminp" %{{.*}}, %{{.*}} : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.sminp.v2i32(<2 x i32> [[VPMIN_I]], <2 x i32> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <2 x i32> [[VPMIN2_I]]
|
|
return vpmin_s32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmin_u8(
|
|
// CIR-LABEL: @vpmin_u8(
|
|
uint8x8_t test_vpmin_u8(uint8x8_t a, uint8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uminp" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VPMIN_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.uminp.v8i8(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM-NEXT: ret <8 x i8> [[VPMIN_I]]
|
|
return vpmin_u8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmin_u16(
|
|
// CIR-LABEL: @vpmin_u16(
|
|
uint16x4_t test_vpmin_u16(uint16x4_t a, uint16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uminp" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u16i>, !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.uminp.v4i16(<4 x i16> [[VPMIN_I]], <4 x i16> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <4 x i16> [[VPMIN2_I]]
|
|
return vpmin_u16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmin_u32(
|
|
// CIR-LABEL: @vpmin_u32(
|
|
uint32x2_t test_vpmin_u32(uint32x2_t a, uint32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uminp" %{{.*}}, %{{.*}} : (!cir.vector<2 x !u32i>, !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.uminp.v2i32(<2 x i32> [[VPMIN_I]], <2 x i32> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <2 x i32> [[VPMIN2_I]]
|
|
return vpmin_u32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmin_f32(
|
|
// CIR-LABEL: @vpmin_f32(
|
|
float32x2_t test_vpmin_f32(float32x2_t a, float32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminp" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[B]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fminp.v2f32(<2 x float> [[VPMIN_I]], <2 x float> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <2 x float> [[VPMIN2_I]]
|
|
return vpmin_f32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_s8(
|
|
// CIR-LABEL: @vpminq_s8(
|
|
int8x16_t test_vpminq_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sminp" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VPMIN_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.sminp.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
|
|
// LLVM-NEXT: ret <16 x i8> [[VPMIN_I]]
|
|
return vpminq_s8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_s16(
|
|
// CIR-LABEL: @vpminq_s16(
|
|
int16x8_t test_vpminq_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sminp" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.sminp.v8i16(<8 x i16> [[VPMIN_I]], <8 x i16> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VPMIN2_I]]
|
|
return vpminq_s16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_s32(
|
|
// CIR-LABEL: @vpminq_s32(
|
|
int32x4_t test_vpminq_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sminp" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.sminp.v4i32(<4 x i32> [[VPMIN_I]], <4 x i32> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VPMIN2_I]]
|
|
return vpminq_s32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_u8(
|
|
// CIR-LABEL: @vpminq_u8(
|
|
uint8x16_t test_vpminq_u8(uint8x16_t a, uint8x16_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uminp" %{{.*}}, %{{.*}} : (!cir.vector<16 x !u8i>, !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VPMIN_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.uminp.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
|
|
// LLVM-NEXT: ret <16 x i8> [[VPMIN_I]]
|
|
return vpminq_u8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_u16(
|
|
// CIR-LABEL: @vpminq_u16(
|
|
uint16x8_t test_vpminq_u16(uint16x8_t a, uint16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uminp" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u16i>, !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.uminp.v8i16(<8 x i16> [[VPMIN_I]], <8 x i16> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <8 x i16> [[VPMIN2_I]]
|
|
return vpminq_u16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_u32(
|
|
// CIR-LABEL: @vpminq_u32(
|
|
uint32x4_t test_vpminq_u32(uint32x4_t a, uint32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uminp" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u32i>, !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.uminp.v4i32(<4 x i32> [[VPMIN_I]], <4 x i32> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <4 x i32> [[VPMIN2_I]]
|
|
return vpminq_u32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_f32(
|
|
// CIR-LABEL: @vpminq_f32(
|
|
float32x4_t test_vpminq_f32(float32x4_t a, float32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminp" %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[B]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fminp.v4f32(<4 x float> [[VPMIN_I]], <4 x float> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <4 x float> [[VPMIN2_I]]
|
|
return vpminq_f32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminq_f64(
|
|
// CIR-LABEL: @vpminq_f64(
|
|
float64x2_t test_vpminq_f64(float64x2_t a, float64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminp" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMIN_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM-NEXT: [[VPMIN1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM-NEXT: [[VPMIN2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fminp.v2f64(<2 x double> [[VPMIN_I]], <2 x double> [[VPMIN1_I]])
|
|
// LLVM-NEXT: ret <2 x double> [[VPMIN2_I]]
|
|
return vpminq_f64(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpmins_f32(
|
|
// CIR-LABEL: @vpmins_f32(
|
|
float32_t test_vpmins_f32(float32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminv" %{{.*}} : (!cir.vector<2 x !cir.float>) -> !cir.float
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VPMINS_F32_I:%.*]] = call float @llvm.aarch64.neon.fminv.f32.v2f32(<2 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VPMINS_F32_I]]
|
|
return vpmins_f32(a);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.8.7 Pairwise minimum (IEEE754)
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#pairwise-minimum-ieee754
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vpminnm_f32(
|
|
// CIR-LABEL: @vpminnm_f32(
|
|
float32x2_t test_vpminnm_f32(float32x2_t a, float32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmp" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.float>, !cir.vector<2 x !cir.float>) -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]], <2 x float> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x float> [[B]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM-NEXT: [[VPMINNM_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x float>
|
|
// LLVM-NEXT: [[VPMINNM1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x float>
|
|
// LLVM-NEXT: [[VPMINNM2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fminnmp.v2f32(<2 x float> [[VPMINNM_I]], <2 x float> [[VPMINNM1_I]])
|
|
// LLVM-NEXT: ret <2 x float> [[VPMINNM2_I]]
|
|
return vpminnm_f32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminnmq_f32(
|
|
// CIR-LABEL: @vpminnmq_f32(
|
|
float32x4_t test_vpminnmq_f32(float32x4_t a, float32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmp" %{{.*}}, %{{.*}} : (!cir.vector<4 x !cir.float>, !cir.vector<4 x !cir.float>) -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]], <4 x float> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[B]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMINNM_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x float>
|
|
// LLVM-NEXT: [[VPMINNM1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x float>
|
|
// LLVM-NEXT: [[VPMINNM2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fminnmp.v4f32(<4 x float> [[VPMINNM_I]], <4 x float> [[VPMINNM1_I]])
|
|
// LLVM-NEXT: ret <4 x float> [[VPMINNM2_I]]
|
|
return vpminnmq_f32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminnmq_f64(
|
|
// CIR-LABEL: @vpminnmq_f64(
|
|
float64x2_t test_vpminnmq_f64(float64x2_t a, float64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmp" %{{.*}}, %{{.*}} : (!cir.vector<2 x !cir.double>, !cir.vector<2 x !cir.double>) -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]], <2 x double> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM-NEXT: [[VPMINNM_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x double>
|
|
// LLVM-NEXT: [[VPMINNM1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x double>
|
|
// LLVM-NEXT: [[VPMINNM2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.fminnmp.v2f64(<2 x double> [[VPMINNM_I]], <2 x double> [[VPMINNM1_I]])
|
|
// LLVM-NEXT: ret <2 x double> [[VPMINNM2_I]]
|
|
return vpminnmq_f64(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminqd_f64(
|
|
// CIR-LABEL: @vpminqd_f64(
|
|
float64_t test_vpminqd_f64(float64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminv" %{{.*}} : (!cir.vector<2 x !cir.double>) -> !cir.double
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VPMINQD_F64_I:%.*]] = call double @llvm.aarch64.neon.fminv.f64.v2f64(<2 x double> [[A]])
|
|
// LLVM-NEXT: ret double [[VPMINQD_F64_I]]
|
|
return vpminqd_f64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminnms_f32(
|
|
// CIR-LABEL: @vpminnms_f32(
|
|
float32_t test_vpminnms_f32(float32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmv" %{{.*}} : (!cir.vector<2 x !cir.float>) -> !cir.float
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VPMINNMS_F32_I:%.*]] = call float @llvm.aarch64.neon.fminnmv.f32.v2f32(<2 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VPMINNMS_F32_I]]
|
|
return vpminnms_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vpminnmqd_f64(
|
|
// CIR-LABEL: @vpminnmqd_f64(
|
|
float64_t test_vpminnmqd_f64(float64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmv" %{{.*}} : (!cir.vector<2 x !cir.double>) -> !cir.double
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VPMINNMQD_F64_I:%.*]] = call double @llvm.aarch64.neon.fminnmv.f64.v2f64(<2 x double> [[A]])
|
|
// LLVM-NEXT: ret double [[VPMINNMQD_F64_I]]
|
|
return vpminnmqd_f64(a);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.1.1. Vector Shift Left
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-shift-left
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: test_vshld_n_s64
|
|
int64_t test_vshld_n_s64(int64_t a) {
|
|
// CIR: cir.shift(left, {{.*}})
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[SHL_N:%.*]] = shl i64 [[A]], 1
|
|
// LLVM: ret i64 [[SHL_N]]
|
|
return (int64_t)vshld_n_s64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshld_n_u64
|
|
int64_t test_vshld_n_u64(int64_t a) {
|
|
// CIR: cir.shift(left, {{.*}})
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[SHL_N:%.*]] = shl i64 [[A]], 1
|
|
// LLVM: ret i64 [[SHL_N]]
|
|
return (int64_t)vshld_n_u64(a, 1);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshld_s64
|
|
// CIR-LABEL: vshld_s64
|
|
int64_t test_vshld_s64(int64_t a,int64_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!s64i, !s64i) -> !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]], i64 {{.*}} [[B:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// LLVM: [[VSHLD_S64_I:%.*]] = call i64 @llvm.aarch64.neon.sshl.i64(i64 [[A]], i64 [[B]])
|
|
// LLVM: ret i64 [[VSHLD_S64_I]]
|
|
return (int64_t)vshld_s64(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshld_u64
|
|
// CIR-LABEL: vshld_u64
|
|
int64_t test_vshld_u64(int64_t a,int64_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!u64i, !s64i) -> !u64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]], i64 {{.*}} [[B:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// LLVM: [[VSHLD_S64_I:%.*]] = call i64 @llvm.aarch64.neon.ushl.i64(i64 [[A]], i64 [[B]])
|
|
// LLVM: ret i64 [[VSHLD_S64_I]]
|
|
return (int64_t)vshld_u64(a, b);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_s8
|
|
int8x16_t test_vshlq_n_s8(int8x16_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<16 x !s8i>, %{{.*}} : !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHL_N:%.*]] = shl <16 x i8> [[A]], splat (i8 3)
|
|
// LLVM: ret <16 x i8> [[VSHL_N]]
|
|
//
|
|
return vshlq_n_s8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_s16
|
|
int16x8_t test_vshlq_n_s16(int16x8_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<8 x !s16i>, %{{.*}} : !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <8 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <8 x i16> [[VSHL_N]]
|
|
return vshlq_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_s32
|
|
int32x4_t test_vshlq_n_s32(int32x4_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<4 x !s32i>, %{{.*}} : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <4 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <4 x i32> [[VSHL_N]]
|
|
return vshlq_n_s32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_s64
|
|
int64x2_t test_vshlq_n_s64(int64x2_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<2 x !s64i>, %{{.*}} : !cir.vector<2 x !s64i>) -> !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <2 x i64> [[TMP1]], splat (i64 3)
|
|
// LLVM: ret <2 x i64> [[VSHL_N]]
|
|
return vshlq_n_s64(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_u8
|
|
uint8x16_t test_vshlq_n_u8(uint8x16_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<16 x !u8i>, %{{.*}} : !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHL_N:%.*]] = shl <16 x i8> [[A]], splat (i8 3)
|
|
// LLVM: ret <16 x i8> [[VSHL_N]]
|
|
return vshlq_n_u8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_u16
|
|
uint16x8_t test_vshlq_n_u16(uint16x8_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<8 x !u16i>, %{{.*}} : !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <8 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <8 x i16> [[VSHL_N]]
|
|
return vshlq_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_u32
|
|
uint32x4_t test_vshlq_n_u32(uint32x4_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<4 x !u32i>, %{{.*}} : !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <4 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <4 x i32> [[VSHL_N]]
|
|
return vshlq_n_u32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshlq_n_u64
|
|
uint64x2_t test_vshlq_n_u64(uint64x2_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<2 x !u64i>, %{{.*}} : !cir.vector<2 x !u64i>) -> !cir.vector<2 x !u64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <2 x i64> [[TMP1]], splat (i64 3)
|
|
// LLVM: ret <2 x i64> [[VSHL_N]]
|
|
return vshlq_n_u64(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_s8
|
|
int8x8_t test_vshl_n_s8(int8x8_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<8 x !s8i>, %{{.*}} : !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHL_N:%.*]] = shl <8 x i8> [[A]], splat (i8 3)
|
|
// LLVM: ret <8 x i8> [[VSHL_N]]
|
|
return vshl_n_s8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_s16
|
|
int16x4_t test_vshl_n_s16(int16x4_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<4 x !s16i>, %{{.*}} : !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <4 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <4 x i16> [[VSHL_N]]
|
|
return vshl_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_s32
|
|
int32x2_t test_vshl_n_s32(int32x2_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<2 x !s32i>, %{{.*}} : !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <2 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <2 x i32> [[VSHL_N]]
|
|
return vshl_n_s32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_s64
|
|
int64x1_t test_vshl_n_s64(int64x1_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<1 x !s64i>, %{{.*}} : !cir.vector<1 x !s64i>) -> !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <1 x i64> [[TMP1]], splat (i64 1)
|
|
// LLVM: ret <1 x i64> [[VSHL_N]]
|
|
return vshl_n_s64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_u8
|
|
uint8x8_t test_vshl_n_u8(uint8x8_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<8 x !u8i>, %{{.*}} : !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHL_N:%.*]] = shl <8 x i8> [[A]], splat (i8 3)
|
|
// LLVM: ret <8 x i8> [[VSHL_N]]
|
|
return vshl_n_u8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_u16
|
|
uint16x4_t test_vshl_n_u16(uint16x4_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<4 x !u16i>, %{{.*}} : !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <4 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <4 x i16> [[VSHL_N]]
|
|
return vshl_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_u32
|
|
uint32x2_t test_vshl_n_u32(uint32x2_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<2 x !u32i>, %{{.*}} : !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <2 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <2 x i32> [[VSHL_N]]
|
|
return vshl_n_u32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: test_vshl_n_u64
|
|
uint64x1_t test_vshl_n_u64(uint64x1_t a) {
|
|
// CIR: [[RES:%.*]] = cir.shift(left, %{{.*}} : !cir.vector<1 x !u64i>, %{{.*}} : !cir.vector<1 x !u64i>) -> !cir.vector<1 x !u64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSHL_N:%.*]] = shl <1 x i64> [[TMP1]], splat (i64 1)
|
|
// LLVM: ret <1 x i64> [[VSHL_N]]
|
|
return vshl_n_u64(a, 1);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_s8
|
|
// CIR-LABEL: vshl_s8
|
|
int8x8_t test_vshl_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[VSHL_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.sshl.v8i8(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM: ret <8 x i8> [[VSHL_V_I]]
|
|
return vshl_s8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_s16
|
|
// CIR-LABEL: vshl_s16
|
|
int16x4_t test_vshl_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[VSHL_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSHL_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VSHL_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.sshl.v4i16(<4 x i16> [[VSHL_V_I]], <4 x i16> [[VSHL_V1_I]])
|
|
// LLVM: [[VSHL_V3_I:%.*]] = bitcast <4 x i16> [[VSHL_V2_I]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i8> [[VSHL_V3_I]] to <4 x i16>
|
|
// LLVM: ret <4 x i16> [[TMP2]]
|
|
return vshl_s16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_s32
|
|
// CIR-LABEL: vshl_s32
|
|
int32x2_t test_vshl_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM: [[VSHL_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSHL_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VSHL_V2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.sshl.v2i32(<2 x i32> [[VSHL_V_I]], <2 x i32> [[VSHL_V1_I]])
|
|
// LLVM: [[VSHL_V3_I:%.*]] = bitcast <2 x i32> [[VSHL_V2_I]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i8> [[VSHL_V3_I]] to <2 x i32>
|
|
// LLVM: ret <2 x i32> [[TMP2]]
|
|
return vshl_s32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_s64
|
|
// CIR-LABEL: vshl_s64
|
|
int64x1_t test_vshl_s64(int64x1_t a, int64x1_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<1 x !s64i>, !cir.vector<1 x !s64i>) -> !cir.vector<1 x !s64i>
|
|
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[VSHL_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSHL_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VSHL_V2_I:%.*]] = call <1 x i64> @llvm.aarch64.neon.sshl.v1i64(<1 x i64> [[VSHL_V_I]], <1 x i64> [[VSHL_V1_I]])
|
|
// LLVM: [[VSHL_V3_I:%.*]] = bitcast <1 x i64> [[VSHL_V2_I]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i8> [[VSHL_V3_I]] to i64
|
|
// LLVM: [[REF_TMP_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP2]], i32 0
|
|
// LLVM-NEXT: ret <1 x i64> [[REF_TMP_I_SROA_0_0_VEC_INSERT]]
|
|
return vshl_s64(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_u8
|
|
// CIR-LABEL: vshl_u8
|
|
uint8x8_t test_vshl_u8(uint8x8_t a, int8x8_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[VSHL_V_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.ushl.v8i8(<8 x i8> [[A]], <8 x i8> [[B]])
|
|
// LLVM: ret <8 x i8> [[VSHL_V_I]]
|
|
return vshl_u8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_u16
|
|
// CIR-LABEL: vshl_u16
|
|
uint16x4_t test_vshl_u16(uint16x4_t a, int16x4_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u16i>, !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[VSHL_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSHL_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VSHL_V2_I:%.*]] = call <4 x i16> @llvm.aarch64.neon.ushl.v4i16(<4 x i16> [[VSHL_V_I]], <4 x i16> [[VSHL_V1_I]])
|
|
// LLVM: [[VSHL_V3_I:%.*]] = bitcast <4 x i16> [[VSHL_V2_I]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i8> [[VSHL_V3_I]] to <4 x i16>
|
|
// LLVM: ret <4 x i16> [[TMP2]]
|
|
return vshl_u16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_u32
|
|
// CIR-LABEL: vshl_u32
|
|
uint32x2_t test_vshl_u32(uint32x2_t a, int32x2_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<2 x !u32i>, !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM: [[VSHL_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSHL_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VSHL_V2_I:%.*]] = call <2 x i32> @llvm.aarch64.neon.ushl.v2i32(<2 x i32> [[VSHL_V_I]], <2 x i32> [[VSHL_V1_I]])
|
|
// LLVM: [[VSHL_V3_I:%.*]] = bitcast <2 x i32> [[VSHL_V2_I]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i8> [[VSHL_V3_I]] to <2 x i32>
|
|
// LLVM: ret <2 x i32> [[TMP2]]
|
|
return vshl_u32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshl_u64
|
|
// CIR-LABEL: vshl_u64
|
|
uint64x1_t test_vshl_u64(uint64x1_t a, int64x1_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<1 x !u64i>, !cir.vector<1 x !u64i>) -> !cir.vector<1 x !u64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]], <1 x i64> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[VSHL_V_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSHL_V1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VSHL_V2_I:%.*]] = call <1 x i64> @llvm.aarch64.neon.ushl.v1i64(<1 x i64> [[VSHL_V_I]], <1 x i64> [[VSHL_V1_I]])
|
|
// LLVM: [[VSHL_V3_I:%.*]] = bitcast <1 x i64> [[VSHL_V2_I]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i8> [[VSHL_V3_I]] to i64
|
|
// LLVM: [[REF_TMP_I_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP2]], i32 0
|
|
// LLVM: ret <1 x i64> [[REF_TMP_I_SROA_0_0_VEC_INSERT]]
|
|
return vshl_u64(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_s8
|
|
// CIR-LABEL: vshlq_s8
|
|
int8x16_t test_vshlq_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.sshl.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
|
|
// LLVM: ret <16 x i8> [[VSHLQ_V_I]]
|
|
return vshlq_s8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_s16
|
|
// CIR-LABEL: vshlq_s16
|
|
int16x8_t test_vshlq_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
|
|
|
|
// LLVM: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSHLQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VSHLQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.sshl.v8i16(<8 x i16> [[VSHLQ_V_I]], <8 x i16> [[VSHLQ_V1_I]])
|
|
// LLVM: [[VSHLQ_V3_I:%.*]] = bitcast <8 x i16> [[VSHLQ_V2_I]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <16 x i8> [[VSHLQ_V3_I]] to <8 x i16>
|
|
// LLVM: ret <8 x i16> [[TMP2]]
|
|
//
|
|
return vshlq_s16(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_s32
|
|
// CIR-LABEL: vshlq_s32
|
|
int32x4_t test_vshlq_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSHLQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VSHLQ_V2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.sshl.v4i32(<4 x i32> [[VSHLQ_V_I]], <4 x i32> [[VSHLQ_V1_I]])
|
|
// LLVM: [[VSHLQ_V3_I:%.*]] = bitcast <4 x i32> [[VSHLQ_V2_I]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <16 x i8> [[VSHLQ_V3_I]] to <4 x i32>
|
|
// LLVM: ret <4 x i32> [[TMP2]]
|
|
return vshlq_s32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_s64
|
|
// CIR-LABEL: vshlq_s64
|
|
int64x2_t test_vshlq_s64(int64x2_t a, int64x2_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.sshl" %{{.*}}, %{{.*}} : (!cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>) -> !cir.vector<2 x !s64i>
|
|
|
|
// LLVM: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSHLQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VSHLQ_V2_I:%.*]] = call <2 x i64> @llvm.aarch64.neon.sshl.v2i64(<2 x i64> [[VSHLQ_V_I]], <2 x i64> [[VSHLQ_V1_I]])
|
|
// LLVM: [[VSHLQ_V3_I:%.*]] = bitcast <2 x i64> [[VSHLQ_V2_I]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <16 x i8> [[VSHLQ_V3_I]] to <2 x i64>
|
|
// LLVM: ret <2 x i64> [[TMP2]]
|
|
return vshlq_s64(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_u8
|
|
// CIR-LABEL: vshlq_u8
|
|
uint8x16_t test_vshlq_u8(uint8x16_t a, int8x16_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<16 x !u8i>, !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.ushl.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
|
|
// LLVM: ret <16 x i8> [[VSHLQ_V_I]]
|
|
return vshlq_u8(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_u16
|
|
// CIR-LABEL: vshlq_u16
|
|
uint16x8_t test_vshlq_u16(uint16x8_t a, int16x8_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u16i>, !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
|
|
|
|
|
|
// LLVM: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSHLQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VSHLQ_V2_I:%.*]] = call <8 x i16> @llvm.aarch64.neon.ushl.v8i16(<8 x i16> [[VSHLQ_V_I]], <8 x i16> [[VSHLQ_V1_I]])
|
|
// LLVM: [[VSHLQ_V3_I:%.*]] = bitcast <8 x i16> [[VSHLQ_V2_I]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <16 x i8> [[VSHLQ_V3_I]] to <8 x i16>
|
|
// LLVM: ret <8 x i16> [[TMP2]]
|
|
//
|
|
return vshlq_u16(a, b);
|
|
}
|
|
|
|
|
|
// LLVM-LABEL: test_vshlq_u32
|
|
// CIR-LABEL: vshlq_u32
|
|
uint32x4_t test_vshlq_u32(uint32x4_t a, int32x4_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<4 x !u32i>, !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSHLQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VSHLQ_V2_I:%.*]] = call <4 x i32> @llvm.aarch64.neon.ushl.v4i32(<4 x i32> [[VSHLQ_V_I]], <4 x i32> [[VSHLQ_V1_I]])
|
|
// LLVM: [[VSHLQ_V3_I:%.*]] = bitcast <4 x i32> [[VSHLQ_V2_I]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <16 x i8> [[VSHLQ_V3_I]] to <4 x i32>
|
|
// LLVM: ret <4 x i32> [[TMP2]]
|
|
return vshlq_u32(a, b);
|
|
}
|
|
|
|
// LLVM-LABEL: test_vshlq_u64
|
|
// CIR-LABEL: vshlq_u64
|
|
uint64x2_t test_vshlq_u64(uint64x2_t a, int64x2_t b) {
|
|
// CIR: [[RES:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.ushl" %{{.*}}, %{{.*}} : (!cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>) -> !cir.vector<2 x !u64i>
|
|
|
|
// LLVM: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]]) #{{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VSHLQ_V_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSHLQ_V1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VSHLQ_V2_I:%.*]] = call <2 x i64> @llvm.aarch64.neon.ushl.v2i64(<2 x i64> [[VSHLQ_V_I]], <2 x i64> [[VSHLQ_V1_I]])
|
|
// LLVM: [[VSHLQ_V3_I:%.*]] = bitcast <2 x i64> [[VSHLQ_V2_I]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <16 x i8> [[VSHLQ_V3_I]] to <2 x i64>
|
|
// LLVM: ret <2 x i64> [[TMP2]]
|
|
return vshlq_u64(a, b);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.2.1 Vector shift right
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vshr_n_s8(
|
|
int8x8_t test_vshr_n_s8(int8x8_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s8i, !cir.vector<8 x !s8i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<8 x !s8i>, {{%.*}} : !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <8 x i8> {{.*}}, splat (i8 3)
|
|
// LLVM: ret <8 x i8> [[VSHR_N]]
|
|
return vshr_n_s8(a, 3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vshr_n_s16(
|
|
// CIR-LABEL: @test_vshr_n_s16(
|
|
int16x4_t test_vshr_n_s16(int16x4_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s16i, !cir.vector<4 x !s16i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<4 x !s16i>, {{%.*}} : !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <4 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <4 x i16> [[VSHR_N]]
|
|
return vshr_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshr_n_s32(
|
|
int32x2_t test_vshr_n_s32(int32x2_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s32i, !cir.vector<2 x !s32i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<2 x !s32i>, {{%.*}} : !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <2 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <2 x i32> [[VSHR_N]]
|
|
return vshr_n_s32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshr_n_s64(
|
|
int64x1_t test_vshr_n_s64(int64x1_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s64i, !cir.vector<1 x !s64i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<1 x !s64i>, {{%.*}} : !cir.vector<1 x !s64i>) -> !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <1 x i64> [[TMP1]], splat (i64 1)
|
|
// LLVM: ret <1 x i64> [[VSHR_N]]
|
|
return vshr_n_s64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_s8(
|
|
int8x16_t test_vshrq_n_s8(int8x16_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s8i, !cir.vector<16 x !s8i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<16 x !s8i>, {{%.*}} : !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <16 x i8> {{.*}}, splat (i8 3)
|
|
// LLVM: ret <16 x i8> [[VSHR_N]]
|
|
return vshrq_n_s8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_s16(
|
|
int16x8_t test_vshrq_n_s16(int16x8_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s16i, !cir.vector<8 x !s16i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<8 x !s16i>, {{%.*}} : !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <8 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <8 x i16> [[VSHR_N]]
|
|
return vshrq_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_s32(
|
|
int32x4_t test_vshrq_n_s32(int32x4_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s32i, !cir.vector<4 x !s32i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<4 x !s32i>, {{%.*}} : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <4 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <4 x i32> [[VSHR_N]]
|
|
return vshrq_n_s32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_s64(
|
|
int64x2_t test_vshrq_n_s64(int64x2_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !s64i, !cir.vector<2 x !s64i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<2 x !s64i>, {{%.*}} : !cir.vector<2 x !s64i>) -> !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSHR_N:%.*]] = ashr <2 x i64> [[TMP1]], splat (i64 3)
|
|
// LLVM: ret <2 x i64> [[VSHR_N]]
|
|
return vshrq_n_s64(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshr_n_u8(
|
|
uint8x8_t test_vshr_n_u8(uint8x8_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u8i, !cir.vector<8 x !u8i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<8 x !u8i>, {{%.*}} : !cir.vector<8 x !u8i>) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <8 x i8> {{.*}}, splat (i8 3)
|
|
// LLVM: ret <8 x i8> [[VSHR_N]]
|
|
return vshr_n_u8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshr_n_u16(
|
|
uint16x4_t test_vshr_n_u16(uint16x4_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u16i, !cir.vector<4 x !u16i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<4 x !u16i>, {{%.*}} : !cir.vector<4 x !u16i>) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <4 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <4 x i16> [[VSHR_N]]
|
|
return vshr_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshr_n_u32(
|
|
uint32x2_t test_vshr_n_u32(uint32x2_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u32i, !cir.vector<2 x !u32i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<2 x !u32i>, {{%.*}} : !cir.vector<2 x !u32i>) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <2 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <2 x i32> [[VSHR_N]]
|
|
return vshr_n_u32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshr_n_u64(
|
|
uint64x1_t test_vshr_n_u64(uint64x1_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u64i, !cir.vector<1 x !u64i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<1 x !u64i>, {{%.*}} : !cir.vector<1 x !u64i>) -> !cir.vector<1 x !u64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <1 x i64> [[TMP1]], splat (i64 3)
|
|
// ret <1 x i64> [[VSHR_N]]
|
|
return vshr_n_u64(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_u8(
|
|
uint8x16_t test_vshrq_n_u8(uint8x16_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u8i, !cir.vector<16 x !u8i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<16 x !u8i>, {{%.*}} : !cir.vector<16 x !u8i>) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <16 x i8> {{.*}}, splat (i8 3)
|
|
// LLVM: ret <16 x i8> [[VSHR_N]]
|
|
return vshrq_n_u8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_u16(
|
|
uint16x8_t test_vshrq_n_u16(uint16x8_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u16i, !cir.vector<8 x !u16i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<8 x !u16i>, {{%.*}} : !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <8 x i16> [[TMP1]], splat (i16 3)
|
|
// LLVM: ret <8 x i16> [[VSHR_N]]
|
|
return vshrq_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_u32(
|
|
uint32x4_t test_vshrq_n_u32(uint32x4_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u32i, !cir.vector<4 x !u32i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<4 x !u32i>, {{%.*}} : !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <4 x i32> [[TMP1]], splat (i32 3)
|
|
// LLVM: ret <4 x i32> [[VSHR_N]]
|
|
return vshrq_n_u32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrq_n_u64(
|
|
uint64x2_t test_vshrq_n_u64(uint64x2_t a) {
|
|
// CIR: {{%.*}} = cir.vec.splat {{%.*}} : !u64i, !cir.vector<2 x !u64i>
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !cir.vector<2 x !u64i>, {{%.*}} : !cir.vector<2 x !u64i>) -> !cir.vector<2 x !u64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSHR_N:%.*]] = lshr <2 x i64> [[TMP1]], splat (i64 3)
|
|
// LLVM: ret <2 x i64> [[VSHR_N]]
|
|
return vshrq_n_u64(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrd_n_s64(
|
|
int64_t test_vshrd_n_s64(int64_t a) {
|
|
// CIR: {{%.*}} = cir.shift(right, {{%.*}} : !s64i, {{%.*}} : !s64i) -> !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: [[SHRD_N:%.*]] = ashr i64 {{.*}}, 1
|
|
// LLVM: ret i64 [[SHRD_N]]
|
|
return (int64_t)vshrd_n_s64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrd_n_u64(
|
|
uint64_t test_vshrd_n_u64(uint64_t a) {
|
|
// CIR: {{.*}} = cir.const #cir.int<0> : !u64i
|
|
// CIR: cir.return {{.*}} : !u64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]]) {{.*}} {
|
|
// LLVM: ret i64 0
|
|
return (uint64_t)vshrd_n_u64(a, 64);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vshrd_n_u64_2(
|
|
uint64_t test_vshrd_n_u64_2() {
|
|
// CIR: {{.*}} = cir.const #cir.int<0> : !u64i
|
|
// CIR: cir.return {{.*}} : !u64i
|
|
|
|
// LLVM-SAME: {{.*}} {
|
|
// LLVM: ret i64 0
|
|
uint64_t a = UINT64_C(0xf000000000000000);
|
|
return vshrd_n_u64(a, 64);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.8.5 Bitwise select
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#markdown-toc-bitwise-select
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vbsl_s8(
|
|
// CIR-LABEL: @vbsl_s8(
|
|
int8x8_t test_vbsl_s8(uint8x8_t v1, int8x8_t v2, int8x8_t v3) {
|
|
// CIR: [[MASK_PTR:%.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[AND:%.*]] = cir.and %{{.*}}, %{{.*}} : !cir.vector<8 x !s8i>
|
|
// CIR: [[NOT:%.*]] = cir.not %{{.*}} : !cir.vector<8 x !s8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], %{{.*}} : !cir.vector<8 x !s8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]], <8 x i8> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <8 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <8 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <8 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <8 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <8 x i8> [[VBSL2_I]]
|
|
return vbsl_s8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_s8(
|
|
// CIR-LABEL: @vbslq_s8(
|
|
int8x16_t test_vbslq_s8(uint8x16_t v1, int8x16_t v2, int8x16_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[AND:%.*]] = cir.and %{{.*}}, %{{.*}} : !cir.vector<16 x !s8i>
|
|
// CIR: [[NOT:%.*]] = cir.not %{{.*}} : !cir.vector<16 x !s8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], %{{.*}} : !cir.vector<16 x !s8i>
|
|
// CIR: cir.or [[AND]], [[AND2]] : !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]], <16 x i8> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <16 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <16 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <16 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <16 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <16 x i8> [[VBSL2_I]]
|
|
return vbslq_s8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_s16(
|
|
// CIR-LABEL: @vbsl_s16(
|
|
int8x8_t test_vbsl_s16(uint16x4_t v1, int16x4_t v2, int16x4_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !s16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !s16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<4 x !s16i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<4 x !s16i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<4 x !s16i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]], <4 x i16> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i16> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x i16>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <4 x i16> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <4 x i16> [[VBSL_I]], splat (i16 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <4 x i16> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <4 x i16> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: [[TMP4:%.*]] = bitcast <4 x i16> [[VBSL5_I]] to <8 x i8>
|
|
// LLVM: ret <8 x i8> [[TMP4]]
|
|
return (int8x8_t)vbsl_s16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_s16(
|
|
// CIR-LABEL: @vbslq_s16(
|
|
int16x8_t test_vbslq_s16(uint16x8_t v1, int16x8_t v2, int16x8_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !s16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !s16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<8 x !s16i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<8 x !s16i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<8 x !s16i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]], <8 x i16> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i16> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x i16>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <8 x i16> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <8 x i16> [[VBSL_I]], splat (i16 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <8 x i16> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <8 x i16> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <8 x i16> [[VBSL5_I]]
|
|
return vbslq_s16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_s32(
|
|
// CIR-LABEL: @vbsl_s32(
|
|
int32x2_t test_vbsl_s32(uint32x2_t v1, int32x2_t v2, int32x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !s32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !s32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !s32i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !s32i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !s32i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> {{.*}} [[V2:%.*]], <2 x i32> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x i32>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i32> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <2 x i32> [[VBSL_I]], splat (i32 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i32> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i32> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <2 x i32> [[VBSL5_I]]
|
|
return vbsl_s32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_s32(
|
|
// CIR-LABEL: @vbslq_s32(
|
|
int32x4_t test_vbslq_s32(uint32x4_t v1, int32x4_t v2, int32x4_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !s32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !s32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<4 x !s32i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<4 x !s32i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<4 x !s32i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> {{.*}} [[V2:%.*]], <4 x i32> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x i32>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <4 x i32> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <4 x i32> [[VBSL_I]], splat (i32 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <4 x i32> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <4 x i32> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <4 x i32> [[VBSL5_I]]
|
|
return vbslq_s32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_s64(
|
|
// CIR-LABEL: @vbsl_s64(
|
|
int64x1_t test_vbsl_s64(uint64x1_t v1, int64x1_t v2, int64x1_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !s64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !s64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[V1:%.*]], <1 x i64> {{.*}} [[V2:%.*]], <1 x i64> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <1 x i64> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <1 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <1 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <1 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <1 x i64> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <1 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <1 x i64> [[VBSL5_I]]
|
|
return vbsl_s64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_s64(
|
|
// CIR-LABEL: @vbslq_s64(
|
|
int64x2_t test_vbslq_s64(uint64x2_t v1, int64x2_t v2, int64x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !s64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !s64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[V1:%.*]], <2 x i64> {{.*}} [[V2:%.*]], <2 x i64> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <2 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i64> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <2 x i64> [[VBSL5_I]]
|
|
return vbslq_s64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_u8(
|
|
// CIR-LABEL: @vbsl_u8(
|
|
uint8x8_t test_vbsl_u8(uint8x8_t v1, uint8x8_t v2, uint8x8_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<8 x !u8i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<8 x !u8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<8 x !u8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]], <8 x i8> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <8 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <8 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <8 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <8 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <8 x i8> [[VBSL2_I]]
|
|
return vbsl_u8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_u8(
|
|
// CIR-LABEL: @vbslq_u8(
|
|
uint8x16_t test_vbslq_u8(uint8x16_t v1, uint8x16_t v2, uint8x16_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<16 x !u8i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<16 x !u8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<16 x !u8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]], <16 x i8> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <16 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <16 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <16 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <16 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <16 x i8> [[VBSL2_I]]
|
|
return vbslq_u8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_u16(
|
|
// CIR-LABEL: @vbsl_u16(
|
|
uint16x4_t test_vbsl_u16(uint16x4_t v1, uint16x4_t v2, uint16x4_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<4 x !u16i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<4 x !u16i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<4 x !u16i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]], <4 x i16> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i16> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x i16>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <4 x i16> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <4 x i16> [[VBSL_I]], splat (i16 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <4 x i16> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <4 x i16> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <4 x i16> [[VBSL5_I]]
|
|
return vbsl_u16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_u16(
|
|
// CIR-LABEL: @vbslq_u16(
|
|
uint16x8_t test_vbslq_u16(uint16x8_t v1, uint16x8_t v2, uint16x8_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<8 x !u16i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<8 x !u16i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<8 x !u16i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]], <8 x i16> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i16> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x i16>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <8 x i16> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <8 x i16> [[VBSL_I]], splat (i16 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <8 x i16> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <8 x i16> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <8 x i16> [[VBSL5_I]]
|
|
return vbslq_u16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_u32(
|
|
// CIR-LABEL: @vbsl_u32(
|
|
uint32x2_t test_vbsl_u32(uint32x2_t v1, uint32x2_t v2, uint32x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !u32i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !u32i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !u32i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x i32> {{.*}} [[V2:%.*]], <2 x i32> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x i32>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i32> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <2 x i32> [[VBSL_I]], splat (i32 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i32> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i32> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <2 x i32> [[VBSL5_I]]
|
|
return vbsl_u32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_u32(
|
|
// CIR-LABEL: @vbslq_u32(
|
|
uint32x4_t test_vbslq_u32(uint32x4_t v1, uint32x4_t v2, uint32x4_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<4 x !u32i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<4 x !u32i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<4 x !u32i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x i32> {{.*}} [[V2:%.*]], <4 x i32> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x i32>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <4 x i32> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <4 x i32> [[VBSL_I]], splat (i32 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <4 x i32> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <4 x i32> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <4 x i32> [[VBSL5_I]]
|
|
return vbslq_u32(v1, v2, v3);
|
|
}
|
|
|
|
|
|
// LLVM-LABEL: @test_vbsl_u64(
|
|
// CIR-LABEL: @vbsl_u64(
|
|
uint64x1_t test_vbsl_u64(uint64x1_t v1, uint64x1_t v2, uint64x1_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !u64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !u64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !u64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<1 x !u64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<1 x !u64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<1 x !u64i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<1 x !u64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[V1:%.*]], <1 x i64> {{.*}} [[V2:%.*]], <1 x i64> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <1 x i64> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <1 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <1 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <1 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <1 x i64> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <1 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <1 x i64> [[VBSL5_I]]
|
|
return vbsl_u64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_u64(
|
|
// CIR-LABEL: @vbslq_u64(
|
|
uint64x2_t test_vbslq_u64(uint64x2_t v1, uint64x2_t v2, uint64x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !u64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !u64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !u64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !u64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !u64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !u64i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !u64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[V1:%.*]], <2 x i64> {{.*}} [[V2:%.*]], <2 x i64> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <2 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i64> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <2 x i64> [[VBSL5_I]]
|
|
return vbslq_u64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_f32(
|
|
// CIR-LABEL: @vbsl_f32(
|
|
float32x2_t test_vbsl_f32(uint32x2_t v1, float32x2_t v2, float32x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u32i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !cir.float>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !cir.float>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !s32i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !s32i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !s32i>
|
|
// CIR: [[OR:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !s32i>
|
|
// CIR: cir.cast bitcast [[OR]] : !cir.vector<2 x !s32i> -> !cir.vector<2 x !cir.float>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[V1:%.*]], <2 x float> {{.*}} [[V2:%.*]], <2 x float> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[V2]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x float> [[V3]] to <2 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i32> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <2 x i32>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP3]] to <2 x i32>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP4]] to <2 x i32>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i32> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP5:%.*]] = xor <2 x i32> [[VBSL_I]], splat (i32 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i32> [[TMP5]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i32> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: [[TMP6:%.*]] = bitcast <2 x i32> [[VBSL5_I]] to <2 x float>
|
|
// LLVM: ret <2 x float> [[TMP6]]
|
|
return vbsl_f32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_f32(
|
|
// CIR-LABEL: @vbslq_f32(
|
|
float32x4_t test_vbslq_f32(uint32x4_t v1, float32x4_t v2, float32x4_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u32i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !cir.float>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !cir.float>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<4 x !s32i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<4 x !s32i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<4 x !s32i>
|
|
// CIR: [[OR:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<4 x !s32i>
|
|
// CIR: cir.cast bitcast [[OR]] : !cir.vector<4 x !s32i> -> !cir.vector<4 x !cir.float>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[V1:%.*]], <4 x float> {{.*}} [[V2:%.*]], <4 x float> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[V2]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x float> [[V3]] to <4 x i32>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i32> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <4 x i32>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x i32>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP4]] to <4 x i32>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <4 x i32> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP5:%.*]] = xor <4 x i32> [[VBSL_I]], splat (i32 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <4 x i32> [[TMP5]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <4 x i32> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: [[TMP6:%.*]] = bitcast <4 x i32> [[VBSL5_I]] to <4 x float>
|
|
// LLVM: ret <4 x float> [[TMP6]]
|
|
return vbslq_f32(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_p8(
|
|
// CIR-LABEL: @vbsl_p8(
|
|
poly8x8_t test_vbsl_p8(uint8x8_t v1, poly8x8_t v2, poly8x8_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[AND:%.*]] = cir.and %{{.*}}, %{{.*}} : !cir.vector<8 x !s8i>
|
|
// CIR: [[NOT:%.*]] = cir.not %{{.*}} : !cir.vector<8 x !s8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], %{{.*}} : !cir.vector<8 x !s8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> {{.*}} [[V2:%.*]], <8 x i8> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <8 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <8 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <8 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <8 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <8 x i8> [[VBSL2_I]]
|
|
return vbsl_p8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_p8(
|
|
// CIR-LABEL: @vbslq_p8(
|
|
poly8x16_t test_vbslq_p8(uint8x16_t v1, poly8x16_t v2, poly8x16_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[AND:%.*]] = cir.and %{{.*}}, %{{.*}} : !cir.vector<16 x !s8i>
|
|
// CIR: [[NOT:%.*]] = cir.not %{{.*}} : !cir.vector<16 x !s8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], %{{.*}} : !cir.vector<16 x !s8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> {{.*}} [[V2:%.*]], <16 x i8> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <16 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <16 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <16 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <16 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <16 x i8> [[VBSL2_I]]
|
|
return vbslq_p8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_p16(
|
|
// CIR-LABEL: @vbsl_p16(
|
|
poly16x4_t test_vbsl_p16(uint16x4_t v1, poly16x4_t v2, poly16x4_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<4 x !u16i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<4 x !s16i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<4 x !s16i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<4 x !s16i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[V1:%.*]], <4 x i16> {{.*}} [[V2:%.*]], <4 x i16> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <4 x i16> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <4 x i16>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <4 x i16> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <4 x i16> [[VBSL_I]], splat (i16 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <4 x i16> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <4 x i16> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <4 x i16> [[VBSL5_I]]
|
|
return vbsl_p16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_p16(
|
|
// CIR-LABEL: @vbslq_p16(
|
|
poly16x8_t test_vbslq_p16(uint16x8_t v1, poly16x8_t v2, poly16x8_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u16i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<8 x !s16i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<8 x !s16i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<8 x !s16i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[V1:%.*]], <8 x i16> {{.*}} [[V2:%.*]], <8 x i16> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <8 x i16> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <8 x i16>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <8 x i16> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <8 x i16> [[VBSL_I]], splat (i16 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <8 x i16> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <8 x i16> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <8 x i16> [[VBSL5_I]]
|
|
return vbslq_p16(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_p64(
|
|
// CIR-LABEL: @vbsl_p64(
|
|
poly64x1_t test_vbsl_p64(poly64x1_t v1, poly64x1_t v2, poly64x1_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[V1:%.*]], <1 x i64> {{.*}} [[V2:%.*]], <1 x i64> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[V2]] to <8 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <1 x i64> [[V3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP2]] to <1 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <1 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <1 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <1 x i64> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <1 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <1 x i64> [[VBSL5_I]]
|
|
return vbsl_p64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_p64(
|
|
// CIR-LABEL: @vbslq_p64(
|
|
poly64x2_t test_vbslq_p64(poly64x2_t v1, poly64x2_t v2, poly64x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[V1:%.*]], <2 x i64> {{.*}} [[V2:%.*]], <2 x i64> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[V2]] to <16 x i8>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[V3]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP3:%.*]] = xor <2 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i64> [[TMP3]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: ret <2 x i64> [[VBSL5_I]]
|
|
return vbslq_p64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_f64(
|
|
// CIR-LABEL: @vbsl_f64(
|
|
float64x1_t test_vbsl_f64(uint64x1_t v1, float64x1_t v2, float64x1_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !u64i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !cir.double>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<1 x !cir.double>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<1 x !s64i>
|
|
// CIR: [[OR:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<1 x !s64i>
|
|
// CIR: cir.cast bitcast [[OR]] : !cir.vector<1 x !s64i> -> !cir.vector<1 x !cir.double>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[V1:%.*]], <1 x double> {{.*}} [[V2:%.*]], <1 x double> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[V2]] to i64
|
|
// LLVM: [[TMP1:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM: [[TMP2:%.*]] = bitcast <1 x double> [[V3]] to i64
|
|
// LLVM: [[TMP3:%.*]] = insertelement <1 x i64> undef, i64 [[TMP2]], i32 0
|
|
// LLVM: [[TMP4:%.*]] = bitcast <1 x i64> [[V1]] to <8 x i8>
|
|
// LLVM: [[TMP5:%.*]] = bitcast <1 x i64> [[TMP1]] to <8 x i8>
|
|
// LLVM: [[TMP6:%.*]] = bitcast <1 x i64> [[TMP3]] to <8 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <8 x i8> [[TMP4]] to <1 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <8 x i8> [[TMP5]] to <1 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <8 x i8> [[TMP6]] to <1 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <1 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP7:%.*]] = xor <1 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <1 x i64> [[TMP7]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <1 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: [[TMP8:%.*]] = bitcast <1 x i64> [[VBSL5_I]] to <1 x double>
|
|
// LLVM: ret <1 x double> [[TMP8]]
|
|
return vbsl_f64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_f64(
|
|
// CIR-LABEL: @vbslq_f64(
|
|
float64x2_t test_vbslq_f64(uint64x2_t v1, float64x2_t v2, float64x2_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !u64i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !cir.double>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<2 x !cir.double>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<2 x !s64i>
|
|
// CIR: [[OR:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<2 x !s64i>
|
|
// CIR: cir.cast bitcast [[OR]] : !cir.vector<2 x !s64i> -> !cir.vector<2 x !cir.double>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[V1:%.*]], <2 x double> {{.*}} [[V2:%.*]], <2 x double> {{.*}} [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[V2]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x double> [[V3]] to <2 x i64>
|
|
// LLVM: [[TMP2:%.*]] = bitcast <2 x i64> [[V1]] to <16 x i8>
|
|
// LLVM: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
|
|
// LLVM: [[VBSL_I:%.*]] = bitcast <16 x i8> [[TMP2]] to <2 x i64>
|
|
// LLVM: [[VBSL1_I:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x i64>
|
|
// LLVM: [[VBSL2_I:%.*]] = bitcast <16 x i8> [[TMP4]] to <2 x i64>
|
|
// LLVM: [[VBSL3_I:%.*]] = and <2 x i64> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: [[TMP5:%.*]] = xor <2 x i64> [[VBSL_I]], splat (i64 -1)
|
|
// LLVM: [[VBSL4_I:%.*]] = and <2 x i64> [[TMP5]], [[VBSL2_I]]
|
|
// LLVM: [[VBSL5_I:%.*]] = or <2 x i64> [[VBSL3_I]], [[VBSL4_I]]
|
|
// LLVM: [[TMP6:%.*]] = bitcast <2 x i64> [[VBSL5_I]] to <2 x double>
|
|
// LLVM: ret <2 x double> [[TMP6]]
|
|
return vbslq_f64(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbsl_mf8(
|
|
// CIR-LABEL: @vbsl_mf8(
|
|
mfloat8x8_t test_vbsl_mf8(uint8x8_t v1, mfloat8x8_t v2, mfloat8x8_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<8 x !u8i>> -> !cir.ptr<!cir.vector<8 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<8 x !u8i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<8 x !u8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<8 x !u8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[V1:%.*]], <8 x i8> [[V2:%.*]], <8 x i8> [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <8 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <8 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <8 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <8 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <8 x i8> [[VBSL2_I]]
|
|
return vbsl_mf8(v1, v2, v3);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vbslq_mf8(
|
|
// CIR-LABEL: @vbslq_mf8(
|
|
mfloat8x16_t test_vbslq_mf8(uint8x16_t v1, mfloat8x16_t v2, mfloat8x16_t v3) {
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.vector<16 x !u8i>> -> !cir.ptr<!cir.vector<16 x !s8i>>
|
|
// CIR: [[MASK:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[VAL1:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[VAL2:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[AND:%.*]] = cir.and [[MASK]], [[VAL1]] : !cir.vector<16 x !u8i>
|
|
// CIR: [[NOT:%.*]] = cir.not [[MASK]] : !cir.vector<16 x !u8i>
|
|
// CIR: [[AND2:%.*]] = cir.and [[NOT]], [[VAL2]] : !cir.vector<16 x !u8i>
|
|
// CIR: [[RES:%.*]] = cir.or [[AND]], [[AND2]] : !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[V1:%.*]], <16 x i8> [[V2:%.*]], <16 x i8> [[V3:%.*]]) {{.*}} {
|
|
// LLVM: [[VBSL_I:%.*]] = and <16 x i8> [[V1]], [[V2]]
|
|
// LLVM: [[TMP0:%.*]] = xor <16 x i8> [[V1]], splat (i8 -1)
|
|
// LLVM: [[VBSL1_I:%.*]] = and <16 x i8> [[TMP0]], [[V3]]
|
|
// LLVM: [[VBSL2_I:%.*]] = or <16 x i8> [[VBSL_I]], [[VBSL1_I]]
|
|
// LLVM: ret <16 x i8> [[VBSL2_I]]
|
|
return vbslq_mf8(v1, v2, v3);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.4.1 Convearions
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#conversions
|
|
//===------------------------------------------------------===//
|
|
// ALL-LABEL: @test_vcvt_n_f32_s32(
|
|
float32x2_t test_vcvt_n_f32_s32(int32x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxs2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x float> @llvm.aarch64.neon.vcvtfxs2fp.v2f32.v2i32(<2 x i32> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <2 x float> [[VCVT_N1]]
|
|
return vcvt_n_f32_s32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_f32_s32(
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
float32x4_t test_vcvtq_n_f32_s32(int32x4_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxs2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <4 x float> @llvm.aarch64.neon.vcvtfxs2fp.v4f32.v4i32(<4 x i32> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <4 x float> [[VCVT_N1]]
|
|
return vcvtq_n_f32_s32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_f64_s64(
|
|
float64x2_t test_vcvtq_n_f64_s64(int64x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<50>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxs2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x double> @llvm.aarch64.neon.vcvtfxs2fp.v2f64.v2i64(<2 x i64> [[VCVT_N]], i32 50)
|
|
// LLVM: ret <2 x double> [[VCVT_N1]]
|
|
return vcvtq_n_f64_s64(a, 50);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_f32_u32(
|
|
float32x2_t test_vcvt_n_f32_u32(uint32x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxu2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x float> @llvm.aarch64.neon.vcvtfxu2fp.v2f32.v2i32(<2 x i32> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <2 x float> [[VCVT_N1]]
|
|
return vcvt_n_f32_u32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_f32_u32(
|
|
float32x4_t test_vcvtq_n_f32_u32(uint32x4_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxu2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <4 x float> @llvm.aarch64.neon.vcvtfxu2fp.v4f32.v4i32(<4 x i32> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <4 x float> [[VCVT_N1]]
|
|
return vcvtq_n_f32_u32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_f64_u64(
|
|
float64x2_t test_vcvtq_n_f64_u64(uint64x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<50>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxu2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x double> @llvm.aarch64.neon.vcvtfxu2fp.v2f64.v2i64(<2 x i64> [[VCVT_N]], i32 50)
|
|
// LLVM: ret <2 x double> [[VCVT_N1]]
|
|
return vcvtq_n_f64_u64(a, 50);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_s32_f32(
|
|
int32x2_t test_vcvt_n_s32_f32(float32x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxs" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.vcvtfp2fxs.v2i32.v2f32(<2 x float> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <2 x i32> [[VCVT_N1]]
|
|
return vcvt_n_s32_f32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_s32_f32(
|
|
int32x4_t test_vcvtq_n_s32_f32(float32x4_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxs" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <4 x i32> @llvm.aarch64.neon.vcvtfp2fxs.v4i32.v4f32(<4 x float> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <4 x i32> [[VCVT_N1]]
|
|
return vcvtq_n_s32_f32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_s64_f64(
|
|
int64x2_t test_vcvtq_n_s64_f64(float64x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<50>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxs" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x i64> @llvm.aarch64.neon.vcvtfp2fxs.v2i64.v2f64(<2 x double> [[VCVT_N]], i32 50)
|
|
// LLVM: ret <2 x i64> [[VCVT_N1]]
|
|
return vcvtq_n_s64_f64(a, 50);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_u32_f32(
|
|
uint32x2_t test_vcvt_n_u32_f32(float32x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxu" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.vcvtfp2fxu.v2i32.v2f32(<2 x float> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <2 x i32> [[VCVT_N1]]
|
|
return vcvt_n_u32_f32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_u32_f32(
|
|
uint32x4_t test_vcvtq_n_u32_f32(float32x4_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<31>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxu" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <4 x i32> @llvm.aarch64.neon.vcvtfp2fxu.v4i32.v4f32(<4 x float> [[VCVT_N]], i32 31)
|
|
// LLVM: ret <4 x i32> [[VCVT_N1]]
|
|
return vcvtq_n_u32_f32(a, 31);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtq_n_u64_f64(
|
|
uint64x2_t test_vcvtq_n_u64_f64(float64x2_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<50>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxu" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x double>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <2 x i64> @llvm.aarch64.neon.vcvtfp2fxu.v2i64.v2f64(<2 x double> [[VCVT_N]], i32 50)
|
|
// LLVM: ret <2 x i64> [[VCVT_N1]]
|
|
return vcvtq_n_u64_f64(a, 50);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_s64_f64(
|
|
int64x1_t test_vcvt_n_s64_f64(float64x1_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<64>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxs" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64
|
|
// LLVM: [[__S0_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[__S0_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x double>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <1 x i64> @llvm.aarch64.neon.vcvtfp2fxs.v1i64.v1f64(<1 x double> [[VCVT_N]], i32 64)
|
|
// LLVM: ret <1 x i64> [[VCVT_N1]]
|
|
return vcvt_n_s64_f64(a, 64);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_u64_f64(
|
|
uint64x1_t test_vcvt_n_u64_f64(float64x1_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<64>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxu" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <1 x double> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x double> [[A]] to i64
|
|
// LLVM: [[__S0_SROA_0_0_VEC_INSERT:%.*]] = insertelement <1 x i64> undef, i64 [[TMP0]], i32 0
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[__S0_SROA_0_0_VEC_INSERT]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x double>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <1 x i64> @llvm.aarch64.neon.vcvtfp2fxu.v1i64.v1f64(<1 x double> [[VCVT_N]], i32 64)
|
|
// LLVM: ret <1 x i64> [[VCVT_N1]]
|
|
return vcvt_n_u64_f64(a, 64);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_f64_s64(
|
|
float64x1_t test_vcvt_n_f64_s64(int64x1_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<64>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxs2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <1 x double> @llvm.aarch64.neon.vcvtfxs2fp.v1f64.v1i64(<1 x i64> [[VCVT_N]], i32 64)
|
|
// LLVM: ret <1 x double> [[VCVT_N1]]
|
|
return vcvt_n_f64_s64(a, 64);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvt_n_f64_u64(
|
|
float64x1_t test_vcvt_n_f64_u64(uint64x1_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<64>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxu2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[VCVT_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VCVT_N1:%.*]] = call <1 x double> @llvm.aarch64.neon.vcvtfxu2fp.v1f64.v1i64(<1 x i64> [[VCVT_N]], i32 64)
|
|
// LLVM: ret <1 x double> [[VCVT_N1]]
|
|
return vcvt_n_f64_u64(a, 64);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvts_n_f32_s32(
|
|
float32_t test_vcvts_n_f32_s32(int32_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<1>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxs2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: i32 {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTS_N_F32_S32:%.*]] = call float @llvm.aarch64.neon.vcvtfxs2fp.f32.i32(i32 [[A]], i32 1)
|
|
// LLVM: ret float [[VCVTS_N_F32_S32]]
|
|
return vcvts_n_f32_s32(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvts_n_f32_u32(
|
|
float32_t test_vcvts_n_f32_u32(uint32_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<32>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxu2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: i32 {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTS_N_F32_U32:%.*]] = call float @llvm.aarch64.neon.vcvtfxu2fp.f32.i32(i32 [[A]], i32 32)
|
|
// LLVM: ret float [[VCVTS_N_F32_U32]]
|
|
return vcvts_n_f32_u32(a, 32);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvts_n_s32_f32(
|
|
int32_t test_vcvts_n_s32_f32(float32_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<1>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxs" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: float {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTS_N_S32_F32:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f32(float [[A]], i32 1)
|
|
// LLVM: ret i32 [[VCVTS_N_S32_F32]]
|
|
return (int32_t)vcvts_n_s32_f32(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvts_n_u32_f32(
|
|
uint32_t test_vcvts_n_u32_f32(float32_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<32>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxu" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: float {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTS_N_U32_F32:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f32(float [[A]], i32 32)
|
|
// LLVM: ret i32 [[VCVTS_N_U32_F32]]
|
|
return (uint32_t)vcvts_n_u32_f32(a, 32);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtd_n_f64_s64(
|
|
float64_t test_vcvtd_n_f64_s64(int64_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<1>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxs2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTD_N_F64_S64:%.*]] = call double @llvm.aarch64.neon.vcvtfxs2fp.f64.i64(i64 [[A]], i32 1)
|
|
// LLVM: ret double [[VCVTD_N_F64_S64]]
|
|
return vcvtd_n_f64_s64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtd_n_f64_u64(
|
|
float64_t test_vcvtd_n_f64_u64(uint64_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<64>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfxu2fp" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTD_N_F64_U64:%.*]] = call double @llvm.aarch64.neon.vcvtfxu2fp.f64.i64(i64 [[A]], i32 64)
|
|
// LLVM: ret double [[VCVTD_N_F64_U64]]
|
|
return vcvtd_n_f64_u64(a, 64);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtd_n_s64_f64(
|
|
int64_t test_vcvtd_n_s64_f64(float64_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<1>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxs" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: double {{.*}}[[A:%.*]])
|
|
// LLVM: [[VCVTD_N_S64_F64:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f64(double [[A]], i32 1)
|
|
// LLVM: ret i64 [[VCVTD_N_S64_F64]]
|
|
return (int64_t)vcvtd_n_s64_f64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vcvtd_n_u64_f64(
|
|
uint64_t test_vcvtd_n_u64_f64(float64_t a) {
|
|
// CIR: [[CST:%.*]] = cir.const #cir.int<64>
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vcvtfp2fxu" %{{.*}}, [[CST]]
|
|
|
|
// LLVM-SAME: double {{.*}} [[A:%.*]])
|
|
// LLVM: [[VCVTD_N_U64_F64:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxu.i64.f64(double [[A]], i32 64)
|
|
// LLVM: ret i64 [[VCVTD_N_U64_F64]]
|
|
return (uint64_t)vcvtd_n_u64_f64(a, 64);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.2.3 Vector shift right and accumulate
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-shift-right-and-accumulate
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vsra_n_s8(
|
|
int8x8_t test_vsra_n_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]], <8 x i8> {{.*}}[[B:%.*]])
|
|
// LLVM: [[VSRA_N:%.*]] = ashr <8 x i8> [[B]], splat (i8 3)
|
|
// LLVM: [[TMP0:%.*]] = add <8 x i8> [[A]], [[VSRA_N]]
|
|
// LLVM: ret <8 x i8> [[TMP0]]
|
|
return vsra_n_s8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_s16(
|
|
int16x4_t test_vsra_n_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]], <4 x i16> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = ashr <4 x i16> [[TMP3]], splat (i16 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <4 x i16> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <4 x i16> [[TMP4]]
|
|
return vsra_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_s32(
|
|
int32x2_t test_vsra_n_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}}[[A:%.*]], <2 x i32> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = ashr <2 x i32> [[TMP3]], splat (i32 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <2 x i32> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <2 x i32> [[TMP4]]
|
|
return vsra_n_s32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_s8(
|
|
int8x16_t test_vsraq_n_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]], <16 x i8> {{.*}}[[B:%.*]])
|
|
// LLVM: [[VSRA_N:%.*]] = ashr <16 x i8> [[B]], splat (i8 3)
|
|
// LLVM: [[TMP0:%.*]] = add <16 x i8> [[A]], [[VSRA_N]]
|
|
// LLVM: ret <16 x i8> [[TMP0]]
|
|
return vsraq_n_s8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_s16(
|
|
int16x8_t test_vsraq_n_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]], <8 x i16> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = ashr <8 x i16> [[TMP3]], splat (i16 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <8 x i16> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <8 x i16> [[TMP4]]
|
|
return vsraq_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_s32(
|
|
int32x4_t test_vsraq_n_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}}[[A:%.*]], <4 x i32> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = ashr <4 x i32> [[TMP3]], splat (i32 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <4 x i32> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <4 x i32> [[TMP4]]
|
|
return vsraq_n_s32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_s64(
|
|
int64x2_t test_vsraq_n_s64(int64x2_t a, int64x2_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}}[[A:%.*]], <2 x i64> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = ashr <2 x i64> [[TMP3]], splat (i64 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <2 x i64> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <2 x i64> [[TMP4]]
|
|
return vsraq_n_s64(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_u8(
|
|
uint8x8_t test_vsra_n_u8(uint8x8_t a, uint8x8_t b) {
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]], <8 x i8> {{.*}}[[B:%.*]])
|
|
// LLVM: [[VSRA_N:%.*]] = lshr <8 x i8> [[B]], splat (i8 3)
|
|
// LLVM: [[TMP0:%.*]] = add <8 x i8> [[A]], [[VSRA_N]]
|
|
// LLVM: ret <8 x i8> [[TMP0]]
|
|
return vsra_n_u8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_u16(
|
|
uint16x4_t test_vsra_n_u16(uint16x4_t a, uint16x4_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]], <4 x i16> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = lshr <4 x i16> [[TMP3]], splat (i16 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <4 x i16> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <4 x i16> [[TMP4]]
|
|
return vsra_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_u32(
|
|
uint32x2_t test_vsra_n_u32(uint32x2_t a, uint32x2_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}}[[A:%.*]], <2 x i32> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = lshr <2 x i32> [[TMP3]], splat (i32 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <2 x i32> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <2 x i32> [[TMP4]]
|
|
return vsra_n_u32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_u8(
|
|
uint8x16_t test_vsraq_n_u8(uint8x16_t a, uint8x16_t b) {
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]], <16 x i8> {{.*}}[[B:%.*]])
|
|
// LLVM: [[VSRA_N:%.*]] = lshr <16 x i8> [[B]], splat (i8 3)
|
|
// LLVM: [[TMP0:%.*]] = add <16 x i8> [[A]], [[VSRA_N]]
|
|
// LLVM: ret <16 x i8> [[TMP0]]
|
|
return vsraq_n_u8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_u16(
|
|
uint16x8_t test_vsraq_n_u16(uint16x8_t a, uint16x8_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]], <8 x i16> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = lshr <8 x i16> [[TMP3]], splat (i16 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <8 x i16> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <8 x i16> [[TMP4]]
|
|
return vsraq_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_u32(
|
|
uint32x4_t test_vsraq_n_u32(uint32x4_t a, uint32x4_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}}[[A:%.*]], <4 x i32> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = lshr <4 x i32> [[TMP3]], splat (i32 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <4 x i32> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <4 x i32> [[TMP4]]
|
|
return vsraq_n_u32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsraq_n_u64(
|
|
uint64x2_t test_vsraq_n_u64(uint64x2_t a, uint64x2_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}}[[A:%.*]], <2 x i64> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = lshr <2 x i64> [[TMP3]], splat (i64 3)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <2 x i64> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <2 x i64> [[TMP4]]
|
|
return vsraq_n_u64(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_s64(
|
|
int64x1_t test_vsra_n_s64(int64x1_t a, int64x1_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}}[[A:%.*]], <1 x i64> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = ashr <1 x i64> [[TMP3]], splat (i64 1)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <1 x i64> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <1 x i64> [[TMP4]]
|
|
return vsra_n_s64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsra_n_u64(
|
|
uint64x1_t test_vsra_n_u64(uint64x1_t a, uint64x1_t b) {
|
|
// CIR: cir.cast bitcast
|
|
// CIR: cir.vec.splat
|
|
// CIR: cir.shift(right,
|
|
// CIR: cir.add
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}}[[A:%.*]], <1 x i64> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[TMP3:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRA_N:%.*]] = lshr <1 x i64> [[TMP3]], splat (i64 1)
|
|
// LLVM-NEXT: [[TMP4:%.*]] = add <1 x i64> [[TMP2]], [[VSRA_N]]
|
|
// LLVM: ret <1 x i64> [[TMP4]]
|
|
return vsra_n_u64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsrad_n_s64(
|
|
int64_t test_vsrad_n_s64(int64_t a, int64_t b) {
|
|
// CIR: [[SHR:%.*]] = cir.shift(right, %{{.*}} : !s64i, %{{.*}} : !s64i) -> !s64i
|
|
// CIR: cir.add %{{.*}}, [[SHR]] : !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]], i64 {{.*}}[[B:%.*]])
|
|
// LLVM: [[SHRD_N:%.*]] = ashr i64 [[B]], 63
|
|
// LLVM: [[TMP0:%.*]] = add i64 [[A]], [[SHRD_N]]
|
|
// LLVM: ret i64 [[TMP0]]
|
|
return (int64_t)vsrad_n_s64(a, b, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsrad_n_u64(
|
|
uint64_t test_vsrad_n_u64(uint64_t a, uint64_t b) {
|
|
// CIR: [[SHR:%.*]] = cir.shift(right, %{{.*}} : !u64i, %{{.*}} : !u64i) -> !u64i
|
|
// CIR: cir.add %{{.*}}, [[SHR]] : !u64i
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]], i64 {{.*}}[[B:%.*]])
|
|
// LLVM: [[SHRD_N:%.*]] = lshr i64 [[B]], 63
|
|
// LLVM: [[TMP0:%.*]] = add i64 [[A]], [[SHRD_N]]
|
|
// LLVM: ret i64 [[TMP0]]
|
|
return (uint64_t)vsrad_n_u64(a, b, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsrad_n_u64_2(
|
|
uint64_t test_vsrad_n_u64_2(uint64_t a, uint64_t b) {
|
|
// CIR-NOT: cir.shift
|
|
// CIR-NOT: cir.add
|
|
// CIR: cir.return
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]], i64 {{.*}}[[B:%.*]])
|
|
// LLVM: ret i64 [[A]]
|
|
return (uint64_t)vsrad_n_u64(a, b, 64);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.2.4 Vector rounding shift right and accumulate
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-rounding-shift-right-and-accumulate
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vrsra_n_s8(
|
|
int8x8_t test_vrsra_n_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s8i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s8i, !cir.vector<8 x !s8i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !s8i>
|
|
// CIR: [[RES:%.*]] = cir.add %{{.*}}, [[RSH]] : !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[RSH:%.*]] = call <8 x i8> @llvm.aarch64.neon.srshl.v8i8(<8 x i8> [[B]], <8 x i8> splat (i8 -1))
|
|
// LLVM: [[RES:%.*]] = add <8 x i8> [[A]], [[RSH]]
|
|
// LLVM: ret <8 x i8> [[RES]]
|
|
return vrsra_n_s8(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_s8(
|
|
int8x16_t test_vrsraq_n_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s8i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s8i, !cir.vector<16 x !s8i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !s8i>
|
|
// CIR: [[RES:%.*]] = cir.add %{{.*}}, [[RSH]] : !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[RSH:%.*]] = call <16 x i8> @llvm.aarch64.neon.srshl.v16i8(<16 x i8> [[B]], <16 x i8> splat (i8 -1))
|
|
// LLVM: [[RES:%.*]] = add <16 x i8> [[A]], [[RSH]]
|
|
// LLVM: ret <16 x i8> [[RES]]
|
|
return vrsraq_n_s8(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_s16(
|
|
int16x4_t test_vrsra_n_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s16i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s16i, !cir.vector<4 x !s16i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !s16i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !s16i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_RAW]] to <4 x i16>
|
|
// LLVM: [[RSH:%.*]] = call <4 x i16> @llvm.aarch64.neon.srshl.v4i16(<4 x i16> [[B_CAST]], <4 x i16> splat (i16 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_RAW]] to <4 x i16>
|
|
// LLVM: [[RES:%.*]] = add <4 x i16> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <4 x i16> [[RES]]
|
|
return vrsra_n_s16(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_s16(
|
|
int16x8_t test_vrsraq_n_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s16i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s16i, !cir.vector<8 x !s16i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !s16i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_RAW]] to <8 x i16>
|
|
// LLVM: [[RSH:%.*]] = call <8 x i16> @llvm.aarch64.neon.srshl.v8i16(<8 x i16> [[B_CAST]], <8 x i16> splat (i16 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_RAW]] to <8 x i16>
|
|
// LLVM: [[RES:%.*]] = add <8 x i16> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <8 x i16> [[RES]]
|
|
return vrsraq_n_s16(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_s32(
|
|
int32x2_t test_vrsra_n_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s32i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s32i, !cir.vector<2 x !s32i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !s32i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_RAW]] to <2 x i32>
|
|
// LLVM: [[RSH:%.*]] = call <2 x i32> @llvm.aarch64.neon.srshl.v2i32(<2 x i32> [[B_CAST]], <2 x i32> splat (i32 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_RAW]] to <2 x i32>
|
|
// LLVM: [[RES:%.*]] = add <2 x i32> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <2 x i32> [[RES]]
|
|
return vrsra_n_s32(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_s32(
|
|
int32x4_t test_vrsraq_n_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s32i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s32i, !cir.vector<4 x !s32i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !s32i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_RAW]] to <4 x i32>
|
|
// LLVM: [[RSH:%.*]] = call <4 x i32> @llvm.aarch64.neon.srshl.v4i32(<4 x i32> [[B_CAST]], <4 x i32> splat (i32 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_RAW]] to <4 x i32>
|
|
// LLVM: [[RES:%.*]] = add <4 x i32> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <4 x i32> [[RES]]
|
|
return vrsraq_n_s32(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_s64(
|
|
int64x1_t test_vrsra_n_s64(int64x1_t a, int64x1_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s64i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s64i, !cir.vector<1 x !s64i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<1 x !s64i>, !cir.vector<1 x !s64i>) -> !cir.vector<1 x !s64i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !s64i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]], <1 x i64> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_RAW]] to <1 x i64>
|
|
// LLVM: [[RSH:%.*]] = call <1 x i64> @llvm.aarch64.neon.srshl.v1i64(<1 x i64> [[B_CAST]], <1 x i64> splat (i64 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_RAW]] to <1 x i64>
|
|
// LLVM: [[RES:%.*]] = add <1 x i64> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <1 x i64> [[RES]]
|
|
return vrsra_n_s64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_s64(
|
|
int64x2_t test_vrsraq_n_s64(int64x2_t a, int64x2_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s64i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s64i, !cir.vector<2 x !s64i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>) -> !cir.vector<2 x !s64i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !s64i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_RAW]] to <2 x i64>
|
|
// LLVM: [[RSH:%.*]] = call <2 x i64> @llvm.aarch64.neon.srshl.v2i64(<2 x i64> [[B_CAST]], <2 x i64> splat (i64 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_RAW]] to <2 x i64>
|
|
// LLVM: [[RES:%.*]] = add <2 x i64> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <2 x i64> [[RES]]
|
|
return vrsraq_n_s64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_u8(
|
|
uint8x8_t test_vrsra_n_u8(uint8x8_t a, uint8x8_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s8i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s8i, !cir.vector<8 x !s8i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<8 x !u8i>, !cir.vector<8 x !s8i>) -> !cir.vector<8 x !u8i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<8 x !u8i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[RSH:%.*]] = call <8 x i8> @llvm.aarch64.neon.urshl.v8i8(<8 x i8> [[B]], <8 x i8> splat (i8 -1))
|
|
// LLVM: [[RES:%.*]] = add <8 x i8> [[A]], [[RSH]]
|
|
// LLVM: ret <8 x i8> [[RES]]
|
|
return vrsra_n_u8(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_u8(
|
|
uint8x16_t test_vrsraq_n_u8(uint8x16_t a, uint8x16_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s8i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s8i, !cir.vector<16 x !s8i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<16 x !u8i>, !cir.vector<16 x !s8i>) -> !cir.vector<16 x !u8i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<16 x !u8i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[RSH:%.*]] = call <16 x i8> @llvm.aarch64.neon.urshl.v16i8(<16 x i8> [[B]], <16 x i8> splat (i8 -1))
|
|
// LLVM: [[RES:%.*]] = add <16 x i8> [[A]], [[RSH]]
|
|
// LLVM: ret <16 x i8> [[RES]]
|
|
return vrsraq_n_u8(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_u16(
|
|
uint16x4_t test_vrsra_n_u16(uint16x4_t a, uint16x4_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s16i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s16i, !cir.vector<4 x !s16i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<4 x !u16i>, !cir.vector<4 x !s16i>) -> !cir.vector<4 x !u16i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<4 x !u16i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_RAW]] to <4 x i16>
|
|
// LLVM: [[RSH:%.*]] = call <4 x i16> @llvm.aarch64.neon.urshl.v4i16(<4 x i16> [[B_CAST]], <4 x i16> splat (i16 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_RAW]] to <4 x i16>
|
|
// LLVM: [[RES:%.*]] = add <4 x i16> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <4 x i16> [[RES]]
|
|
return vrsra_n_u16(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_u16(
|
|
uint16x8_t test_vrsraq_n_u16(uint16x8_t a, uint16x8_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s16i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s16i, !cir.vector<8 x !s16i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<8 x !u16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !u16i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<8 x !u16i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_RAW]] to <8 x i16>
|
|
// LLVM: [[RSH:%.*]] = call <8 x i16> @llvm.aarch64.neon.urshl.v8i16(<8 x i16> [[B_CAST]], <8 x i16> splat (i16 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_RAW]] to <8 x i16>
|
|
// LLVM: [[RES:%.*]] = add <8 x i16> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <8 x i16> [[RES]]
|
|
return vrsraq_n_u16(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_u32(
|
|
uint32x2_t test_vrsra_n_u32(uint32x2_t a, uint32x2_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s32i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s32i, !cir.vector<2 x !s32i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<2 x !u32i>, !cir.vector<2 x !s32i>) -> !cir.vector<2 x !u32i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<2 x !u32i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_RAW]] to <2 x i32>
|
|
// LLVM: [[RSH:%.*]] = call <2 x i32> @llvm.aarch64.neon.urshl.v2i32(<2 x i32> [[B_CAST]], <2 x i32> splat (i32 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_RAW]] to <2 x i32>
|
|
// LLVM: [[RES:%.*]] = add <2 x i32> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <2 x i32> [[RES]]
|
|
return vrsra_n_u32(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_u32(
|
|
uint32x4_t test_vrsraq_n_u32(uint32x4_t a, uint32x4_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s32i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s32i, !cir.vector<4 x !s32i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<4 x !u32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !u32i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<4 x !u32i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_RAW]] to <4 x i32>
|
|
// LLVM: [[RSH:%.*]] = call <4 x i32> @llvm.aarch64.neon.urshl.v4i32(<4 x i32> [[B_CAST]], <4 x i32> splat (i32 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_RAW]] to <4 x i32>
|
|
// LLVM: [[RES:%.*]] = add <4 x i32> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <4 x i32> [[RES]]
|
|
return vrsraq_n_u32(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsra_n_u64(
|
|
uint64x1_t test_vrsra_n_u64(uint64x1_t a, uint64x1_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s64i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s64i, !cir.vector<1 x !s64i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<1 x !u64i>, !cir.vector<1 x !s64i>) -> !cir.vector<1 x !u64i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s8i> -> !cir.vector<1 x !u64i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<1 x !u64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]], <1 x i64> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <8 x i8> [[B_RAW]] to <1 x i64>
|
|
// LLVM: [[RSH:%.*]] = call <1 x i64> @llvm.aarch64.neon.urshl.v1i64(<1 x i64> [[B_CAST]], <1 x i64> splat (i64 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <8 x i8> [[A_RAW]] to <1 x i64>
|
|
// LLVM: [[RES:%.*]] = add <1 x i64> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <1 x i64> [[RES]]
|
|
return vrsra_n_u64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsraq_n_u64(
|
|
uint64x2_t test_vrsraq_n_u64(uint64x2_t a, uint64x2_t b) {
|
|
// CIR: [[C_M1:%.*]] = cir.const #cir.int<-1> : !s64i
|
|
// CIR: [[SHIFT:%.*]] = cir.vec.splat [[C_M1]] : !s64i, !cir.vector<2 x !s64i>
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!cir.vector<2 x !u64i>, !cir.vector<2 x !s64i>) -> !cir.vector<2 x !u64i>
|
|
// CIR: [[A:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s8i> -> !cir.vector<2 x !u64i>
|
|
// CIR: [[RES:%.*]] = cir.add [[A]], [[RSH]] : !cir.vector<2 x !u64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[A_RAW:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[B_RAW:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[B_CAST:%.*]] = bitcast <16 x i8> [[B_RAW]] to <2 x i64>
|
|
// LLVM: [[RSH:%.*]] = call <2 x i64> @llvm.aarch64.neon.urshl.v2i64(<2 x i64> [[B_CAST]], <2 x i64> splat (i64 -1))
|
|
// LLVM: [[A_CAST:%.*]] = bitcast <16 x i8> [[A_RAW]] to <2 x i64>
|
|
// LLVM: [[RES:%.*]] = add <2 x i64> [[A_CAST]], [[RSH]]
|
|
// LLVM: ret <2 x i64> [[RES]]
|
|
return vrsraq_n_u64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsrad_n_s64(
|
|
int64_t test_vrsrad_n_s64(int64_t a, int64_t b) {
|
|
// CIR: [[SHIFT:%.*]] = cir.const #cir.int<-63> : !s64i
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.srshl" %{{.*}}, [[SHIFT]] : (!s64i, !s64i) -> !s64i
|
|
// CIR: [[RES:%.*]] = cir.add %{{.*}}, [[RSH]] : !s64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]], i64 {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[RSH:%.*]] = call i64 @llvm.aarch64.neon.srshl.i64(i64 [[B]], i64 -63)
|
|
// LLVM: [[RES:%.*]] = add i64 [[A]], [[RSH]]
|
|
// LLVM: ret i64 [[RES]]
|
|
return (int64_t)vrsrad_n_s64(a, b, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrsrad_n_u64(
|
|
uint64_t test_vrsrad_n_u64(uint64_t a, uint64_t b) {
|
|
// CIR: [[SHIFT:%.*]] = cir.const #cir.int<-63> : !s64i
|
|
// CIR: [[RSH:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.urshl" %{{.*}}, [[SHIFT]] : (!u64i, !s64i) -> !u64i
|
|
// CIR: [[RES:%.*]] = cir.add %{{.*}}, [[RSH]] : !u64i
|
|
|
|
// LLVM-SAME: i64 {{.*}} [[A:%.*]], i64 {{.*}} [[B:%.*]]) {{.*}} {
|
|
// LLVM: [[RSH:%.*]] = call i64 @llvm.aarch64.neon.urshl.i64(i64 [[B]], i64 -63)
|
|
// LLVM: [[RES:%.*]] = add i64 [[A]], [[RSH]]
|
|
// LLVM: ret i64 [[RES]]
|
|
return (uint64_t)vrsrad_n_u64(a, b, 63);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.13.4. Minimum across vector
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#minimum-across-vector
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vminv_s8(
|
|
// CIR-LABEL: @vminv_s8(
|
|
int8_t test_vminv_s8(int8x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.smin" %{{.*}} : (!cir.vector<8 x !s8i>) -> !s8i
|
|
// CIR: cir.return %{{.*}} : !s8i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_S8_I:%.*]] = call i8 @llvm.vector.reduce.smin.v8i8(<8 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VMINV_S8_I]]
|
|
return vminv_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_s8(
|
|
// CIR-LABEL: @vminvq_s8(
|
|
int8_t test_vminvq_s8(int8x16_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.smin" %{{.*}} : (!cir.vector<16 x !s8i>) -> !s8i
|
|
// CIR: cir.return %{{.*}} : !s8i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_S8_I:%.*]] = call i8 @llvm.vector.reduce.smin.v16i8(<16 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VMINVQ_S8_I]]
|
|
return vminvq_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminv_s16(
|
|
// CIR-LABEL: @vminv_s16(
|
|
int16_t test_vminv_s16(int16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.smin" %{{.*}} : (!cir.vector<4 x !s16i>) -> !s16i
|
|
// CIR: cir.return %{{.*}} : !s16i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_S16_I:%.*]] = call i16 @llvm.vector.reduce.smin.v4i16(<4 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VMINV_S16_I]]
|
|
return vminv_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_s16(
|
|
// CIR-LABEL: @vminvq_s16(
|
|
int16_t test_vminvq_s16(int16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.smin" %{{.*}} : (!cir.vector<8 x !s16i>) -> !s16i
|
|
// CIR: cir.return %{{.*}} : !s16i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_S16_I:%.*]] = call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VMINVQ_S16_I]]
|
|
return vminvq_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminv_s32(
|
|
// CIR-LABEL: @vminv_s32(
|
|
int32_t test_vminv_s32(int32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.smin" %{{.*}} : (!cir.vector<2 x !s32i>) -> !s32i
|
|
// CIR: cir.return %{{.*}} : !s32i
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_S32_I:%.*]] = call i32 @llvm.vector.reduce.smin.v2i32(<2 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VMINV_S32_I]]
|
|
return vminv_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_s32(
|
|
// CIR-LABEL: @vminvq_s32(
|
|
int32_t test_vminvq_s32(int32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.smin" %{{.*}} : (!cir.vector<4 x !s32i>) -> !s32i
|
|
// CIR: cir.return %{{.*}} : !s32i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_S32_I:%.*]] = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VMINVQ_S32_I]]
|
|
return vminvq_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminv_u8(
|
|
// CIR-LABEL: @vminv_u8(
|
|
uint8_t test_vminv_u8(uint8x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.umin" %{{.*}} : (!cir.vector<8 x !u8i>) -> !u8i
|
|
// CIR: cir.return %{{.*}} : !u8i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_U8_I:%.*]] = call i8 @llvm.vector.reduce.umin.v8i8(<8 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VMINV_U8_I]]
|
|
return vminv_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_u8(
|
|
// CIR-LABEL: @vminvq_u8(
|
|
uint8_t test_vminvq_u8(uint8x16_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.umin" %{{.*}} : (!cir.vector<16 x !u8i>) -> !u8i
|
|
// CIR: cir.return %{{.*}} : !u8i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_U8_I:%.*]] = call i8 @llvm.vector.reduce.umin.v16i8(<16 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VMINVQ_U8_I]]
|
|
return vminvq_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminv_u16(
|
|
// CIR-LABEL: @vminv_u16(
|
|
uint16_t test_vminv_u16(uint16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.umin" %{{.*}} : (!cir.vector<4 x !u16i>) -> !u16i
|
|
// CIR: cir.return %{{.*}} : !u16i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_U16_I:%.*]] = call i16 @llvm.vector.reduce.umin.v4i16(<4 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VMINV_U16_I]]
|
|
return vminv_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_u16(
|
|
// CIR-LABEL: @vminvq_u16(
|
|
uint16_t test_vminvq_u16(uint16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.umin" %{{.*}} : (!cir.vector<8 x !u16i>) -> !u16i
|
|
// CIR: cir.return %{{.*}} : !u16i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_U16_I:%.*]] = call i16 @llvm.vector.reduce.umin.v8i16(<8 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VMINVQ_U16_I]]
|
|
return vminvq_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminv_u32(
|
|
// CIR-LABEL: @vminv_u32(
|
|
uint32_t test_vminv_u32(uint32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.umin" %{{.*}} : (!cir.vector<2 x !u32i>) -> !u32i
|
|
// CIR: cir.return %{{.*}} : !u32i
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_U32_I:%.*]] = call i32 @llvm.vector.reduce.umin.v2i32(<2 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VMINV_U32_I]]
|
|
return vminv_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_u32(
|
|
// CIR-LABEL: @vminvq_u32(
|
|
uint32_t test_vminvq_u32(uint32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.umin" %{{.*}} : (!cir.vector<4 x !u32i>) -> !u32i
|
|
// CIR: cir.return %{{.*}} : !u32i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_U32_I:%.*]] = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VMINVQ_U32_I]]
|
|
return vminvq_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminv_f32(
|
|
// CIR-LABEL: @vminv_f32(
|
|
float32_t test_vminv_f32(float32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminv" %{{.*}} : (!cir.vector<2 x !cir.float>) -> !cir.float
|
|
// CIR: cir.return %{{.*}} : !cir.float
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINV_F32_I:%.*]] = call float @llvm.aarch64.neon.fminv.f32.v2f32(<2 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VMINV_F32_I]]
|
|
return vminv_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_f32(
|
|
// CIR-LABEL: @vminvq_f32(
|
|
float32_t test_vminvq_f32(float32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminv" %{{.*}} : (!cir.vector<4 x !cir.float>) -> !cir.float
|
|
// CIR: cir.return %{{.*}} : !cir.float
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fminv.f32.v4f32(<4 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VMINVQ_F32_I]]
|
|
return vminvq_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminvq_f64(
|
|
// CIR-LABEL: @vminvq_f64(
|
|
float64_t test_vminvq_f64(float64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminv" %{{.*}} : (!cir.vector<2 x !cir.double>) -> !cir.double
|
|
// CIR: cir.return %{{.*}} : !cir.double
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINVQ_F64_I:%.*]] = call double @llvm.aarch64.neon.fminv.f64.v2f64(<2 x double> [[A]])
|
|
// LLVM-NEXT: ret double [[VMINVQ_F64_I]]
|
|
return vminvq_f64(a);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.1.13.6. Minimum across vector (IEEE754)
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#markdown-toc-maximum-across-vector-ieee754
|
|
//===------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vminnmv_f32(
|
|
// CIR-LABEL: @vminnmv_f32(
|
|
float32_t test_vminnmv_f32(float32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmv" %{{.*}} : (!cir.vector<2 x !cir.float>) -> !cir.float
|
|
// CIR: cir.return %{{.*}} : !cir.float
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINNMV_F32_I:%.*]] = call float @llvm.aarch64.neon.fminnmv.f32.v2f32(<2 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VMINNMV_F32_I]]
|
|
return vminnmv_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminnmvq_f32(
|
|
// CIR-LABEL: @vminnmvq_f32(
|
|
float32_t test_vminnmvq_f32(float32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmv" %{{.*}} : (!cir.vector<4 x !cir.float>) -> !cir.float
|
|
// CIR: cir.return %{{.*}} : !cir.float
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINNMVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.fminnmv.f32.v4f32(<4 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VMINNMVQ_F32_I]]
|
|
return vminnmvq_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vminnmvq_f64(
|
|
// CIR-LABEL: @vminnmvq_f64(
|
|
float64_t test_vminnmvq_f64(float64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnmv" %{{.*}} : (!cir.vector<2 x !cir.double>) -> !cir.double
|
|
// CIR: cir.return %{{.*}} : !cir.double
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VMINNMVQ_F64_I:%.*]] = call double @llvm.aarch64.neon.fminnmv.f64.v2f64(<2 x double> [[A]])
|
|
// LLVM-NEXT: ret double [[VMINNMVQ_F64_I]]
|
|
return vminnmvq_f64(a);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.3.2.2 Vector rounding shift right
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-rounding-shift-right
|
|
//===----------------------------------------------------------------------===//
|
|
// ALL-LABEL: @test_vrshr_n_s8(
|
|
int8x8_t test_vrshr_n_s8(int8x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VRSHR_N:%.*]] = call <8 x i8> @llvm.aarch64.neon.srshl.v8i8(<8 x i8> [[A]], <8 x i8> splat (i8 -3))
|
|
// LLVM: ret <8 x i8> [[VRSHR_N]]
|
|
return vrshr_n_s8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_s16(
|
|
int16x4_t test_vrshr_n_s16(int16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[VRSHR_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VRSHR_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.srshl.v4i16(<4 x i16> [[VRSHR_N]], <4 x i16> splat (i16 -3))
|
|
// LLVM: ret <4 x i16> [[VRSHR_N1]]
|
|
return vrshr_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_s32(
|
|
int32x2_t test_vrshr_n_s32(int32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// CHECK: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// CHECK: [[VRSHR_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// CHECK: [[VRSHR_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.srshl.v2i32(<2 x i32> [[VRSHR_N]], <2 x i32> splat (i32 -3))
|
|
// CHECK: ret <2 x i32> [[VRSHR_N1]]
|
|
return vrshr_n_s32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_s64(
|
|
int64x1_t test_vrshr_n_s64(int64x1_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// CHECK: [[VRSHR_N:%.*]] = call <16 x i8> @llvm.aarch64.neon.srshl.v16i8(<16 x i8> [[A]], <16 x i8> splat (i8 -3))
|
|
// CHECK: ret <16 x i8> [[VRSHR_N]]
|
|
return vrshr_n_s64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_u8(
|
|
uint8x8_t test_vrshr_n_u8(uint8x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = call <8 x i8> @llvm.aarch64.neon.urshl.v8i8(<8 x i8> [[A]], <8 x i8> splat (i8 -3))
|
|
// CHECK-NEXT: ret <8 x i8> [[VRSHR_N]]
|
|
return vrshr_n_u8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_u16(
|
|
uint16x4_t test_vrshr_n_u16(uint16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <4 x i16> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <4 x i16> @llvm.aarch64.neon.urshl.v4i16(<4 x i16> [[VRSHR_N]], <4 x i16> splat (i16 -3))
|
|
// CHECK-NEXT: ret <4 x i16> [[VRSHR_N1]]
|
|
return vrshr_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_u32(
|
|
uint32x2_t test_vrshr_n_u32(uint32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <2 x i32> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <2 x i32> @llvm.aarch64.neon.urshl.v2i32(<2 x i32> [[VRSHR_N]], <2 x i32> splat (i32 -3))
|
|
// CHECK-NEXT: ret <2 x i32> [[VRSHR_N1]]
|
|
return vrshr_n_u32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshr_n_u64(
|
|
uint64x1_t test_vrshr_n_u64(uint64x1_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <1 x i64> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <1 x i64> @llvm.aarch64.neon.urshl.v1i64(<1 x i64> [[VRSHR_N]], <1 x i64> splat (i64 -1))
|
|
// CHECK-NEXT: ret <1 x i64> [[VRSHR_N1]]
|
|
return vrshr_n_u64(a, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_s8(
|
|
int8x16_t test_vrshrq_n_s8(int8x16_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = call <16 x i8> @llvm.aarch64.neon.srshl.v16i8(<16 x i8> [[A]], <16 x i8> splat (i8 -3))
|
|
// CHECK-NEXT: ret <16 x i8> [[VRSHR_N]]
|
|
return vrshrq_n_s8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_s16(
|
|
int16x8_t test_vrshrq_n_s16(int16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <8 x i16> {{.*}} [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <8 x i16> @llvm.aarch64.neon.srshl.v8i16(<8 x i16> [[VRSHR_N]], <8 x i16> splat (i16 -3))
|
|
// CHECK-NEXT: ret <8 x i16> [[VRSHR_N1]]
|
|
return vrshrq_n_s16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_s32(
|
|
int32x4_t test_vrshrq_n_s32(int32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <4 x i32> @llvm.aarch64.neon.srshl.v4i32(<4 x i32> [[VRSHR_N]], <4 x i32> splat (i32 -3))
|
|
// CHECK-NEXT: ret <4 x i32> [[VRSHR_N1]]
|
|
return vrshrq_n_s32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_s64(
|
|
int64x2_t test_vrshrq_n_s64(int64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <2 x i64> @llvm.aarch64.neon.srshl.v2i64(<2 x i64> [[VRSHR_N]], <2 x i64> splat (i64 -3))
|
|
// CHECK-NEXT: ret <2 x i64> [[VRSHR_N1]]
|
|
return vrshrq_n_s64(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_u8(
|
|
uint8x16_t test_vrshrq_n_u8(uint8x16_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = call <16 x i8> @llvm.aarch64.neon.urshl.v16i8(<16 x i8> [[A]], <16 x i8> splat (i8 -3))
|
|
// CHECK-NEXT: ret <16 x i8> [[VRSHR_N]]
|
|
return vrshrq_n_u8(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_u16(
|
|
uint16x8_t test_vrshrq_n_u16(uint16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <8 x i16> @llvm.aarch64.neon.urshl.v8i16(<8 x i16> [[VRSHR_N]], <8 x i16> splat (i16 -3))
|
|
// CHECK-NEXT: ret <8 x i16> [[VRSHR_N1]]
|
|
return vrshrq_n_u16(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_u32(
|
|
uint32x4_t test_vrshrq_n_u32(uint32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// CHECK-NEXT: ret <4 x i32> [[VRSHR_N1]]
|
|
return vrshrq_n_u32(a, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrq_n_u64(
|
|
uint64x2_t test_vrshrq_n_u64(uint64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// CHECK-NEXT: [[VRSHR_N1:%.*]] = call <2 x i64> @llvm.aarch64.neon.urshl.v2i64(<2 x i64> [[VRSHR_N]], <2 x i64> splat (i64 -3))
|
|
// CHECK-NEXT: ret <2 x i64> [[VRSHR_N1]]
|
|
return vrshrq_n_u64(a, 3);
|
|
}
|
|
|
|
// vrshrd_n_* (scalar 64-bit)
|
|
// ALL-LABEL: @test_vrshrd_n_s64(
|
|
int64_t test_vrshrd_n_s64(int64_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.srshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: i64 {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = call i64 @llvm.aarch64.neon.srshl.i64(i64 [[A]], i64 -63)
|
|
// CHECK-NEXT: ret i64 [[VRSHR_N]]
|
|
return (int64_t)vrshrd_n_s64(a, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vrshrd_n_u64(
|
|
uint64_t test_vrshrd_n_u64(uint64_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.urshl" {{%.*}}, {{%.*}}
|
|
|
|
// CHECK-SAME: i64 {{.*}} [[A:%.*]])
|
|
// CHECK-NEXT: [[VRSHR_N:%.*]] = call i64 @llvm.aarch64.neon.urshl.i64(i64 [[A]], i64 -63)
|
|
return (uint64_t)vrshrd_n_u64(a, 63);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.1.13.1 Addition across vector
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#addition-across-vector
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vaddv_s8(
|
|
// CIR-LABEL: @vaddv_s8(
|
|
int8_t test_vaddv_s8(int8x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<8 x !s8i>) -> !s8i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_I:%.*]] = call i8 @llvm.vector.reduce.add.v8i8(<8 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VADDV_I]]
|
|
return vaddv_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_s8(
|
|
// CIR-LABEL: @vaddvq_s8(
|
|
int8_t test_vaddvq_s8(int8x16_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<16 x !s8i>) -> !s8i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i8 @llvm.vector.reduce.add.v16i8(<16 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VADDVQ_I]]
|
|
return vaddvq_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddv_s16(
|
|
// CIR-LABEL: @vaddv_s16(
|
|
int16_t test_vaddv_s16(int16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<4 x !s16i>) -> !s16i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_I:%.*]] = call i16 @llvm.vector.reduce.add.v4i16(<4 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VADDV_I]]
|
|
return vaddv_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_s16(
|
|
// CIR-LABEL: @vaddvq_s16(
|
|
int16_t test_vaddvq_s16(int16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<8 x !s16i>) -> !s16i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VADDVQ_I]]
|
|
return vaddvq_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddv_s32(
|
|
// CIR-LABEL: @vaddv_s32(
|
|
int32_t test_vaddv_s32(int32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<2 x !s32i>) -> !s32i
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_I:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDV_I]]
|
|
return vaddv_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_s32(
|
|
// CIR-LABEL: @vaddvq_s32(
|
|
int32_t test_vaddvq_s32(int32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<4 x !s32i>) -> !s32i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDVQ_I]]
|
|
return vaddvq_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_s64(
|
|
// CIR-LABEL: @vaddvq_s64(
|
|
int64_t test_vaddvq_s64(int64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<2 x !s64i>) -> !s64i
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> [[A]])
|
|
// LLVM-NEXT: ret i64 [[VADDVQ_I]]
|
|
return vaddvq_s64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddv_u8(
|
|
// CIR-LABEL: @vaddv_u8(
|
|
uint8_t test_vaddv_u8(uint8x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<8 x !u8i>) -> !u8i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_I:%.*]] = call i8 @llvm.vector.reduce.add.v8i8(<8 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VADDV_I]]
|
|
return vaddv_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_u8(
|
|
// CIR-LABEL: @vaddvq_u8(
|
|
uint8_t test_vaddvq_u8(uint8x16_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<16 x !u8i>) -> !u8i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i8 @llvm.vector.reduce.add.v16i8(<16 x i8> [[A]])
|
|
// LLVM-NEXT: ret i8 [[VADDVQ_I]]
|
|
return vaddvq_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddv_u16(
|
|
// CIR-LABEL: @vaddv_u16(
|
|
uint16_t test_vaddv_u16(uint16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<4 x !u16i>) -> !u16i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_I:%.*]] = call i16 @llvm.vector.reduce.add.v4i16(<4 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VADDV_I]]
|
|
return vaddv_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_u16(
|
|
// CIR-LABEL: @vaddvq_u16(
|
|
uint16_t test_vaddvq_u16(uint16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<8 x !u16i>) -> !u16i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> [[A]])
|
|
// LLVM-NEXT: ret i16 [[VADDVQ_I]]
|
|
return vaddvq_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddv_u32(
|
|
// CIR-LABEL: @vaddv_u32(
|
|
uint32_t test_vaddv_u32(uint32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<2 x !u32i>) -> !u32i
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_I:%.*]] = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDV_I]]
|
|
return vaddv_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_u32(
|
|
// CIR-LABEL: @vaddvq_u32(
|
|
uint32_t test_vaddvq_u32(uint32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<4 x !u32i>) -> !u32i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDVQ_I]]
|
|
return vaddvq_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_u64(
|
|
// CIR-LABEL: @vaddvq_u64(
|
|
uint64_t test_vaddvq_u64(uint64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "vector.reduce.add" %{{.*}} : (!cir.vector<2 x !u64i>) -> !u64i
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_I:%.*]] = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> [[A]])
|
|
// LLVM-NEXT: ret i64 [[VADDVQ_I]]
|
|
return vaddvq_u64(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddv_f32(
|
|
// CIR-LABEL: @vaddv_f32(
|
|
float32_t test_vaddv_f32(float32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.faddv" %{{.*}} : (!cir.vector<2 x !cir.float>) -> !cir.float
|
|
|
|
// LLVM-SAME: <2 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDV_F32_I:%.*]] = call float @llvm.aarch64.neon.faddv.f32.v2f32(<2 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VADDV_F32_I]]
|
|
return vaddv_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_f32(
|
|
// CIR-LABEL: @vaddvq_f32(
|
|
float32_t test_vaddvq_f32(float32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.faddv" %{{.*}} : (!cir.vector<4 x !cir.float>) -> !cir.float
|
|
|
|
// LLVM-SAME: <4 x float> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_F32_I:%.*]] = call float @llvm.aarch64.neon.faddv.f32.v4f32(<4 x float> [[A]])
|
|
// LLVM-NEXT: ret float [[VADDVQ_F32_I]]
|
|
return vaddvq_f32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddvq_f64(
|
|
// CIR-LABEL: @vaddvq_f64(
|
|
float64_t test_vaddvq_f64(float64x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.faddv" %{{.*}} : (!cir.vector<2 x !cir.double>) -> !cir.double
|
|
|
|
// LLVM-SAME: <2 x double> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDVQ_F64_I:%.*]] = call double @llvm.aarch64.neon.faddv.f64.v2f64(<2 x double> [[A]])
|
|
// LLVM-NEXT: ret double [[VADDVQ_F64_I]]
|
|
return vaddvq_f64(a);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 2.1.1.13.2 Addition across vector widening
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#addition-across-vector-widening
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLVM-LABEL: @test_vaddlv_s8(
|
|
// CIR-LABEL: @vaddlv_s8(
|
|
int16_t test_vaddlv_s8(int8x8_t a) {
|
|
// CIR: [[VADDLV_I:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.saddlv" %{{.*}} : (!cir.vector<8 x !s8i>) -> !s32i
|
|
// CIR: cir.cast integral [[VADDLV_I]] : !s32i -> !s16i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i8(<8 x i8> [[A]])
|
|
// LLVM-NEXT: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
|
|
// LLVM-NEXT: ret i16 [[TMP0]]
|
|
return vaddlv_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlv_s16(
|
|
// CIR-LABEL: @vaddlv_s16(
|
|
int32_t test_vaddlv_s16(int16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.saddlv" %{{.*}} : (!cir.vector<4 x !s16i>) -> !s32i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v4i16(<4 x i16> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDLV_I]]
|
|
return vaddlv_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlv_s32(
|
|
// CIR-LABEL: @vaddlv_s32(
|
|
int64_t test_vaddlv_s32(int32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.saddlv" %{{.*}} : (!cir.vector<2 x !s32i>) -> !s64i
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_S32_I:%.*]] = call i64 @llvm.aarch64.neon.saddlv.i64.v2i32(<2 x i32> [[A]])
|
|
// LLVM-NEXT: ret i64 [[VADDLV_S32_I]]
|
|
return vaddlv_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlv_u8(
|
|
// CIR-LABEL: @vaddlv_u8(
|
|
uint16_t test_vaddlv_u8(uint8x8_t a) {
|
|
// CIR: [[VADDLV_I:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.uaddlv" %{{.*}} : (!cir.vector<8 x !u8i>) -> !u32i
|
|
// CIR: cir.cast integral [[VADDLV_I]] : !u32i -> !u16i
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i8(<8 x i8> [[A]])
|
|
// LLVM-NEXT: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
|
|
// LLVM-NEXT: ret i16 [[TMP0]]
|
|
return vaddlv_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlv_u16(
|
|
// CIR-LABEL: @vaddlv_u16(
|
|
uint32_t test_vaddlv_u16(uint16x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uaddlv" %{{.*}} : (!cir.vector<4 x !u16i>) -> !u32i
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v4i16(<4 x i16> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDLV_I]]
|
|
return vaddlv_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlv_u32(
|
|
// CIR-LABEL: @vaddlv_u32(
|
|
uint64_t test_vaddlv_u32(uint32x2_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uaddlv" %{{.*}} : (!cir.vector<2 x !u32i>) -> !u64i
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_U32_I:%.*]] = call i64 @llvm.aarch64.neon.uaddlv.i64.v2i32(<2 x i32> [[A]])
|
|
// LLVM-NEXT: ret i64 [[VADDLV_U32_I]]
|
|
return vaddlv_u32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlvq_s8(
|
|
// CIR-LABEL: @vaddlvq_s8(
|
|
int16_t test_vaddlvq_s8(int8x16_t a) {
|
|
// CIR: [[VADDLV_I:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.saddlv" %{{.*}} : (!cir.vector<16 x !s8i>) -> !s32i
|
|
// CIR: cir.cast integral [[VADDLV_I]] : !s32i -> !s16i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v16i8(<16 x i8> [[A]])
|
|
// LLVM-NEXT: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
|
|
// LLVM-NEXT: ret i16 [[TMP0]]
|
|
return vaddlvq_s8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlvq_s16(
|
|
// CIR-LABEL: @vaddlvq_s16(
|
|
int32_t test_vaddlvq_s16(int16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.saddlv" %{{.*}} : (!cir.vector<8 x !s16i>) -> !s32i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.saddlv.i32.v8i16(<8 x i16> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDLV_I]]
|
|
return vaddlvq_s16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlvq_s32(
|
|
// CIR-LABEL: @vaddlvq_s32(
|
|
int64_t test_vaddlvq_s32(int32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.saddlv" %{{.*}} : (!cir.vector<4 x !s32i>) -> !s64i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLVQ_S32_I:%.*]] = call i64 @llvm.aarch64.neon.saddlv.i64.v4i32(<4 x i32> [[A]])
|
|
// LLVM-NEXT: ret i64 [[VADDLVQ_S32_I]]
|
|
return vaddlvq_s32(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlvq_u8(
|
|
// CIR-LABEL: @vaddlvq_u8(
|
|
uint16_t test_vaddlvq_u8(uint8x16_t a) {
|
|
// CIR: [[VADDLV_I:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.uaddlv" %{{.*}} : (!cir.vector<16 x !u8i>) -> !u32i
|
|
// CIR: cir.cast integral [[VADDLV_I]] : !u32i -> !u16i
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v16i8(<16 x i8> [[A]])
|
|
// LLVM-NEXT: [[TMP0:%.*]] = trunc i32 [[VADDLV_I]] to i16
|
|
// LLVM-NEXT: ret i16 [[TMP0]]
|
|
return vaddlvq_u8(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlvq_u16(
|
|
// CIR-LABEL: @vaddlvq_u16(
|
|
uint32_t test_vaddlvq_u16(uint16x8_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uaddlv" %{{.*}} : (!cir.vector<8 x !u16i>) -> !u32i
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLV_I:%.*]] = call i32 @llvm.aarch64.neon.uaddlv.i32.v8i16(<8 x i16> [[A]])
|
|
// LLVM-NEXT: ret i32 [[VADDLV_I]]
|
|
return vaddlvq_u16(a);
|
|
}
|
|
|
|
// LLVM-LABEL: @test_vaddlvq_u32(
|
|
// CIR-LABEL: @vaddlvq_u32(
|
|
uint64_t test_vaddlvq_u32(uint32x4_t a) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.uaddlv" %{{.*}} : (!cir.vector<4 x !u32i>) -> !u64i
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]])
|
|
// LLVM: [[VADDLVQ_U32_I:%.*]] = call i64 @llvm.aarch64.neon.uaddlv.i64.v4i32(<4 x i32> [[A]])
|
|
// LLVM-NEXT: ret i64 [[VADDLVQ_U32_I]]
|
|
return vaddlvq_u32(a);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.1.6. Vector shift left and insert
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-shift-left-and-insert
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vsli_n_s8(
|
|
int8x8_t test_vsli_n_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>, !s32i) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VSLI:%.*]] = call <8 x i8> @llvm.aarch64.neon.vsli.v8i8(<8 x i8> [[A]], <8 x i8> [[B]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VSLI]]
|
|
return vsli_n_s8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_s8(
|
|
int8x16_t test_vsliq_n_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>, !s32i) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VSLI:%.*]] = call <16 x i8> @llvm.aarch64.neon.vsli.v16i8(<16 x i8> [[A]], <16 x i8> [[B]], i32 3)
|
|
// LLVM: ret <16 x i8> [[VSLI]]
|
|
return vsliq_n_s8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_s16(
|
|
int16x4_t test_vsli_n_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>, !s32i) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VSLI:%.*]] = call <4 x i16> @llvm.aarch64.neon.vsli.v4i16(<4 x i16> [[VSLI_N]], <4 x i16> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <4 x i16> [[VSLI]]
|
|
return vsli_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_s16(
|
|
int16x8_t test_vsliq_n_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>, !s32i) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VSLI:%.*]] = call <8 x i16> @llvm.aarch64.neon.vsli.v8i16(<8 x i16> [[VSLI_N]], <8 x i16> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <8 x i16> [[VSLI]]
|
|
return vsliq_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_s32(
|
|
int32x2_t test_vsli_n_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<2 x !s32i>, !cir.vector<2 x !s32i>, !s32i) -> !cir.vector<2 x !s32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VSLI:%.*]] = call <2 x i32> @llvm.aarch64.neon.vsli.v2i32(<2 x i32> [[VSLI_N]], <2 x i32> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <2 x i32> [[VSLI]]
|
|
return vsli_n_s32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_s32(
|
|
int32x4_t test_vsliq_n_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>, !s32i) -> !cir.vector<4 x !s32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VSLI:%.*]] = call <4 x i32> @llvm.aarch64.neon.vsli.v4i32(<4 x i32> [[VSLI_N]], <4 x i32> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <4 x i32> [[VSLI]]
|
|
return vsliq_n_s32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_s64(
|
|
int64x1_t test_vsli_n_s64(int64x1_t a, int64x1_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<1 x !s64i>, !cir.vector<1 x !s64i>, !s32i) -> !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]], <1 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VSLI:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsli.v1i64(<1 x i64> [[VSLI_N]], <1 x i64> [[VSLI_N1]], i32 1)
|
|
// LLVM: ret <1 x i64> [[VSLI]]
|
|
return vsli_n_s64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_s64(
|
|
int64x2_t test_vsliq_n_s64(int64x2_t a, int64x2_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !s32i) -> !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VSLI:%.*]] = call <2 x i64> @llvm.aarch64.neon.vsli.v2i64(<2 x i64> [[VSLI_N]], <2 x i64> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <2 x i64> [[VSLI]]
|
|
return vsliq_n_s64(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_u8(
|
|
uint8x8_t test_vsli_n_u8(uint8x8_t a, uint8x8_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<8 x !u8i>, !cir.vector<8 x !u8i>, !s32i) -> !cir.vector<8 x !u8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VSLI:%.*]] = call <8 x i8> @llvm.aarch64.neon.vsli.v8i8(<8 x i8> [[A]], <8 x i8> [[B]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VSLI]]
|
|
return vsli_n_u8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_u8(
|
|
uint8x16_t test_vsliq_n_u8(uint8x16_t a, uint8x16_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<16 x !u8i>, !cir.vector<16 x !u8i>, !s32i) -> !cir.vector<16 x !u8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VSLI:%.*]] = call <16 x i8> @llvm.aarch64.neon.vsli.v16i8(<16 x i8> [[A]], <16 x i8> [[B]], i32 3)
|
|
// LLVM: ret <16 x i8> [[VSLI]]
|
|
return vsliq_n_u8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_u16(
|
|
uint16x4_t test_vsli_n_u16(uint16x4_t a, uint16x4_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<4 x !u16i>, !cir.vector<4 x !u16i>, !s32i) -> !cir.vector<4 x !u16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VSLI:%.*]] = call <4 x i16> @llvm.aarch64.neon.vsli.v4i16(<4 x i16> [[VSLI_N]], <4 x i16> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <4 x i16> [[VSLI]]
|
|
return vsli_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_u16(
|
|
uint16x8_t test_vsliq_n_u16(uint16x8_t a, uint16x8_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<8 x !u16i>, !cir.vector<8 x !u16i>, !s32i) -> !cir.vector<8 x !u16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VSLI:%.*]] = call <8 x i16> @llvm.aarch64.neon.vsli.v8i16(<8 x i16> [[VSLI_N]], <8 x i16> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <8 x i16> [[VSLI]]
|
|
return vsliq_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_u32(
|
|
uint32x2_t test_vsli_n_u32(uint32x2_t a, uint32x2_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<2 x !u32i>, !cir.vector<2 x !u32i>, !s32i) -> !cir.vector<2 x !u32i>
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}} [[A:%.*]], <2 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM: [[VSLI:%.*]] = call <2 x i32> @llvm.aarch64.neon.vsli.v2i32(<2 x i32> [[VSLI_N]], <2 x i32> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <2 x i32> [[VSLI]]
|
|
return vsli_n_u32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_u32(
|
|
uint32x4_t test_vsliq_n_u32(uint32x4_t a, uint32x4_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<4 x !u32i>, !cir.vector<4 x !u32i>, !s32i) -> !cir.vector<4 x !u32i>
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}} [[A:%.*]], <4 x i32> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM: [[VSLI:%.*]] = call <4 x i32> @llvm.aarch64.neon.vsli.v4i32(<4 x i32> [[VSLI_N]], <4 x i32> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <4 x i32> [[VSLI]]
|
|
return vsliq_n_u32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_u64(
|
|
uint64x1_t test_vsli_n_u64(uint64x1_t a, uint64x1_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<1 x !u64i>, !cir.vector<1 x !u64i>, !s32i) -> !cir.vector<1 x !u64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]], <1 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VSLI:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsli.v1i64(<1 x i64> [[VSLI_N]], <1 x i64> [[VSLI_N1]], i32 1)
|
|
// LLVM: ret <1 x i64> [[VSLI]]
|
|
return vsli_n_u64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_u64(
|
|
uint64x2_t test_vsliq_n_u64(uint64x2_t a, uint64x2_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !s32i) -> !cir.vector<2 x !u64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VSLI:%.*]] = call <2 x i64> @llvm.aarch64.neon.vsli.v2i64(<2 x i64> [[VSLI_N]], <2 x i64> [[VSLI_N1]], i32 3)
|
|
// LLVM: ret <2 x i64> [[VSLI]]
|
|
return vsliq_n_u64(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_p64(
|
|
poly64x1_t test_vsli_n_p64(poly64x1_t a, poly64x1_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<1 x !s64i>, !cir.vector<1 x !s64i>, !s32i) -> !cir.vector<1 x !s64i>
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}} [[A:%.*]], <1 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM: [[VSLI:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsli.v1i64(<1 x i64> [[VSLI_N]], <1 x i64> [[VSLI_N1]], i32 0)
|
|
// LLVM: ret <1 x i64> [[VSLI]]
|
|
return vsli_n_p64(a, b, 0);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_p64(
|
|
poly64x2_t test_vsliq_n_p64(poly64x2_t a, poly64x2_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !s32i) -> !cir.vector<2 x !s64i>
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}} [[A:%.*]], <2 x i64> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM: [[VSLI:%.*]] = call <2 x i64> @llvm.aarch64.neon.vsli.v2i64(<2 x i64> [[VSLI_N]], <2 x i64> [[VSLI_N1]], i32 0)
|
|
// LLVM: ret <2 x i64> [[VSLI]]
|
|
return vsliq_n_p64(a, b, 0);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_p8(
|
|
poly8x8_t test_vsli_n_p8(poly8x8_t a, poly8x8_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<8 x !s8i>, !cir.vector<8 x !s8i>, !s32i) -> !cir.vector<8 x !s8i>
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}} [[A:%.*]], <8 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VSLI:%.*]] = call <8 x i8> @llvm.aarch64.neon.vsli.v8i8(<8 x i8> [[A]], <8 x i8> [[B]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VSLI]]
|
|
return vsli_n_p8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_p8(
|
|
poly8x16_t test_vsliq_n_p8(poly8x16_t a, poly8x16_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<16 x !s8i>, !cir.vector<16 x !s8i>, !s32i) -> !cir.vector<16 x !s8i>
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}} [[A:%.*]], <16 x i8> {{.*}} [[B:%.*]])
|
|
// LLVM: [[VSLI:%.*]] = call <16 x i8> @llvm.aarch64.neon.vsli.v16i8(<16 x i8> [[A]], <16 x i8> [[B]], i32 3)
|
|
// LLVM: ret <16 x i8> [[VSLI]]
|
|
return vsliq_n_p8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsli_n_p16(
|
|
poly16x4_t test_vsli_n_p16(poly16x4_t a, poly16x4_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<4 x !s16i>, !cir.vector<4 x !s16i>, !s32i) -> !cir.vector<4 x !s16i>
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}} [[A:%.*]], <4 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM: [[VSLI:%.*]] = call <4 x i16> @llvm.aarch64.neon.vsli.v4i16(<4 x i16> [[VSLI_N]], <4 x i16> [[VSLI_N1]], i32 15)
|
|
// LLVM: ret <4 x i16> [[VSLI]]
|
|
return vsli_n_p16(a, b, 15);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsliq_n_p16(
|
|
poly16x8_t test_vsliq_n_p16(poly16x8_t a, poly16x8_t b) {
|
|
// CIR: [[VSLI:%.*]] = cir.call_llvm_intrinsic "aarch64.neon.vsli" %{{.*}}, %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>, !s32i) -> !cir.vector<8 x !s16i>
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}} [[A:%.*]], <8 x i16> {{.*}} [[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM: [[VSLI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM: [[VSLI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM: [[VSLI:%.*]] = call <8 x i16> @llvm.aarch64.neon.vsli.v8i16(<8 x i16> [[VSLI_N]], <8 x i16> [[VSLI_N1]], i32 15)
|
|
// LLVM: ret <8 x i16> [[VSLI]]
|
|
return vsliq_n_p16(a, b, 15);
|
|
}
|
|
|
|
//===------------------------------------------------------===//
|
|
// 2.1.3.2.9 Vector Shift Right and Insert
|
|
// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-shift-right-and-insert
|
|
//===------------------------------------------------------===//
|
|
|
|
// ALL-LABEL: @test_vsri_n_s8(
|
|
int8x8_t test_vsri_n_s8(int8x8_t a, int8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]], <8 x i8> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[VSRI_N:%.*]] = call <8 x i8> @llvm.aarch64.neon.vsri.v8i8(<8 x i8> [[A]], <8 x i8> [[B]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VSRI_N]]
|
|
return vsri_n_s8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_s16(
|
|
int16x4_t test_vsri_n_s16(int16x4_t a, int16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]], <4 x i16> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <4 x i16> @llvm.aarch64.neon.vsri.v4i16(<4 x i16> [[VSRI_N]], <4 x i16> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <4 x i16> [[VSRI_N2]]
|
|
return vsri_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_s32(
|
|
int32x2_t test_vsri_n_s32(int32x2_t a, int32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}}[[A:%.*]], <2 x i32> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <2 x i32> @llvm.aarch64.neon.vsri.v2i32(<2 x i32> [[VSRI_N]], <2 x i32> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <2 x i32> [[VSRI_N2]]
|
|
return vsri_n_s32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_s8(
|
|
int8x16_t test_vsriq_n_s8(int8x16_t a, int8x16_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]], <16 x i8> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[VSRI_N:%.*]] = call <16 x i8> @llvm.aarch64.neon.vsri.v16i8(<16 x i8> [[A]], <16 x i8> [[B]], i32 3)
|
|
// LLVM: ret <16 x i8> [[VSRI_N]]
|
|
return vsriq_n_s8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_s16(
|
|
int16x8_t test_vsriq_n_s16(int16x8_t a, int16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]], <8 x i16> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <8 x i16> @llvm.aarch64.neon.vsri.v8i16(<8 x i16> [[VSRI_N]], <8 x i16> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <8 x i16> [[VSRI_N2]]
|
|
return vsriq_n_s16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_s32(
|
|
int32x4_t test_vsriq_n_s32(int32x4_t a, int32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}}[[A:%.*]], <4 x i32> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <4 x i32> @llvm.aarch64.neon.vsri.v4i32(<4 x i32> [[VSRI_N]], <4 x i32> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <4 x i32> [[VSRI_N2]]
|
|
return vsriq_n_s32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_s64(
|
|
int64x2_t test_vsriq_n_s64(int64x2_t a, int64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}}[[A:%.*]], <2 x i64> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <2 x i64> @llvm.aarch64.neon.vsri.v2i64(<2 x i64> [[VSRI_N]], <2 x i64> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <2 x i64> [[VSRI_N2]]
|
|
return vsriq_n_s64(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_u8(
|
|
uint8x8_t test_vsri_n_u8(uint8x8_t a, uint8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]], <8 x i8> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[VSRI_N:%.*]] = call <8 x i8> @llvm.aarch64.neon.vsri.v8i8(<8 x i8> [[A]], <8 x i8> [[B]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VSRI_N]]
|
|
return vsri_n_u8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_u16(
|
|
uint16x4_t test_vsri_n_u16(uint16x4_t a, uint16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]], <4 x i16> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <4 x i16> @llvm.aarch64.neon.vsri.v4i16(<4 x i16> [[VSRI_N]], <4 x i16> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <4 x i16> [[VSRI_N2]]
|
|
return vsri_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_u32(
|
|
uint32x2_t test_vsri_n_u32(uint32x2_t a, uint32x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <2 x i32> {{.*}}[[A:%.*]], <2 x i32> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i32> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <2 x i32>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x i32>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <2 x i32> @llvm.aarch64.neon.vsri.v2i32(<2 x i32> [[VSRI_N]], <2 x i32> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <2 x i32> [[VSRI_N2]]
|
|
return vsri_n_u32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_u8(
|
|
uint8x16_t test_vsriq_n_u8(uint8x16_t a, uint8x16_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]], <16 x i8> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[VSRI_N:%.*]] = call <16 x i8> @llvm.aarch64.neon.vsri.v16i8(<16 x i8> [[A]], <16 x i8> [[B]], i32 3)
|
|
// LLVM: ret <16 x i8> [[VSRI_N]]
|
|
return vsriq_n_u8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_u16(
|
|
uint16x8_t test_vsriq_n_u16(uint16x8_t a, uint16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]], <8 x i16> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <8 x i16> @llvm.aarch64.neon.vsri.v8i16(<8 x i16> [[VSRI_N]], <8 x i16> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <8 x i16> [[VSRI_N2]]
|
|
return vsriq_n_u16(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_u32(
|
|
uint32x4_t test_vsriq_n_u32(uint32x4_t a, uint32x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <4 x i32> {{.*}}[[A:%.*]], <4 x i32> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <4 x i32>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x i32>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <4 x i32> @llvm.aarch64.neon.vsri.v4i32(<4 x i32> [[VSRI_N]], <4 x i32> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <4 x i32> [[VSRI_N2]]
|
|
return vsriq_n_u32(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_u64(
|
|
uint64x2_t test_vsriq_n_u64(uint64x2_t a, uint64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}}[[A:%.*]], <2 x i64> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <2 x i64> @llvm.aarch64.neon.vsri.v2i64(<2 x i64> [[VSRI_N]], <2 x i64> [[VSRI_N1]], i32 3)
|
|
// LLVM: ret <2 x i64> [[VSRI_N2]]
|
|
return vsriq_n_u64(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_p8(
|
|
poly8x8_t test_vsri_n_p8(poly8x8_t a, poly8x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <8 x i8> {{.*}}[[A:%.*]], <8 x i8> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[VSRI_N:%.*]] = call <8 x i8> @llvm.aarch64.neon.vsri.v8i8(<8 x i8> [[A]], <8 x i8> [[B]], i32 3)
|
|
// LLVM: ret <8 x i8> [[VSRI_N]]
|
|
return vsri_n_p8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_p16(
|
|
poly16x4_t test_vsri_n_p16(poly16x4_t a, poly16x4_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <4 x i16> {{.*}}[[A:%.*]], <4 x i16> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <4 x i16> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x i16>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <4 x i16> @llvm.aarch64.neon.vsri.v4i16(<4 x i16> [[VSRI_N]], <4 x i16> [[VSRI_N1]], i32 15)
|
|
// LLVM: ret <4 x i16> [[VSRI_N2]]
|
|
return vsri_n_p16(a, b, 15);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_p8(
|
|
poly8x16_t test_vsriq_n_p8(poly8x16_t a, poly8x16_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <16 x i8> {{.*}}[[A:%.*]], <16 x i8> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[VSRI_N:%.*]] = call <16 x i8> @llvm.aarch64.neon.vsri.v16i8(<16 x i8> [[A]], <16 x i8> [[B]], i32 3)
|
|
// LLVM: ret <16 x i8> [[VSRI_N]]
|
|
return vsriq_n_p8(a, b, 3);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_p16(
|
|
poly16x8_t test_vsriq_n_p16(poly16x8_t a, poly16x8_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <8 x i16> {{.*}}[[A:%.*]], <8 x i16> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x i16>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <8 x i16> @llvm.aarch64.neon.vsri.v8i16(<8 x i16> [[VSRI_N]], <8 x i16> [[VSRI_N1]], i32 15)
|
|
// LLVM: ret <8 x i16> [[VSRI_N2]]
|
|
return vsriq_n_p16(a, b, 15);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsrid_n_s64(
|
|
int64_t test_vsrid_n_s64(int64_t a, int64_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]], i64 {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[T0:%.*]] = bitcast i64 [[A]] to <1 x i64>
|
|
// LLVM-NEXT: [[T1:%.*]] = bitcast i64 [[B]] to <1 x i64>
|
|
// LLVM-NEXT: [[T2:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsri.v1i64(<1 x i64> [[T0]], <1 x i64> [[T1]], i32 63)
|
|
// LLVM-NEXT: [[T3:%.*]] = bitcast <1 x i64> [[T2]] to i64
|
|
// LLVM: ret i64 [[T3]]
|
|
return (int64_t)vsrid_n_s64(a, b, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_s64(
|
|
int64x1_t test_vsri_n_s64(int64x1_t a, int64x1_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}}[[A:%.*]], <1 x i64> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsri.v1i64(<1 x i64> [[VSRI_N]], <1 x i64> [[VSRI_N1]], i32 1)
|
|
// LLVM: ret <1 x i64> [[VSRI_N2]]
|
|
return vsri_n_s64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsrid_n_u64(
|
|
uint64_t test_vsrid_n_u64(uint64_t a, uint64_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: i64 {{.*}}[[A:%.*]], i64 {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[T0:%.*]] = bitcast i64 [[A]] to <1 x i64>
|
|
// LLVM-NEXT: [[T1:%.*]] = bitcast i64 [[B]] to <1 x i64>
|
|
// LLVM-NEXT: [[T2:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsri.v1i64(<1 x i64> [[T0]], <1 x i64> [[T1]], i32 63)
|
|
// LLVM-NEXT: [[T3:%.*]] = bitcast <1 x i64> [[T2]] to i64
|
|
// LLVM: ret i64 [[T3]]
|
|
return (uint64_t)vsrid_n_u64(a, b, 63);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_u64(
|
|
uint64x1_t test_vsri_n_u64(uint64x1_t a, uint64x1_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}}[[A:%.*]], <1 x i64> {{.*}}[[B:%.*]]) {{.*}} {
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsri.v1i64(<1 x i64> [[VSRI_N]], <1 x i64> [[VSRI_N1]], i32 1)
|
|
// LLVM: ret <1 x i64> [[VSRI_N2]]
|
|
return vsri_n_u64(a, b, 1);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsri_n_p64(
|
|
poly64x1_t test_vsri_n_p64(poly64x1_t a, poly64x1_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <1 x i64> {{.*}}[[A:%.*]], <1 x i64> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <1 x i64> [[A]] to <8 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[B]] to <8 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <8 x i8> [[TMP0]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <8 x i8> [[TMP1]] to <1 x i64>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <1 x i64> @llvm.aarch64.neon.vsri.v1i64(<1 x i64> [[VSRI_N]], <1 x i64> [[VSRI_N1]], i32 33)
|
|
// LLVM: ret <1 x i64> [[VSRI_N2]]
|
|
return vsri_n_p64(a, b, 33);
|
|
}
|
|
|
|
// ALL-LABEL: @test_vsriq_n_p64(
|
|
poly64x2_t test_vsriq_n_p64(poly64x2_t a, poly64x2_t b) {
|
|
// CIR: cir.call_llvm_intrinsic "aarch64.neon.vsri"
|
|
|
|
// LLVM-SAME: <2 x i64> {{.*}}[[A:%.*]], <2 x i64> {{.*}}[[B:%.*]])
|
|
// LLVM: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to <16 x i8>
|
|
// LLVM-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[B]] to <16 x i8>
|
|
// LLVM-NEXT: [[VSRI_N:%.*]] = bitcast <16 x i8> [[TMP0]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRI_N1:%.*]] = bitcast <16 x i8> [[TMP1]] to <2 x i64>
|
|
// LLVM-NEXT: [[VSRI_N2:%.*]] = call <2 x i64> @llvm.aarch64.neon.vsri.v2i64(<2 x i64> [[VSRI_N]], <2 x i64> [[VSRI_N1]], i32 64)
|
|
// LLVM: ret <2 x i64> [[VSRI_N2]]
|
|
return vsriq_n_p64(a, b, 64);
|
|
}
|