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]+ +**... +*/ +
