
Currently arm_neon.h emits C-style casts to do vector type casts. This relies on implicit conversion between vector types to be enabled, which is currently deprecated behaviour and soon will disappear. To ensure NEON code will keep working afterwards, this patch changes all this vector type casts into bitcasts. Co-authored-by: Momchil Velikov <momchil.velikov@arm.com>
216 lines
10 KiB
C
216 lines
10 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature
|
|
// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg,sroa | FileCheck %s
|
|
|
|
// REQUIRES: aarch64-registered-target || arm-registered-target
|
|
|
|
#include <arm_neon.h>
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvta_s32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTA_S32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTA_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtas.v2i32.v2f32(<2 x float> [[VCVTA_S32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTA_S32_V1_I]]
|
|
//
|
|
int32x2_t test_vcvta_s32_f32(float32x2_t a) {
|
|
return vcvta_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvta_u32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTA_U32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTA_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtau.v2i32.v2f32(<2 x float> [[VCVTA_U32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTA_U32_V1_I]]
|
|
//
|
|
uint32x2_t test_vcvta_u32_f32(float32x2_t a) {
|
|
return vcvta_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtaq_s32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTAQ_S32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTAQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtas.v4i32.v4f32(<4 x float> [[VCVTAQ_S32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTAQ_S32_V1_I]]
|
|
//
|
|
int32x4_t test_vcvtaq_s32_f32(float32x4_t a) {
|
|
return vcvtaq_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtaq_u32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTAQ_U32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTAQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtau.v4i32.v4f32(<4 x float> [[VCVTAQ_U32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTAQ_U32_V1_I]]
|
|
//
|
|
uint32x4_t test_vcvtaq_u32_f32(float32x4_t a) {
|
|
return vcvtaq_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtn_s32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTN_S32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTN_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtns.v2i32.v2f32(<2 x float> [[VCVTN_S32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTN_S32_V1_I]]
|
|
//
|
|
int32x2_t test_vcvtn_s32_f32(float32x2_t a) {
|
|
return vcvtn_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtn_u32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTN_U32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTN_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtnu.v2i32.v2f32(<2 x float> [[VCVTN_U32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTN_U32_V1_I]]
|
|
//
|
|
uint32x2_t test_vcvtn_u32_f32(float32x2_t a) {
|
|
return vcvtn_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtnq_s32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTNQ_S32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTNQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtns.v4i32.v4f32(<4 x float> [[VCVTNQ_S32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTNQ_S32_V1_I]]
|
|
//
|
|
int32x4_t test_vcvtnq_s32_f32(float32x4_t a) {
|
|
return vcvtnq_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtnq_u32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTNQ_U32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTNQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtnu.v4i32.v4f32(<4 x float> [[VCVTNQ_U32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTNQ_U32_V1_I]]
|
|
//
|
|
uint32x4_t test_vcvtnq_u32_f32(float32x4_t a) {
|
|
return vcvtnq_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtp_s32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTP_S32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTP_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtps.v2i32.v2f32(<2 x float> [[VCVTP_S32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTP_S32_V1_I]]
|
|
//
|
|
int32x2_t test_vcvtp_s32_f32(float32x2_t a) {
|
|
return vcvtp_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtp_u32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTP_U32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTP_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtpu.v2i32.v2f32(<2 x float> [[VCVTP_U32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTP_U32_V1_I]]
|
|
//
|
|
uint32x2_t test_vcvtp_u32_f32(float32x2_t a) {
|
|
return vcvtp_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtpq_s32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTPQ_S32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTPQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtps.v4i32.v4f32(<4 x float> [[VCVTPQ_S32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTPQ_S32_V1_I]]
|
|
//
|
|
int32x4_t test_vcvtpq_s32_f32(float32x4_t a) {
|
|
return vcvtpq_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtpq_u32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTPQ_U32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTPQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtpu.v4i32.v4f32(<4 x float> [[VCVTPQ_U32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTPQ_U32_V1_I]]
|
|
//
|
|
uint32x4_t test_vcvtpq_u32_f32(float32x4_t a) {
|
|
return vcvtpq_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtm_s32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTM_S32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTM_S32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtms.v2i32.v2f32(<2 x float> [[VCVTM_S32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTM_S32_V1_I]]
|
|
//
|
|
int32x2_t test_vcvtm_s32_f32(float32x2_t a) {
|
|
return vcvtm_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtm_u32_f32
|
|
// CHECK-SAME: (<2 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8>
|
|
// CHECK-NEXT: [[VCVTM_U32_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float>
|
|
// CHECK-NEXT: [[VCVTM_U32_V1_I:%.*]] = call <2 x i32> @llvm.arm.neon.vcvtmu.v2i32.v2f32(<2 x float> [[VCVTM_U32_V_I]])
|
|
// CHECK-NEXT: ret <2 x i32> [[VCVTM_U32_V1_I]]
|
|
//
|
|
uint32x2_t test_vcvtm_u32_f32(float32x2_t a) {
|
|
return vcvtm_u32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtmq_s32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTMQ_S32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTMQ_S32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtms.v4i32.v4f32(<4 x float> [[VCVTMQ_S32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTMQ_S32_V1_I]]
|
|
//
|
|
int32x4_t test_vcvtmq_s32_f32(float32x4_t a) {
|
|
return vcvtmq_s32_f32(a);
|
|
}
|
|
|
|
// CHECK-LABEL: define {{[^@]+}}@test_vcvtmq_u32_f32
|
|
// CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32>
|
|
// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8>
|
|
// CHECK-NEXT: [[VCVTMQ_U32_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float>
|
|
// CHECK-NEXT: [[VCVTMQ_U32_V1_I:%.*]] = call <4 x i32> @llvm.arm.neon.vcvtmu.v4i32.v4f32(<4 x float> [[VCVTMQ_U32_V_I]])
|
|
// CHECK-NEXT: ret <4 x i32> [[VCVTMQ_U32_V1_I]]
|
|
//
|
|
uint32x4_t test_vcvtmq_u32_f32(float32x4_t a) {
|
|
return vcvtmq_u32_f32(a);
|
|
}
|
|
|