https://gcc.gnu.org/g:d9118b9975dd0ddb6024e973f2707273ff2526c5

commit r17-1426-gd9118b9975dd0ddb6024e973f2707273ff2526c5
Author: Alfie Richards <[email protected]>
Date:   Mon Jan 5 17:01:55 2026 +0000

    aarch64: Add new fp->int conversion intrinsics
    
    Adds intrinsics for the following conversions:
    - float32_t -> uint64_t
    - float32_t -> int64_t
    - float64_t -> uint32_t
    - float64_t -> int32_t
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64-simd-builtins.def: (lround): Add new
            forms for new conversions.
            (lroundu): Likewise.
            (lceil): Likewise.
            (lceilu): Likewise.
            (lfloor): Likewise.
            (lflooru): Likewise.
            (lfrintn): Likewise.
            (lfrintnu): Likewise.
            * config/aarch64/arm_neon.h (vcvtd_s32_f64): New intrinsic.
            (vcvtd_s32_f64): Likewise.
            (vcvtd_u32_f64): Likewise.
            (vcvts_s64_f32): Likewise.
            (vcvts_u64_f32): Likewise.
            (vcvtad_s32_f64): Likewise.
            (vcvtad_u32_f64): Likewise.
            (vcvtas_s64_f32): Likewise.
            (vcvtas_u64_f32): Likewise.
            (vcvtmd_s32_f64): Likewise.
            (vcvtmd_u32_f64): Likewise.
            (vcvtms_s64_f32): Likewise.
            (vcvtms_u64_f32): Likewise.
            (vcvtnd_s32_f64): Likewise.
            (vcvtnd_u32_f64): Likewise.
            (vcvtns_s64_f32): Likewise.
            (vcvtns_u64_f32): Likewise.
            (vcvtpd_s32_f64): Likewise.
            (vcvtpd_u32_f64): Likewise.
            (vcvtps_s64_f32): Likewise.
            (vcvtps_u64_f32): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/acle/fcvt_intrinsics.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64-simd-builtins.def       |  16 ++
 gcc/config/aarch64/arm_neon.h                      | 139 +++++++++++++++++
 .../gcc.target/aarch64/acle/fcvt_intrinsics.c      | 166 +++++++++++++++++++++
 3 files changed, 321 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def 
b/gcc/config/aarch64/aarch64-simd-builtins.def
index 8677df3f488f..1b09191a0c01 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -577,6 +577,8 @@
   /* Implemented by l<fcvt_pattern><su_optab><GPF_F16:mode><GPI:mode>2.  */
   BUILTIN_GPI_I16 (UNOP, lroundhf, 2, FP)
   VAR1 (UNOP, lroundsf, 2, FP, si)
+  VAR1 (UNOP, lroundsf, 2, FP, di)
+  VAR1 (UNOP, lrounddf, 2, FP, si)
   VAR1 (UNOP, lrounddf, 2, FP, di)
 
   VAR1 (UNOPUS, lrounduv4hf, 2, FP, v4hi)
@@ -586,6 +588,8 @@
   VAR1 (UNOPUS, lrounduv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOPUS, lrounduhf, 2, FP)
   VAR1 (UNOPUS, lroundusf, 2, FP, si)
+  VAR1 (UNOPUS, lroundusf, 2, FP, di)
+  VAR1 (UNOPUS, lroundudf, 2, FP, si)
   VAR1 (UNOPUS, lroundudf, 2, FP, di)
 
   VAR1 (UNOP, lceilv4hf, 2, FP, v4hi)
@@ -594,6 +598,8 @@
   VAR1 (UNOP, lceilv4sf, 2, FP, v4si)
   VAR1 (UNOP, lceilv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOP, lceilhf, 2, FP)
+  VAR1 (UNOP, lceilsf, 2, FP, di)
+  VAR1 (UNOP, lceildf, 2, FP, si)
 
   VAR1 (UNOPUS, lceiluv4hf, 2, FP, v4hi)
   VAR1 (UNOPUS, lceiluv8hf, 2, FP, v8hi)
@@ -602,6 +608,8 @@
   VAR1 (UNOPUS, lceiluv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOPUS, lceiluhf, 2, FP)
   VAR1 (UNOPUS, lceilusf, 2, FP, si)
+  VAR1 (UNOPUS, lceilusf, 2, FP, di)
+  VAR1 (UNOPUS, lceiludf, 2, FP, si)
   VAR1 (UNOPUS, lceiludf, 2, FP, di)
 
   VAR1 (UNOP, lfloorv4hf, 2, FP, v4hi)
@@ -610,6 +618,8 @@
   VAR1 (UNOP, lfloorv4sf, 2, FP, v4si)
   VAR1 (UNOP, lfloorv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOP, lfloorhf, 2, FP)
+  VAR1 (UNOP, lfloorsf, 2, FP, di)
+  VAR1 (UNOP, lfloordf, 2, FP, si)
 
   VAR1 (UNOPUS, lflooruv4hf, 2, FP, v4hi)
   VAR1 (UNOPUS, lflooruv8hf, 2, FP, v8hi)
@@ -618,6 +628,8 @@
   VAR1 (UNOPUS, lflooruv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOPUS, lflooruhf, 2, FP)
   VAR1 (UNOPUS, lfloorusf, 2, FP, si)
+  VAR1 (UNOPUS, lfloorusf, 2, FP, di)
+  VAR1 (UNOPUS, lfloorudf, 2, FP, si)
   VAR1 (UNOPUS, lfloorudf, 2, FP, di)
 
   VAR1 (UNOP, lfrintnv4hf, 2, FP, v4hi)
@@ -627,6 +639,8 @@
   VAR1 (UNOP, lfrintnv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOP, lfrintnhf, 2, FP)
   VAR1 (UNOP, lfrintnsf, 2, FP, si)
+  VAR1 (UNOP, lfrintnsf, 2, FP, di)
+  VAR1 (UNOP, lfrintndf, 2, FP, si)
   VAR1 (UNOP, lfrintndf, 2, FP, di)
 
   VAR1 (UNOPUS, lfrintnuv4hf, 2, FP, v4hi)
@@ -636,6 +650,8 @@
   VAR1 (UNOPUS, lfrintnuv2df, 2, FP, v2di)
   BUILTIN_GPI_I16 (UNOPUS, lfrintnuhf, 2, FP)
   VAR1 (UNOPUS, lfrintnusf, 2, FP, si)
+  VAR1 (UNOPUS, lfrintnusf, 2, FP, di)
+  VAR1 (UNOPUS, lfrintnudf, 2, FP, si)
   VAR1 (UNOPUS, lfrintnudf, 2, FP, di)
 
   /* Implemented by <optab><fcvt_target><VDQF:mode>2.  */
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 2c4e24f4ad27..d7505a16edb5 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -10033,6 +10033,13 @@ vcvtd_s64_f64 (float64_t __a)
   return (int64_t) __a;
 }
 
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtd_s32_f64 (float64_t __a)
+{
+  return (int32_t) __a;
+}
+
 __extension__ extern __inline uint64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtd_u64_f64 (float64_t __a)
@@ -10040,6 +10047,13 @@ vcvtd_u64_f64 (float64_t __a)
   return (uint64_t) __a;
 }
 
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtd_u32_f64 (float64_t __a)
+{
+  return (uint32_t) __a;
+}
+
 __extension__ extern __inline int32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvts_s32_f32 (float32_t __a)
@@ -10047,6 +10061,13 @@ vcvts_s32_f32 (float32_t __a)
   return (int32_t) __a;
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvts_s64_f32 (float32_t __a)
+{
+  return (int64_t) __a;
+}
+
 __extension__ extern __inline uint32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvts_u32_f32 (float32_t __a)
@@ -10054,6 +10075,13 @@ vcvts_u32_f32 (float32_t __a)
   return (uint32_t) __a;
 }
 
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvts_u64_f32 (float32_t __a)
+{
+  return (uint64_t) __a;
+}
+
 __extension__ extern __inline int32x2_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvt_s32_f32 (float32x2_t __a)
@@ -10119,6 +10147,13 @@ vcvtad_s64_f64 (float64_t __a)
   return __builtin_aarch64_lrounddfdi (__a);
 }
 
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtad_s32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lrounddfsi (__a);
+}
+
 __extension__ extern __inline uint64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtad_u64_f64 (float64_t __a)
@@ -10126,6 +10161,13 @@ vcvtad_u64_f64 (float64_t __a)
   return __builtin_aarch64_lroundudfdi_us (__a);
 }
 
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtad_u32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lroundudfsi_us (__a);
+}
+
 __extension__ extern __inline int32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtas_s32_f32 (float32_t __a)
@@ -10133,6 +10175,13 @@ vcvtas_s32_f32 (float32_t __a)
   return __builtin_aarch64_lroundsfsi (__a);
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtas_s64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lroundsfdi (__a);
+}
+
 __extension__ extern __inline uint32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtas_u32_f32 (float32_t __a)
@@ -10140,6 +10189,13 @@ vcvtas_u32_f32 (float32_t __a)
   return __builtin_aarch64_lroundusfsi_us (__a);
 }
 
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtas_u64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lroundusfdi_us (__a);
+}
+
 __extension__ extern __inline int32x2_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvta_s32_f32 (float32x2_t __a)
@@ -10205,6 +10261,13 @@ vcvtmd_s64_f64 (float64_t __a)
   return __builtin_llfloor (__a);
 }
 
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtmd_s32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lfloordfsi (__a);
+}
+
 __extension__ extern __inline uint64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtmd_u64_f64 (float64_t __a)
@@ -10212,6 +10275,13 @@ vcvtmd_u64_f64 (float64_t __a)
   return __builtin_aarch64_lfloorudfdi_us (__a);
 }
 
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtmd_u32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lfloorudfsi_us (__a);
+}
+
 __extension__ extern __inline int32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtms_s32_f32 (float32_t __a)
@@ -10219,6 +10289,13 @@ vcvtms_s32_f32 (float32_t __a)
   return __builtin_ifloorf (__a);
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtms_s64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lfloorsfdi (__a);
+}
+
 __extension__ extern __inline uint32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtms_u32_f32 (float32_t __a)
@@ -10226,6 +10303,13 @@ vcvtms_u32_f32 (float32_t __a)
   return __builtin_aarch64_lfloorusfsi_us (__a);
 }
 
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtms_u64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lfloorusfdi_us (__a);
+}
+
 __extension__ extern __inline int32x2_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtm_s32_f32 (float32x2_t __a)
@@ -10291,6 +10375,13 @@ vcvtnd_s64_f64 (float64_t __a)
   return __builtin_aarch64_lfrintndfdi (__a);
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtnd_s32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lfrintndfsi (__a);
+}
+
 __extension__ extern __inline uint64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtnd_u64_f64 (float64_t __a)
@@ -10298,6 +10389,13 @@ vcvtnd_u64_f64 (float64_t __a)
   return __builtin_aarch64_lfrintnudfdi_us (__a);
 }
 
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtnd_u32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lfrintnudfsi_us (__a);
+}
+
 __extension__ extern __inline int32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtns_s32_f32 (float32_t __a)
@@ -10305,12 +10403,25 @@ vcvtns_s32_f32 (float32_t __a)
   return __builtin_aarch64_lfrintnsfsi (__a);
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtns_s64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lfrintnsfdi (__a);
+}
+
 __extension__ extern __inline uint32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtns_u32_f32 (float32_t __a)
 {
   return __builtin_aarch64_lfrintnusfsi_us (__a);
 }
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtns_u64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lfrintnusfdi_us (__a);
+}
 
 __extension__ extern __inline int32x2_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
@@ -10377,6 +10488,13 @@ vcvtpd_s64_f64 (float64_t __a)
   return __builtin_llceil (__a);
 }
 
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtpd_s32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lceildfsi (__a);
+}
+
 __extension__ extern __inline uint64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtpd_u64_f64 (float64_t __a)
@@ -10384,6 +10502,13 @@ vcvtpd_u64_f64 (float64_t __a)
   return __builtin_aarch64_lceiludfdi_us (__a);
 }
 
+__extension__ extern __inline uint32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtpd_u32_f64 (float64_t __a)
+{
+  return __builtin_aarch64_lceiludfsi_us (__a);
+}
+
 __extension__ extern __inline int32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtps_s32_f32 (float32_t __a)
@@ -10391,6 +10516,13 @@ vcvtps_s32_f32 (float32_t __a)
   return __builtin_iceilf (__a);
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtps_s64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lceilsfdi (__a);
+}
+
 __extension__ extern __inline uint32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtps_u32_f32 (float32_t __a)
@@ -10398,6 +10530,13 @@ vcvtps_u32_f32 (float32_t __a)
   return __builtin_aarch64_lceilusfsi_us (__a);
 }
 
+__extension__ extern __inline uint64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+vcvtps_u64_f32 (float32_t __a)
+{
+  return __builtin_aarch64_lceilusfdi_us (__a);
+}
+
 __extension__ extern __inline int32x2_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vcvtp_s32_f32 (float32x2_t __a)
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/fcvt_intrinsics.c 
b/gcc/testsuite/gcc.target/aarch64/acle/fcvt_intrinsics.c
new file mode 100644
index 000000000000..ff81d340f35b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/fcvt_intrinsics.c
@@ -0,0 +1,166 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_acle.h>
+#include <arm_neon.h>
+
+#define CONVERT_INTRINSIC(T_FROM, T_TO, INTRINSIC)                             
\
+  void convert_##INTRINSIC (T_FROM *from, T_TO *to)                            
\
+  {                                                                            
\
+    T_FROM from_val = *from;                                                   
\
+    T_TO to_val = INTRINSIC (from_val);                                        
\
+    *to = to_val;                                                              
\
+  }
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvts_s64_f32)
+/*
+** convert_vcvts_s64_f32:
+**...
+**     fcvtzs  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvts_u64_f32)
+/*
+** convert_vcvts_u64_f32:
+**...
+**     fcvtzu  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtns_s64_f32)
+/*
+** convert_vcvtns_s64_f32:
+**...
+**     fcvtns  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtns_u64_f32)
+/*
+** convert_vcvtns_u64_f32:
+**...
+**     fcvtnu  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtms_s64_f32)
+/*
+** convert_vcvtms_s64_f32:
+**...
+**     fcvtms  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtms_u64_f32)
+/*
+** convert_vcvtms_u64_f32:
+**...
+**     fcvtmu  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtps_s64_f32)
+/*
+** convert_vcvtps_s64_f32:
+**...
+**     fcvtps  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtps_u64_f32)
+/*
+** convert_vcvtps_u64_f32:
+**...
+**     fcvtpu  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtas_s64_f32)
+/*
+** convert_vcvtas_s64_f32:
+**...
+**     fcvtas  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtas_u64_f32)
+/*
+** convert_vcvtas_u64_f32:
+**...
+**     fcvtau  x[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtd_s32_f64)
+/*
+** convert_vcvtd_s32_f64:
+**...
+**     fcvtzs  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtd_u32_f64)
+/*
+** convert_vcvtd_u32_f64:
+**...
+**     fcvtzu  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtnd_s32_f64)
+/*
+** convert_vcvtnd_s32_f64:
+**...
+**     fcvtns  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtnd_u32_f64)
+/*
+** convert_vcvtnd_u32_f64:
+**...
+**     fcvtnu  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtmd_s32_f64)
+/*
+** convert_vcvtmd_s32_f64:
+**...
+**     fcvtms  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtmd_u32_f64)
+/*
+** convert_vcvtmd_u32_f64:
+**...
+**     fcvtmu  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtpd_s32_f64)
+/*
+** convert_vcvtpd_s32_f64:
+**...
+**     fcvtps  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtpd_u32_f64)
+/*
+** convert_vcvtpd_u32_f64:
+**...
+**     fcvtpu  w[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtad_s32_f64)
+/*
+** convert_vcvtad_s32_f64:
+**...
+**     fcvtas  w[0-9]+, d[0-9]+
+**...
+*/
+

Reply via email to