> -----Original Message-----
> From: Alfie Richards <[email protected]>
> Sent: 30 April 2026 16:42
> To: [email protected]
> Cc: Alex Coplan <[email protected]>; Alice Carlotti
> <[email protected]>; [email protected];
> [email protected]; Richard Earnshaw <[email protected]>;
> Tamar Christina <[email protected]>; Wilco Dijkstra
> <[email protected]>; Alfie Richards <[email protected]>
> Subject: [PATCH 2/2] aarch64: Add FEAT_FPRCVT support.
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64.h (TARGET_FPRCVT): New macro
> definition.
> * config/aarch64/aarch64.md (arches): Add fprcvt.
> (arch_enabled): Add fprcvt.
> (l<fcvt_pattern><su_optab><GPF_F16:mode><GPI:mode>2): Add
> FEAT_FPRCVT variant.
> (<optab>_trunchf<GPI:mode>2): Likewise.
> (<optab>_trunc<fcvt_change_mode><GPI:mode>2): Likewise.
> (fix_to_zero_extend<mode>di2): Likewise.
> (<optab><fcvt_iesize><GPF:mode>2): Likewise.
> (define_insn "aarch64_fp16_<optab><mode>hf2): Likewise.
> * config/aarch64/iterators.md (fpw): Add SF and DF variants.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/acle/fprcvt.c: New test.
> * gcc.target/aarch64/fprcvt.c: New test.
> * gcc.target/aarch64/fprcvt.x: New test.
> * gcc.target/aarch64/fprcvt_float32_int32.c: New test.
> * gcc.target/aarch64/fprcvt_float32_int64.c: New test.
> * gcc.target/aarch64/fprcvt_float32_uint32.c: New test.
> * gcc.target/aarch64/fprcvt_float32_uint64.c: New test.
> * gcc.target/aarch64/fprcvt_float64_int32.c: New test.
> * gcc.target/aarch64/fprcvt_float64_int64.c: New test.
> * gcc.target/aarch64/fprcvt_float64_uint32.c: New test.
> * gcc.target/aarch64/fprcvt_float64_uint64.c: New test.
OK.
Thanks,
Tamar
> ---
> gcc/config/aarch64/aarch64.h | 2 +
> gcc/config/aarch64/aarch64.md | 74 +-
> gcc/config/aarch64/iterators.md | 2 +-
> .../gcc.target/aarch64/acle/fprcvt.c | 651 ++++++++++++++++++
> gcc/testsuite/gcc.target/aarch64/fprcvt.c | 147 ++++
> gcc/testsuite/gcc.target/aarch64/fprcvt.x | 87 +++
> .../gcc.target/aarch64/fprcvt_float32_int32.c | 18 +
> .../gcc.target/aarch64/fprcvt_float32_int64.c | 16 +
> .../aarch64/fprcvt_float32_uint32.c | 18 +
> .../aarch64/fprcvt_float32_uint64.c | 18 +
> .../gcc.target/aarch64/fprcvt_float64_int32.c | 18 +
> .../gcc.target/aarch64/fprcvt_float64_int64.c | 16 +
> .../aarch64/fprcvt_float64_uint32.c | 18 +
> .../aarch64/fprcvt_float64_uint64.c | 18 +
> 14 files changed, 1073 insertions(+), 30 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c
> create mode 100644 gcc/testsuite/gcc.target/aarch64/fprcvt.c
> create mode 100644 gcc/testsuite/gcc.target/aarch64/fprcvt.x
> create mode 100644 gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c
> create mode 100644 gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c
> create mode 100644 gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c
> create mode 100644 gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c
>
> diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
> index a0282ce285b..0a53b42b199 100644
> --- a/gcc/config/aarch64/aarch64.h
> +++ b/gcc/config/aarch64/aarch64.h
> @@ -591,6 +591,8 @@ through +ssve-fp8dot2. */
> && (AARCH64_HAVE_ISA (SSVE_FEXPA) \
> || TARGET_NON_STREAMING))
>
> +#define TARGET_FPRCVT (AARCH64_HAVE_ISA (FPRCVT))
> +
> /* Standard register usage. */
>
> /* 31 64-bit general purpose registers R0-R30:
> diff --git a/gcc/config/aarch64/aarch64.md
> b/gcc/config/aarch64/aarch64.md
> index 6541fa84f88..234850888e3 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -503,7 +503,7 @@ (define_constants
> ;; Q registers and is equivalent to "simd".
>
> (define_enum "arches" [any rcpc8_4 fp fp_q base_simd nobase_simd
> - simd nosimd sve fp16 sme cssc sve2p2_or_sme2p2])
> + simd nosimd sve fp16 sme cssc fprcvt
> sve2p2_or_sme2p2])
>
> (define_enum_attr "arch" "arches" (const_string "any"))
>
> @@ -585,7 +585,10 @@ (define_attr "arch_enabled" "no,yes"
> (match_test "TARGET_SME"))
>
> (and (eq_attr "arch" "sve2p2_or_sme2p2")
> - (match_test "TARGET_SVE2p2_OR_SME2p2"))))
> + (match_test "TARGET_SVE2p2_OR_SME2p2"))
> +
> + (and (eq_attr "arch" "fprcvt")
> + (match_test "TARGET_FPRCVT"))))
> (const_string "yes")
> (const_string "no")))
>
> @@ -3156,8 +3159,8 @@ (define_insn
> "*subs_<optab><ALLX:mode>_<GPI:mode>"
> (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
> [(set (reg:CC_NZ CC_REGNUM)
> (compare:CC_NZ
> - (plus:GPI (ashift:GPI
> - (ANY_EXTEND:GPI
> + (plus:GPI (ashift:GPI
> + (ANY_EXTEND:GPI
> (match_operand:ALLX 1 "register_operand" "r"))
> (match_operand 2 "aarch64_imm3" "Ui3"))
> (match_operand:GPI 3 "register_operand" "rk"))
> @@ -3175,7 +3178,7 @@ (define_insn
> "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
> [(set (reg:CC_NZ CC_REGNUM)
> (compare:CC_NZ
> (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
> - (ashift:GPI
> + (ashift:GPI
> (ANY_EXTEND:GPI
> (match_operand:ALLX 2 "register_operand" "r"))
> (match_operand 3 "aarch64_imm3" "Ui3")))
> @@ -7097,13 +7100,15 @@ (define_insn "<frint_pattern><mode>2"
> ;; frcvt floating-point round to integer and convert standard patterns.
> ;; Expands to lbtrunc, lceil, lfloor, lround.
> (define_insn "l<fcvt_pattern><su_optab><GPF_F16:mode><GPI:mode>2"
> - [(set (match_operand:GPI 0 "register_operand" "=r")
> + [(set (match_operand:GPI 0 "register_operand")
> (FIXUORS:GPI
> - (unspec:GPF_F16 [(match_operand:GPF_F16 1 "register_operand"
> "w")]
> + (unspec:GPF_F16 [(match_operand:GPF_F16 1 "register_operand")]
> FCVT)))]
> - "TARGET_FLOAT"
> - "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF_F16:s>1"
> - [(set_attr "type" "f_cvtf2i")]
> + ""
> + {@ [ cons: =0 , 1 ; attrs: type , arch ]
> + [ r , w ; f_cvtf2i , fp ]
> fcvt<frint_suffix><su>\t%<GPI:w>0,
> %<GPF_F16:s>1
> + [ w , w ; f_cvtf2i , fprcvt ]
> fcvt<frint_suffix><su>\t%<GPI:v>0,
> %<GPF_F16:s>1
> + }
> )
>
> (define_insn "*aarch64_fcvt<su_optab><GPF:mode><GPI:mode>2_mult"
> @@ -7284,32 +7289,38 @@ (define_insn
> "<optab>_trunc<fcvt_target><GPI:mode>2"
> ;; Convert HF -> SI or DI
>
> (define_insn "<optab>_trunchf<GPI:mode>2"
> - [(set (match_operand:GPI 0 "register_operand" "=r")
> - (FIXUORS:GPI (match_operand:HF 1 "register_operand" "w")))]
> + [(set (match_operand:GPI 0 "register_operand")
> + (FIXUORS:GPI (match_operand:HF 1 "register_operand")))]
> "TARGET_FP_F16INST"
> - "fcvtz<su>\t%<w>0, %h1"
> - [(set_attr "type" "f_cvtf2i")]
> + {@ [ cons: =0 , 1 ; attrs: type , arch ]
> + [ r , w ; f_cvtf2i , fp ] fcvtz<su>\t%<w>0, %h1
> + [ w , w ; f_cvtf2i , fprcvt ] fcvtz<su>\t%<s>0, %h1
> + }
> )
>
> ;; Convert DF -> SI or SF -> DI which can only be accomplished with
> ;; input in a fp register and output in a integer register
>
> (define_insn "<optab>_trunc<fcvt_change_mode><GPI:mode>2"
> - [(set (match_operand:GPI 0 "register_operand" "=r")
> - (FIXUORS:GPI (match_operand:<FCVT_CHANGE_MODE> 1
> "register_operand" "w")))]
> + [(set (match_operand:GPI 0 "register_operand")
> + (FIXUORS:GPI (match_operand:<FCVT_CHANGE_MODE> 1
> "register_operand")))]
> "TARGET_FLOAT"
> - "fcvtz<su>\t%<w>0, %<fpw>1"
> - [(set_attr "type" "f_cvtf2i")]
> + {@ [ cons: =0 , 1 ; attrs: type , arch ]
> + [ r , w ; f_cvtf2i , fp ] fcvtz<su>\t%<w>0, %<fpw>1
> + [ w , w ; f_cvtf2i , fprcvt ] fcvtz<su>\t%<s>0, %<fpw>1
> + }
> )
>
> (define_insn "*fix_to_zero_extend<mode>di2"
> - [(set (match_operand:DI 0 "register_operand" "=r")
> + [(set (match_operand:DI 0 "register_operand")
> (zero_extend:DI
> (unsigned_fix:SI
> - (match_operand:GPF 1 "register_operand" "w"))))]
> + (match_operand:GPF 1 "register_operand"))))]
> "TARGET_FLOAT"
> - "fcvtzu\t%w0, %<s>1"
> - [(set_attr "type" "f_cvtf2i")]
> + {@ [ cons: =0 , 1 ; attrs: type , arch ]
> + [ r , w ; f_cvtf2i , fp ] fcvtzu\t%w0, %<s>1
> + [ w , w ; f_cvtf2i , fprcvt ] fcvtzu\t%s0, %<s>1
> + }
> )
>
> ;; Equal width integer to fp and multiply combine.
> @@ -7362,10 +7373,13 @@ (define_insn
> "<optab><fcvt_target><GPF:mode>2"
>
> ;; Unequal width integer to fp conversions.
> (define_insn "<optab><fcvt_iesize><GPF:mode>2"
> - [(set (match_operand:GPF 0 "register_operand" "=w")
> - (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand"
> "r")))]
> + [(set (match_operand:GPF 0 "register_operand")
> + (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1
> "register_operand")))]
> "TARGET_FLOAT"
> - "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
> + {@ [ cons: =0 , 1 ; attrs: type , arch ]
> + [ w , r ; f_cvti2f , fp ] <su_optab>cvtf\t%<GPF:s>0,
> %<w2>1
> + [ w , w ; f_cvti2f , fprcvt ] <su_optab>cvtf\t%<GPF:s>0,
> %<fpw>1
> + }
> [(set_attr "type" "f_cvti2f")]
> )
>
> @@ -7377,11 +7391,13 @@ (define_insn
> "<optab><fcvt_iesize><GPF:mode>2"
> ;; of the mid-end logic.
>
> (define_insn "aarch64_fp16_<optab><mode>hf2"
> - [(set (match_operand:HF 0 "register_operand" "=w")
> - (FLOATUORS:HF (match_operand:GPI 1 "register_operand" "r")))]
> + [(set (match_operand:HF 0 "register_operand")
> + (FLOATUORS:HF (match_operand:GPI 1 "register_operand")))]
> "TARGET_FP_F16INST"
> - "<su_optab>cvtf\t%h0, %<w>1"
> - [(set_attr "type" "f_cvti2f")]
> + {@ [ cons: =0 , 1 ; attrs: type , arch ]
> + [ w , r ; f_cvti2f , fp ] <su_optab>cvtf\t%h0, %<w>1
> + [ w , w ; f_cvti2f , fprcvt ] <su_optab>cvtf\t%h0, %<v>1
> + }
> )
>
> (define_expand "<optab>sihf2"
> diff --git a/gcc/config/aarch64/iterators.md
> b/gcc/config/aarch64/iterators.md
> index 6b969258182..a469d082bbb 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -1440,7 +1440,7 @@ (define_mode_attr w1 [(HF "w") (SF "w") (DF
> "x")])
> (define_mode_attr w2 [(HF "x") (SF "x") (DF "w")])
>
> ;; For width of fp registers in fcvt instruction
> -(define_mode_attr fpw [(DI "s") (SI "d")])
> +(define_mode_attr fpw [(DI "s") (SI "d") (DF "s") (SF "d")])
>
> (define_mode_attr short_mask [(HI "65535") (QI "255")])
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c
> b/gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c
> new file mode 100644
> index 00000000000..603e72d8c5a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c
> @@ -0,0 +1,651 @@
> +/* { dg-do compile } */
> +/* { dg-options "-save-temps -fno-inline -O1 -march=armv9-a+fprcvt" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +#include <stdint.h>
> +#include <arm_fp16.h>
> +#include <arm_acle.h>
> +#include <arm_neon.h>
> +
> +#define FORCE_FP_REG(a) asm volatile("fmov %d0, %d1" : "=w"(a) : "w"(a)
> :)
> +#define CONVERT_INTRINSIC(T_FROM, T_TO, INTRINSIC)
> \
> + void convert_##INTRINSIC (T_FROM *from, T_TO *to) \
> + {
> \
> + T_FROM from_val = *from;
> \
> + FORCE_FP_REG (from_val);
> \
> + T_TO to_val = INTRINSIC (from_val);
> \
> + FORCE_FP_REG (to_val);
> \
> + *to = to_val;
> \
> + }
> +
> +CONVERT_INTRINSIC (float32_t, int32_t, vcvts_s32_f32)
> +/*
> +** convert_vcvts_s32_f32:
> +**...
> +** fcvtzs s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int64_t, vcvts_s64_f32)
> +/*
> +** convert_vcvts_s64_f32:
> +**...
> +** fcvtzs d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint32_t, vcvts_u32_f32)
> +/*
> +** convert_vcvts_u32_f32:
> +**...
> +** fcvtzu s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint64_t, vcvts_u64_f32)
> +/*
> +** convert_vcvts_u64_f32:
> +**...
> +** fcvtzu d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int32_t, vcvtns_s32_f32)
> +/*
> +** convert_vcvtns_s32_f32:
> +**...
> +** fcvtns s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int64_t, vcvtns_s64_f32)
> +/*
> +** convert_vcvtns_s64_f32:
> +**...
> +** fcvtns d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint32_t, vcvtns_u32_f32)
> +/*
> +** convert_vcvtns_u32_f32:
> +**...
> +** fcvtnu s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint64_t, vcvtns_u64_f32)
> +/*
> +** convert_vcvtns_u64_f32:
> +**...
> +** fcvtnu d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int32_t, vcvtms_s32_f32)
> +/*
> +** convert_vcvtms_s32_f32:
> +**...
> +** fcvtms s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int64_t, vcvtms_s64_f32)
> +/*
> +** convert_vcvtms_s64_f32:
> +**...
> +** fcvtms d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint32_t, vcvtms_u32_f32)
> +/*
> +** convert_vcvtms_u32_f32:
> +**...
> +** fcvtmu s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint64_t, vcvtms_u64_f32)
> +/*
> +** convert_vcvtms_u64_f32:
> +**...
> +** fcvtmu d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int32_t, vcvtps_s32_f32)
> +/*
> +** convert_vcvtps_s32_f32:
> +**...
> +** fcvtps s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int64_t, vcvtps_s64_f32)
> +/*
> +** convert_vcvtps_s64_f32:
> +**...
> +** fcvtps d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint32_t, vcvtps_u32_f32)
> +/*
> +** convert_vcvtps_u32_f32:
> +**...
> +** fcvtpu s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint64_t, vcvtps_u64_f32)
> +/*
> +** convert_vcvtps_u64_f32:
> +**...
> +** fcvtpu d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int32_t, vcvtas_s32_f32)
> +/*
> +** convert_vcvtas_s32_f32:
> +**...
> +** fcvtas s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, int64_t, vcvtas_s64_f32)
> +/*
> +** convert_vcvtas_s64_f32:
> +**...
> +** fcvtas d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint32_t, vcvtas_u32_f32)
> +/*
> +** convert_vcvtas_u32_f32:
> +**...
> +** fcvtau s[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float32_t, uint64_t, vcvtas_u64_f32)
> +/*
> +** convert_vcvtas_u64_f32:
> +**...
> +** fcvtau d[0-9]+, s[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int32_t, vcvtd_s32_f64)
> +/*
> +** convert_vcvtd_s32_f64:
> +**...
> +** fcvtzs s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int64_t, vcvtd_s64_f64)
> +/*
> +** convert_vcvtd_s64_f64:
> +**...
> +** fcvtzs d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint32_t, vcvtd_u32_f64)
> +/*
> +** convert_vcvtd_u32_f64:
> +**...
> +** fcvtzu s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint64_t, vcvtd_u64_f64)
> +/*
> +** convert_vcvtd_u64_f64:
> +**...
> +** fcvtzu d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int32_t, vcvtnd_s32_f64)
> +/*
> +** convert_vcvtnd_s32_f64:
> +**...
> +** fcvtns s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int64_t, vcvtnd_s64_f64)
> +/*
> +** convert_vcvtnd_s64_f64:
> +**...
> +** fcvtns d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint32_t, vcvtnd_u32_f64)
> +/*
> +** convert_vcvtnd_u32_f64:
> +**...
> +** fcvtnu s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint64_t, vcvtnd_u64_f64)
> +/*
> +** convert_vcvtnd_u64_f64:
> +**...
> +** fcvtnu d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int32_t, vcvtmd_s32_f64)
> +/*
> +** convert_vcvtmd_s32_f64:
> +**...
> +** fcvtms s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int64_t, vcvtmd_s64_f64)
> +/*
> +** convert_vcvtmd_s64_f64:
> +**...
> +** fcvtms d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint32_t, vcvtmd_u32_f64)
> +/*
> +** convert_vcvtmd_u32_f64:
> +**...
> +** fcvtmu s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint64_t, vcvtmd_u64_f64)
> +/*
> +** convert_vcvtmd_u64_f64:
> +**...
> +** fcvtmu d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int32_t, vcvtpd_s32_f64)
> +/*
> +** convert_vcvtpd_s32_f64:
> +**...
> +** fcvtps s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int64_t, vcvtpd_s64_f64)
> +/*
> +** convert_vcvtpd_s64_f64:
> +**...
> +** fcvtps d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint32_t, vcvtpd_u32_f64)
> +/*
> +** convert_vcvtpd_u32_f64:
> +**...
> +** fcvtpu s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint64_t, vcvtpd_u64_f64)
> +/*
> +** convert_vcvtpd_u64_f64:
> +**...
> +** fcvtpu d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int32_t, vcvtad_s32_f64)
> +/*
> +** convert_vcvtad_s32_f64:
> +**...
> +** fcvtas s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, int64_t, vcvtad_s64_f64)
> +/*
> +** convert_vcvtad_s64_f64:
> +**...
> +** fcvtas d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint32_t, vcvtad_u32_f64)
> +/*
> +** convert_vcvtad_u32_f64:
> +**...
> +** fcvtau s[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float64_t, uint64_t, vcvtad_u64_f64)
> +/*
> +** convert_vcvtad_u64_f64:
> +**...
> +** fcvtau d[0-9]+, d[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int16_t, vcvth_s16_f16)
> +/*
> +** convert_vcvth_s16_f16:
> +**...
> +** fcvtzs h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int32_t, vcvth_s32_f16)
> +/*
> +** convert_vcvth_s32_f16:
> +**...
> +** fcvtzs s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int64_t, vcvth_s64_f16)
> +/*
> +** convert_vcvth_s64_f16:
> +**...
> +** fcvtzs d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint16_t, vcvth_u16_f16)
> +/*
> +** convert_vcvth_u16_f16:
> +**...
> +** fcvtzu h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint32_t, vcvth_u32_f16)
> +/*
> +** convert_vcvth_u32_f16:
> +**...
> +** fcvtzu s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint64_t, vcvth_u64_f16)
> +/*
> +** convert_vcvth_u64_f16:
> +**...
> +** fcvtzu d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int16_t, vcvtah_s16_f16)
> +/*
> +** convert_vcvtah_s16_f16:
> +**...
> +** fcvtas h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int32_t, vcvtah_s32_f16)
> +/*
> +** convert_vcvtah_s32_f16:
> +**...
> +** fcvtas s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int64_t, vcvtah_s64_f16)
> +/*
> +** convert_vcvtah_s64_f16:
> +**...
> +** fcvtas d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint16_t, vcvtah_u16_f16)
> +/*
> +** convert_vcvtah_u16_f16:
> +**...
> +** fcvtau h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint32_t, vcvtah_u32_f16)
> +/*
> +** convert_vcvtah_u32_f16:
> +**...
> +** fcvtau s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint64_t, vcvtah_u64_f16)
> +/*
> +** convert_vcvtah_u64_f16:
> +**...
> +** fcvtau d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int16_t, vcvtmh_s16_f16)
> +/*
> +** convert_vcvtmh_s16_f16:
> +**...
> +** fcvtms h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int32_t, vcvtmh_s32_f16)
> +/*
> +** convert_vcvtmh_s32_f16:
> +**...
> +** fcvtms s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int64_t, vcvtmh_s64_f16)
> +/*
> +** convert_vcvtmh_s64_f16:
> +**...
> +** fcvtms d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint16_t, vcvtmh_u16_f16)
> +/*
> +** convert_vcvtmh_u16_f16:
> +**...
> +** fcvtmu h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint32_t, vcvtmh_u32_f16)
> +/*
> +** convert_vcvtmh_u32_f16:
> +**...
> +** fcvtmu s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint64_t, vcvtmh_u64_f16)
> +/*
> +** convert_vcvtmh_u64_f16:
> +**...
> +** fcvtmu d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int16_t, vcvtnh_s16_f16)
> +/*
> +** convert_vcvtnh_s16_f16:
> +**...
> +** fcvtns h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int32_t, vcvtnh_s32_f16)
> +/*
> +** convert_vcvtnh_s32_f16:
> +**...
> +** fcvtns s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int64_t, vcvtnh_s64_f16)
> +/*
> +** convert_vcvtnh_s64_f16:
> +**...
> +** fcvtns d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint16_t, vcvtnh_u16_f16)
> +/*
> +** convert_vcvtnh_u16_f16:
> +**...
> +** fcvtnu h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint32_t, vcvtnh_u32_f16)
> +/*
> +** convert_vcvtnh_u32_f16:
> +**...
> +** fcvtnu s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint64_t, vcvtnh_u64_f16)
> +/*
> +** convert_vcvtnh_u64_f16:
> +**...
> +** fcvtnu d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int16_t, vcvtph_s16_f16)
> +/*
> +** convert_vcvtph_s16_f16:
> +**...
> +** fcvtps h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int32_t, vcvtph_s32_f16)
> +/*
> +** convert_vcvtph_s32_f16:
> +**...
> +** fcvtps s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, int64_t, vcvtph_s64_f16)
> +/*
> +** convert_vcvtph_s64_f16:
> +**...
> +** fcvtps d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint16_t, vcvtph_u16_f16)
> +/*
> +** convert_vcvtph_u16_f16:
> +**...
> +** fcvtpu h[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint32_t, vcvtph_u32_f16)
> +/*
> +** convert_vcvtph_u32_f16:
> +**...
> +** fcvtpu s[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +CONVERT_INTRINSIC (float16_t, uint64_t, vcvtph_u64_f16)
> +/*
> +** convert_vcvtph_u64_f16:
> +**...
> +** fcvtpu d[0-9]+, h[0-9]+
> +**...
> +*/
> +
> +
> +CONVERT_INTRINSIC (int32_t, float32_t, vcvts_f32_s32)
> +/*
> +** convert_vcvts_f32_s32:
> +**...
> +** scvtf s[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (uint32_t, float32_t, vcvts_f32_u32)
> +/*
> +** convert_vcvts_f32_u32:
> +**...
> +** ucvtf s[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (int64_t, float64_t, vcvtd_f64_s64)
> +/*
> +** convert_vcvtd_f64_s64:
> +**...
> +** scvtf d[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (uint64_t, float64_t, vcvtd_f64_u64)
> +/*
> +** convert_vcvtd_f64_u64:
> +**...
> +** ucvtf d[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (int16_t, float16_t, vcvth_f16_s16)
> +/*
> +** convert_vcvth_f16_s16:
> +**...
> +** scvtf h[0-9]+, h[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (int32_t, float16_t, vcvth_f16_s32)
> +/*
> +** convert_vcvth_f16_s32:
> +**...
> +** scvtf h[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (int64_t, float16_t, vcvth_f16_s64)
> +/*
> +** convert_vcvth_f16_s64:
> +**...
> +** scvtf h[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (uint16_t, float16_t, vcvth_f16_u16)
> +/*
> +** convert_vcvth_f16_u16:
> +**...
> +** ucvtf h[0-9]+, h[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (uint32_t, float16_t, vcvth_f16_u32)
> +/*
> +** convert_vcvth_f16_u32:
> +**...
> +** ucvtf h[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT_INTRINSIC (uint64_t, float16_t, vcvth_f16_u64)
> +/*
> +** convert_vcvth_f16_u64:
> +**...
> +** ucvtf h[0-9]+, d[0-9]+
> +**...
> +*/
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt.c
> new file mode 100644
> index 00000000000..1bca48b9a15
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt.c
> @@ -0,0 +1,147 @@
> +/* { dg-do compile } */
> +/* { dg-options "-save-temps -fno-inline -O2 -march=armv9-a+fprcvt" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +#include <stdint.h>
> +#include <arm_fp16.h>
> +#include <arm_acle.h>
> +#include <arm_neon.h>
> +
> +#define FORCE_FP_REG(a) asm volatile("fmov %d0, %d1" : "=w"(a) : "w"(a)
> :)
> +#define CONVERT(T_FROM, T_TO)
> \
> + void convert_##T_FROM##_to_##T_TO (T_FROM *from, T_TO *to)
> \
> + {
> \
> + T_FROM from_val = *from;
> \
> + FORCE_FP_REG (from_val);
> \
> + T_TO to_val = (T_TO) from_val;
> \
> + FORCE_FP_REG (to_val);
> \
> + *to = to_val;
> \
> + }
> +
> +/*
> +** convert_float16_t_to_int32_t:
> +**...
> +** fcvtzs s[0-9]+, h[0-9]+
> +**...
> +*/
> +CONVERT (float16_t, int32_t)
> +
> +/*
> +** convert_float64_t_to_int32_t:
> +**...
> +** fcvtzs s[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT (float64_t, int32_t)
> +
> +/*
> +** convert_float16_t_to_int64_t:
> +**...
> +** fcvtzs d[0-9]+, h[0-9]+
> +**...
> +*/
> +CONVERT (float16_t, int64_t)
> +
> +/*
> +** convert_float32_t_to_int64_t:
> +**...
> +** fcvtzs d[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT (float32_t, int64_t)
> +
> +/*
> +** convert_float16_t_to_uint32_t:
> +**...
> +** fcvtzu s[0-9]+, h[0-9]+
> +**...
> +*/
> +CONVERT (float16_t, uint32_t)
> +
> +/*
> +** convert_float64_t_to_uint32_t:
> +**...
> +** fcvtzu s[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT (float64_t, uint32_t)
> +
> +/*
> +** convert_float16_t_to_uint64_t:
> +**...
> +** fcvtzu d[0-9]+, h[0-9]+
> +**...
> +*/
> +CONVERT (float16_t, uint64_t)
> +
> +/*
> +** convert_float32_t_to_uint64_t:
> +**...
> +** fcvtzu d[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT (float32_t, uint64_t)
> +
> +/*
> +** convert_int32_t_to_float16_t:
> +**...
> +** scvtf h[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT (int32_t, float16_t)
> +
> +/*
> +** convert_int32_t_to_float64_t:
> +**...
> +** scvtf d[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT (int32_t, float64_t)
> +
> +/*
> +** convert_int64_t_to_float16_t:
> +**...
> +** scvtf h[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT (int64_t, float16_t)
> +
> +/*
> +** convert_int64_t_to_float32_t:
> +**...
> +** scvtf s[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT (int64_t, float32_t)
> +
> +/*
> +** convert_uint32_t_to_float16_t:
> +**...
> +** ucvtf h[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT (uint32_t, float16_t)
> +
> +/*
> +** convert_uint32_t_to_float64_t:
> +**...
> +** ucvtf d[0-9]+, s[0-9]+
> +**...
> +*/
> +CONVERT (uint32_t, float64_t)
> +
> +/*
> +** convert_uint64_t_to_float16_t:
> +**...
> +** ucvtf h[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT (uint64_t, float16_t)
> +
> +/*
> +** convert_uint64_t_to_float32_t:
> +**...
> +** ucvtf s[0-9]+, d[0-9]+
> +**...
> +*/
> +CONVERT (uint64_t, float32_t)
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt.x
> b/gcc/testsuite/gcc.target/aarch64/fprcvt.x
> new file mode 100644
> index 00000000000..a4e8fc39505
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt.x
> @@ -0,0 +1,87 @@
> +extern GPF SUFFIX(trunc) (GPF);
> +extern GPF SUFFIX(ceil) (GPF);
> +extern GPF SUFFIX(floor) (GPF);
> +extern GPF SUFFIX(round) (GPF);
> +
> +#define FORCE_FP_REG(a) asm volatile("fmov %d0, %d1" : "=w"(a) : "w"(a)
> :)
> +
> +GPI test1a (GPF x) {
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(__builtin_trunc)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test1b (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(trunc)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test2a (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(__builtin_lceil)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test2b (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(ceil)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test2c (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(__builtin_ceil)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test3a (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(__builtin_lfloor)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test3b (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(floor)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test3c (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(__builtin_floor)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test4a (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(__builtin_round)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +GPI test4b (GPF x)
> +{
> + FORCE_FP_REG(x);
> + GPI res = SUFFIX(round)(x);
> + FORCE_FP_REG(res);
> + return res;
> +}
> +
> +
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c
> new file mode 100644
> index 00000000000..6a086339e1b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float32_t
> +#define SUFFIX(x) x##f
> +#define GPI int32_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzs\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtas\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c
> new file mode 100644
> index 00000000000..22464157d2f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float32_t
> +#define SUFFIX(x) x##f
> +#define GPI int64_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzs\td\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 3 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 3 } } */
> +/* { dg-final { scan-assembler-times "fcvtas\td\[0-9\]+, *s\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c
> new file mode 100644
> index 00000000000..87e4686edd3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float32_t
> +#define SUFFIX(x) x##f
> +#define GPI uint32_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzu\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtpu\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtmu\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtau\ts\[0-9\]+, *s\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c
> new file mode 100644
> index 00000000000..76922b33edf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float32_t
> +#define SUFFIX(x) x##f
> +#define GPI uint64_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzu\td\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 1 } } *
> +/* { dg-final { scan-assembler-times "fcvtpu\td\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtmu\td\[0-9\]+, *s\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtau\td\[0-9\]+, *s\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c
> new file mode 100644
> index 00000000000..dd772600e0d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float64_t
> +#define SUFFIX(x) x
> +#define GPI int32_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzs\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtas\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c
> new file mode 100644
> index 00000000000..c28960a4601
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float64_t
> +#define SUFFIX(x) x
> +#define GPI int64_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzs\td\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 3 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 3 } } */
> +/* { dg-final { scan-assembler-times "fcvtas\td\[0-9\]+, *d\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c
> new file mode 100644
> index 00000000000..7dcd0cc41f6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float64_t
> +#define SUFFIX(x) x
> +#define GPI uint32_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzu\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 1 } } *
> +/* { dg-final { scan-assembler-times "fcvtpu\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtmu\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtau\ts\[0-9\]+, *d\[0-9\]" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c
> b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c
> new file mode 100644
> index 00000000000..f0d385d44c1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
> +
> +#include <stdint.h>
> +#include <arm_neon.h>
> +
> +#define GPF float64_t
> +#define SUFFIX(x) x
> +#define GPI uint64_t
> +
> +#include "fprcvt.x"
> +
> +/* { dg-final { scan-assembler-times "fcvtzu\td\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtpu\td\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtmu\td\[0-9\]+, *d\[0-9\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 1 } } */
> +/* { dg-final { scan-assembler-times "fcvtau\td\[0-9\]+, *d\[0-9\]" 2 } } */
> --
> 2.34.1