diff mbox

[AARCH32,ACLE,NEON] Implement vcvt*_s32_f32 and vcvt*_u32_f32 NEON intrinsics.

Message ID 56968DAD.3010203@foss.arm.com
State New
Headers show

Commit Message

Bilyan Borisov Jan. 13, 2016, 5:47 p.m. UTC
[AARCH32][ACLE][NEON] Implement vcvt*_s32_f32 and vcvt*_u32_f32 NEON 
intrinsics.

This patch implements all the vcvtRQ_s32_f32 and vcvtRQ_u32_f32 vector
intrinsics, where R is ['',a,m,n,p] and Q is ['',q]. The intrinsics were
implemented using builtin functions mapping to the existing 
neon_vcvt<sup><mode>
pattern, which was extended to cover the above cross product of all 
variants. In
addition, a new unary type qualifier for builtins, UNOPUS, was added to 
enable
the builtin functions to be called without casts.

Cross tested on arm-none-eabi, arm-none-linux-gnueabi, 
arm-none-linux-gnueabihf,
armeb-none-eabi.

---

gcc/

2015-XX-XX  Bilyan Borisov  <bilyan.borisov@foss.arm.com>

	* config/arm/arm-builtins.c (arm_unopus_qualifiers): New
	qualifier.
	* config/aarch64/arm_neon.h (vcvta_s32_f32): New intrinsic.
	(vcvta_u32_f32): Likewise.
	(vcvtaq_s32_f32): Likewise.
	(vcvtaq_u32_f32): Likewise.
	(vcvtm_s32_f32): Likewise.
	(vcvtm_u32_f32): Likewise.
	(vcvtmq_s32_f32): Likewise.
	(vcvtmq_u32_f32): Likewise.
	(vcvtn_s32_f32): Likewise.
	(vcvtn_u32_f32): Likewise.
	(vcvtnq_s32_f32): Likewise.
	(vcvtnq_u32_f32): Likewise.
	(vcvtp_s32_f32): Likewise.
	(vcvtp_u32_f32): Likewise.
	(vcvtpq_s32_f32): Likewise.
	(vcvtpq_u32_f32): Likewise.
	* config/arm/arm_neon_builtins.def (vcvtas): New builtin.
	(vcvtau): Likewise.
	(vcvtps): Likewise.
	(vcvtpu): Likewise.
	(vcvtms): Likewise.
	(vcvtmu): Likewise.
	(vcvtns): Likewise.
	(vcvtnu): Likewise.
	* config/arm/iterators.md (VCVTR_US): New int iterator.
	(VQMOVN): Modified int iterator.
	(rndmode): New int attribute.
	* config/arm/neon.md (neon_vcvt<VCVTR_US:rndmode><VCVTR_US:sup>
	<VCVTF:mode>): Modified pattern.
	* config/arm/unspecs.md (UNSPEC_VCVTA_S): New unspec definition.
	(UNSPEC_VCVTA_U): Likewise.
	(UNSPEC_VCVTM_S): Likewise.
	(UNSPEC_VCVTM_U): Likewise.
	(UNSPEC_VCVTN_S): Likewise.
	(UNSPEC_VCVTN_U): Likewise.
	(UNSPEC_VCVTP_S): Likewise.
	(UNSPEC_VCVTP_U): Likewise.

gcc/testsuite/

2015-XX-XX  Bilyan Borisov  <bilyan.borisov@foss.arm.com>

	* gcc.target/arm/neon/vcvta_s32_f32_1.c: New.
	* gcc.target/arm/neon/vcvta_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtaq_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtaq_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtm_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtm_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtmq_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtmq_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtn_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtn_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtnq_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtnq_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtp_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtp_u32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtpq_s32_f32_1.c: Likewise.
	* gcc.target/arm/neon/vcvtpq_u32_f32_1.c: Likewise.
diff mbox

Patch

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 11cd17d0b8f3c29ccbe16cb463a17d55ba0fa1e3..d635372c3257b33f9ca353f150e68bb6f9621a8d 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -87,6 +87,12 @@  arm_bswap_qualifiers[SIMD_MAX_BUILTIN_ARGS]
   = { qualifier_unsigned, qualifier_unsigned };
 #define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
 
+/* unsigned T (T).  */
+static enum arm_type_qualifiers
+arm_unopus_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_unsigned, qualifier_none };
+#define UNOPUS_QUALIFIERS (arm_unopus_qualifiers)
+
 /* T (T, T [maybe_immediate]).  */
 static enum arm_type_qualifiers
 arm_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h
index 0a33d21f2fcf8a1074fb62e89f4418295d446db5..fc3f5aa24c88f3aec1cfd234f9ca0aec11e1c612 100644
--- a/gcc/config/arm/arm_neon.h
+++ b/gcc/config/arm/arm_neon.h
@@ -6356,6 +6356,106 @@  vcvtq_u32_f32 (float32x4_t __a)
 }
 
 #pragma GCC push_options
+#pragma GCC target ("fpu=neon-fp-armv8")
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vcvta_s32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtasv2sf (__a);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vcvta_u32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtauv2sf_us (__a);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vcvtaq_s32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtasv4sf (__a);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vcvtaq_u32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtauv4sf_us (__a);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vcvtm_s32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtmsv2sf (__a);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vcvtm_u32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtmuv2sf_us (__a);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vcvtmq_s32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtmsv4sf (__a);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vcvtmq_u32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtmuv4sf_us (__a);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vcvtn_s32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtnsv2sf (__a);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vcvtn_u32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtnuv2sf_us (__a);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vcvtnq_s32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtnsv4sf (__a);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vcvtnq_u32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtnuv4sf_us (__a);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vcvtp_s32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtpsv2sf (__a);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vcvtp_u32_f32 (float32x2_t __a)
+{
+  return __builtin_neon_vcvtpuv2sf_us (__a);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vcvtpq_s32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtpsv4sf (__a);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vcvtpq_u32_f32 (float32x4_t __a)
+{
+  return __builtin_neon_vcvtpuv4sf_us (__a);
+}
+
+#pragma GCC pop_options
+
+#pragma GCC push_options
 #pragma GCC target ("fpu=neon-fp16")
 #if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
 __extension__ static __inline float16x4_t __attribute__ ((__always_inline__))
diff --git a/gcc/config/arm/arm_neon_builtins.def b/gcc/config/arm/arm_neon_builtins.def
index 0b719df760747af7642bd14ab14a9b2144d43359..95e5a96e497e827c1c84c21ea124c53e3cd95690 100644
--- a/gcc/config/arm/arm_neon_builtins.def
+++ b/gcc/config/arm/arm_neon_builtins.def
@@ -223,6 +223,14 @@  VAR1 (UNOP, vcvtmv2sf, v2si)
 VAR1 (UNOP, vcvtmv4sf, v4si)
 VAR1 (UNOP, vcvtmuv2sf, v2si)
 VAR1 (UNOP, vcvtmuv4sf, v4si)
+VAR2 (UNOP, vcvtas, v2sf, v4sf)
+VAR2 (UNOPUS, vcvtau, v2sf, v4sf)
+VAR2 (UNOP, vcvtps, v2sf, v4sf)
+VAR2 (UNOPUS, vcvtpu, v2sf, v4sf)
+VAR2 (UNOP, vcvtms, v2sf, v4sf)
+VAR2 (UNOPUS, vcvtmu, v2sf, v4sf)
+VAR2 (UNOP, vcvtns, v2sf, v4sf)
+VAR2 (UNOPUS, vcvtnu, v2sf, v4sf)
 VAR1 (COMBINE, vtbl1, v8qi)
 VAR1 (COMBINE, vtbl2, v8qi)
 VAR1 (COMBINE, vtbl3, v8qi)
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 6a541251ed1e5d7c766aca04f0da97ba6d470541..322eec8a363f2c1572b47b927ec360072b3ecd50 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -319,6 +319,16 @@ 
 
 (define_int_iterator VCVT_US [UNSPEC_VCVT_S UNSPEC_VCVT_U])
 
+(define_int_iterator VCVTR_US [UNSPEC_VCVT_S UNSPEC_VCVT_U
+			       (UNSPEC_VCVTA_S "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTA_U "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTM_S "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTM_U "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTN_S "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTN_U "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTP_S "TARGET_FPU_ARMV8")
+			       (UNSPEC_VCVTP_U "TARGET_FPU_ARMV8")])
+
 (define_int_iterator VCVT_US_N [UNSPEC_VCVT_S_N UNSPEC_VCVT_U_N])
 
 (define_int_iterator VQMOVN [UNSPEC_VQMOVN_S UNSPEC_VQMOVN_U])
@@ -704,6 +714,10 @@ 
   (UNSPEC_VPMAX "s") (UNSPEC_VPMAX_U "u")
   (UNSPEC_VPMIN "s") (UNSPEC_VPMIN_U "u")
   (UNSPEC_VCVT_S "s") (UNSPEC_VCVT_U "u")
+  (UNSPEC_VCVTA_S "s") (UNSPEC_VCVTA_U "u")
+  (UNSPEC_VCVTM_S "s") (UNSPEC_VCVTM_U "u")
+  (UNSPEC_VCVTN_S "s") (UNSPEC_VCVTN_U "u")
+  (UNSPEC_VCVTP_S "s") (UNSPEC_VCVTP_U "u")
   (UNSPEC_VCVT_S_N "s") (UNSPEC_VCVT_U_N "u")
   (UNSPEC_VQMOVN_S "s") (UNSPEC_VQMOVN_U "u")
   (UNSPEC_VMOVL_S "s") (UNSPEC_VMOVL_U "u")
@@ -722,6 +736,14 @@ 
 
 ])
 
+(define_int_attr rndmode [
+  (UNSPEC_VCVT_S "") (UNSPEC_VCVT_U "")
+  (UNSPEC_VCVTA_S "a") (UNSPEC_VCVTA_U "a")
+  (UNSPEC_VCVTM_S "m") (UNSPEC_VCVTM_U "m")
+  (UNSPEC_VCVTN_S "n") (UNSPEC_VCVTN_U "n")
+  (UNSPEC_VCVTP_S "p") (UNSPEC_VCVTP_U "p")
+])
+
 (define_int_attr cmp_op_unsp [(UNSPEC_VCEQ "eq") (UNSPEC_VCGT "gt")
                               (UNSPEC_VCGE "ge") (UNSPEC_VCLE "le")
                               (UNSPEC_VCLT "lt") (UNSPEC_VCAGE "ge")
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 62fb6daae9983470faf2c9cc686f5181b8bd7cb6..c4ae01586f61068de77b86b4fd7b3fc4e835addb 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -2988,13 +2988,17 @@  if (BYTES_BIG_ENDIAN)
   [(set_attr "type" "neon_fp_to_int_<V_elem_ch><q>")]
 )
 
-(define_insn "neon_vcvt<sup><mode>"
+;; For the ARMv8 versions of vcvt i.e. vcvt(a|m|n|p) to be available, not
+;; only TARGET_NEON needs to be true, but also TARGET_FPU_ARMV8 needs to
+;; be true, because the VCVTR_US int_iterator defines TARGET_FPU_ARMV8
+;; as a condition.
+(define_insn "neon_vcvt<VCVTR_US:rndmode><VCVTR_US:sup><VCVTF:mode>"
   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
 	(unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")]
-			  VCVT_US))]
+			  VCVTR_US))]
   "TARGET_NEON"
-  "vcvt.<sup>%#32.f32\t%<V_reg>0, %<V_reg>1"
-  [(set_attr "type" "neon_fp_to_int_<V_elem_ch><q>")]
+  "vcvt<rndmode>.<sup>%#32.f32\t%<VCVTF:V_reg>0, %<VCVTF:V_reg>1"
+  [(set_attr "type" "neon_fp_to_int_<VCVTF:V_elem_ch><q>")]
 )
 
 (define_insn "neon_vcvt<sup><mode>"
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index 67acafd075fb515a848fbe968a0183e4673ab0cd..d52f3bf738d34ddc8507cedda38d6c2b19550c97 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -200,6 +200,14 @@ 
   UNSPEC_VCVT
   UNSPEC_VCVT_S
   UNSPEC_VCVT_U
+  UNSPEC_VCVTA_S
+  UNSPEC_VCVTA_U
+  UNSPEC_VCVTM_S
+  UNSPEC_VCVTM_U
+  UNSPEC_VCVTN_S
+  UNSPEC_VCVTN_U
+  UNSPEC_VCVTP_S
+  UNSPEC_VCVTP_U
   UNSPEC_VCVT_S_N
   UNSPEC_VCVT_U_N
   UNSPEC_VEXT
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvta_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvta_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..958a7d5baf363518fa0ed1ae61a8d3fe408b4a69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvta_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  int32x2_t _y = vcvta_s32_f32 (x);
+  int32_t y[2];
+  vst1_s32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5};
+  float32x2_t x2 = vld1_f32 (_x2);
+  int32x2_t _y2 = vcvta_s32_f32 (x2);
+  int32_t y2[2];
+  vst1_s32 (y2, _y2);
+
+  for (int i = 0; i < 2; ++i)
+    if (y2[i] != -1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvta\.s32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvta_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvta_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..f832eda501fefd6d5648cb8932a88ee06308f49b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvta_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  uint32x2_t _y = vcvta_u32_f32 (x);
+  uint32_t y[2];
+  vst1_u32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvta\.u32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtaq_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtaq_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..e56ad15e0a492003c748ebe4b5d02b6e687ac86a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtaq_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  int32x4_t _y = vcvtaq_s32_f32 (x);
+  int32_t y[4];
+  vst1q_s32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+
+  float32_t _x2[]= {-0.5, -0.5, -0.5, -0.5};
+  float32x4_t x2 = vld1q_f32 (_x2);
+  int32x4_t _y2 = vcvtaq_s32_f32 (x2);
+  int32_t y2[4];
+  vst1q_s32 (y2, _y2);
+
+  for (int i = 0; i < 4; ++i)
+    if (y2[i] != -1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvta\.s32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtaq_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtaq_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..cd84d24c2e19f792edd4357821d0c01901aff8ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtaq_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  uint32x4_t _y = vcvtaq_u32_f32 (x);
+  uint32_t y[4];
+  vst1q_u32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvta\.u32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtm_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtm_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..9523553b6806ca36c1ed1de31bf2b379ac53d68c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtm_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  int32x2_t _y = vcvtm_s32_f32 (x);
+  int32_t y[2];
+  vst1_s32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5};
+  float32x2_t x2 = vld1_f32 (_x2);
+  int32x2_t _y2 = vcvtm_s32_f32 (x2);
+  int32_t y2[2];
+  vst1_s32 (y2, _y2);
+
+  for (int i = 0; i < 2; ++i)
+    if (y2[i] != -1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtm\.s32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtm_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtm_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..365b16c50e00141be3049b0b9cbc94139359f92a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtm_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  uint32x2_t _y = vcvtm_u32_f32 (x);
+  uint32_t y[2];
+  vst1_u32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtm\.u32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtmq_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtmq_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..21c0fa259bee0243ee8c0e58b263d193ba2e3c35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtmq_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  int32x4_t _y = vcvtmq_s32_f32 (x);
+  int32_t y[4];
+  vst1q_s32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5, -0.5, -0.5};
+  float32x4_t x2 = vld1q_f32 (_x2);
+  int32x4_t _y2 = vcvtmq_s32_f32 (x2);
+  int32_t y2[4];
+  vst1q_s32 (y2, _y2);
+
+  for (int i = 0; i < 4; ++i)
+    if (y2[i] != -1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtm\.s32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtmq_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtmq_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d9b0ae7faa9e0b630304c7cbe5a02779e3c0b1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtmq_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  uint32x4_t _y = vcvtmq_u32_f32 (x);
+  uint32_t y[4];
+  vst1q_u32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtm\.u32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtn_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtn_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..f2685cd748118de636d8f4a69a23042fa1f01ab0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtn_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  int32x2_t _y = vcvtn_s32_f32 (x);
+  int32_t y[2];
+  vst1_s32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5};
+  float32x2_t x2 = vld1_f32 (_x2);
+  int32x2_t _y2 = vcvtn_s32_f32 (x2);
+  int32_t y2[2];
+  vst1_s32 (y2, _y2);
+
+  for (int i = 0; i < 2; ++i)
+    if (y2[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtn\.s32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtn_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtn_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..6e84f6c69fd714bb1d62ca13953ea77acc138cb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtn_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  uint32x2_t _y = vcvtn_u32_f32 (x);
+  uint32_t y[2];
+  vst1_u32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtn\.u32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtnq_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtnq_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..1654ba10ddd5ac697e5a3de30987cd6a704ed3f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtnq_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  int32x4_t _y = vcvtnq_s32_f32 (x);
+  int32_t y[4];
+  vst1q_s32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5, -0.5, -0.5};
+  float32x4_t x2 = vld1q_f32 (_x2);
+  int32x4_t _y2 = vcvtnq_s32_f32 (x2);
+  int32_t y2[4];
+  vst1q_s32 (y2, _y2);
+
+  for (int i = 0; i < 4; ++i)
+    if (y2[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtn\.s32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtnq_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtnq_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a3ed8b9f86cd59222ac933a862c71f7693ab731
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtnq_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  uint32x4_t _y = vcvtnq_u32_f32 (x);
+  uint32_t y[4];
+  vst1q_u32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtn\.u32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtp_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtp_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..02942512f9ee3c24adb8bf415e7b11360dcc359a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtp_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  int32x2_t _y = vcvtp_s32_f32 (x);
+  int32_t y[2];
+  vst1_s32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5};
+  float32x2_t x2 = vld1_f32 (_x2);
+  int32x2_t _y2 = vcvtp_s32_f32 (x2);
+  int32_t y2[2];
+  vst1_s32 (y2, _y2);
+
+  for (int i = 0; i < 2; ++i)
+    if (y2[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtp\.s32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtp_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtp_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..1cdf20b8cec014c1035c4dda9a896f17b30579c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtp_u32_f32_1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5};
+  float32x2_t x = vld1_f32 (_x);
+  uint32x2_t _y = vcvtp_u32_f32 (x);
+  uint32_t y[2];
+  vst1_u32 (y, _y);
+
+  for (int i = 0; i < 2; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtp\.u32.f32\[\t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtpq_s32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtpq_s32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..31cf9d140a4c3810ae70f085797e130451bf8da9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtpq_s32_f32_1.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  int32x4_t _y = vcvtpq_s32_f32 (x);
+  int32_t y[4];
+  vst1q_s32 (y, _y);
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+
+  float32_t _x2[] = {-0.5, -0.5, -0.5, -0.5};
+  float32x4_t x2 = vld1q_f32 (_x2);
+  int32x4_t _y2 = vcvtpq_s32_f32 (x2);
+  int32_t y2[4];
+  vst1q_s32 (y2, _y2);
+
+  for (int i = 0; i < 4; ++i)
+    if (y2[i] != 0)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtp\.s32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vcvtpq_u32_f32_1.c b/gcc/testsuite/gcc.target/arm/neon/vcvtpq_u32_f32_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..dbda430c455f29ff4ebe31fd41ceeb890379c0fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vcvtpq_u32_f32_1.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-options "-save-temps -O3 -march=armv8-a" } */
+/* { dg-add-options arm_v8_neon } */
+
+#include "arm_neon.h"
+
+int
+main ()
+{
+  float32_t _x[] = {0.5, 0.5, 0.5, 0.5};
+  float32x4_t x = vld1q_f32 (_x);
+  uint32x4_t _y = vcvtpq_u32_f32 (x);
+  uint32_t y[4];
+  vst1q_u32 (y, _y);
+
+
+  for (int i = 0; i < 4; ++i)
+    if (y[i] != 1)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler "vcvtp\.u32.f32\[\t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+\n" } } */