Hi Christophe, > -----Original Message----- > From: Christophe Lyon <christophe.l...@arm.com> > Sent: Tuesday, April 18, 2023 2:46 PM > To: gcc-patches@gcc.gnu.org; Kyrylo Tkachov <kyrylo.tkac...@arm.com>; > Richard Earnshaw <richard.earns...@arm.com>; Richard Sandiford > <richard.sandif...@arm.com> > Cc: Christophe Lyon <christophe.l...@arm.com> > Subject: [PATCH 03/22] arm: [MVE intrinsics] Rework vreinterpretq > > This patch implements vreinterpretq using the new MVE intrinsics > framework. > > The old definitions for vreinterpretq are removed as a consequence. > > 2022-09-08 Murray Steele <murray.ste...@arm.com> > Christophe Lyon <christophe.l...@arm.com> > > gcc/ > * config/arm/arm-mve-builtins-base.cc (vreinterpretq_impl): New > class. > * config/arm/arm-mve-builtins-base.def: Define vreinterpretq. > * config/arm/arm-mve-builtins-base.h (vreinterpretq): New > declaration. > * config/arm/arm-mve-builtins-shapes.cc (parse_element_type): New > function. > (parse_type): Likewise. > (parse_signature): Likewise. > (build_one): Likewise. > (build_all): Likewise. > (overloaded_base): New struct. > (unary_convert_def): Likewise. > * config/arm/arm-mve-builtins-shapes.h (unary_convert): Declare. > * config/arm/arm-mve-builtins.cc (TYPES_reinterpret_signed1): New > macro. > (TYPES_reinterpret_unsigned1): Likewise. > (TYPES_reinterpret_integer): Likewise. > (TYPES_reinterpret_integer1): Likewise. > (TYPES_reinterpret_float1): Likewise. > (TYPES_reinterpret_float): Likewise. > (reinterpret_integer): New. > (reinterpret_float): New. > (handle_arm_mve_h): Register builtins. > * config/arm/arm_mve.h (vreinterpretq_s16): Remove. > (vreinterpretq_s32): Likewise. > (vreinterpretq_s64): Likewise. > (vreinterpretq_s8): Likewise. > (vreinterpretq_u16): Likewise. > (vreinterpretq_u32): Likewise. > (vreinterpretq_u64): Likewise. > (vreinterpretq_u8): Likewise. > (vreinterpretq_f16): Likewise. > (vreinterpretq_f32): Likewise. > (vreinterpretq_s16_s32): Likewise. > (vreinterpretq_s16_s64): Likewise. > (vreinterpretq_s16_s8): Likewise. > (vreinterpretq_s16_u16): Likewise. > (vreinterpretq_s16_u32): Likewise. > (vreinterpretq_s16_u64): Likewise. > (vreinterpretq_s16_u8): Likewise. > (vreinterpretq_s32_s16): Likewise. > (vreinterpretq_s32_s64): Likewise. > (vreinterpretq_s32_s8): Likewise. > (vreinterpretq_s32_u16): Likewise. > (vreinterpretq_s32_u32): Likewise. > (vreinterpretq_s32_u64): Likewise. > (vreinterpretq_s32_u8): Likewise. > (vreinterpretq_s64_s16): Likewise. > (vreinterpretq_s64_s32): Likewise. > (vreinterpretq_s64_s8): Likewise. > (vreinterpretq_s64_u16): Likewise. > (vreinterpretq_s64_u32): Likewise. > (vreinterpretq_s64_u64): Likewise. > (vreinterpretq_s64_u8): Likewise. > (vreinterpretq_s8_s16): Likewise. > (vreinterpretq_s8_s32): Likewise. > (vreinterpretq_s8_s64): Likewise. > (vreinterpretq_s8_u16): Likewise. > (vreinterpretq_s8_u32): Likewise. > (vreinterpretq_s8_u64): Likewise. > (vreinterpretq_s8_u8): Likewise. > (vreinterpretq_u16_s16): Likewise. > (vreinterpretq_u16_s32): Likewise. > (vreinterpretq_u16_s64): Likewise. > (vreinterpretq_u16_s8): Likewise. > (vreinterpretq_u16_u32): Likewise. > (vreinterpretq_u16_u64): Likewise. > (vreinterpretq_u16_u8): Likewise. > (vreinterpretq_u32_s16): Likewise. > (vreinterpretq_u32_s32): Likewise. > (vreinterpretq_u32_s64): Likewise. > (vreinterpretq_u32_s8): Likewise. > (vreinterpretq_u32_u16): Likewise. > (vreinterpretq_u32_u64): Likewise. > (vreinterpretq_u32_u8): Likewise. > (vreinterpretq_u64_s16): Likewise. > (vreinterpretq_u64_s32): Likewise. > (vreinterpretq_u64_s64): Likewise. > (vreinterpretq_u64_s8): Likewise. > (vreinterpretq_u64_u16): Likewise. > (vreinterpretq_u64_u32): Likewise. > (vreinterpretq_u64_u8): Likewise. > (vreinterpretq_u8_s16): Likewise. > (vreinterpretq_u8_s32): Likewise. > (vreinterpretq_u8_s64): Likewise. > (vreinterpretq_u8_s8): Likewise. > (vreinterpretq_u8_u16): Likewise. > (vreinterpretq_u8_u32): Likewise. > (vreinterpretq_u8_u64): Likewise. > (vreinterpretq_s32_f16): Likewise. > (vreinterpretq_s32_f32): Likewise. > (vreinterpretq_u16_f16): Likewise. > (vreinterpretq_u16_f32): Likewise. > (vreinterpretq_u32_f16): Likewise. > (vreinterpretq_u32_f32): Likewise. > (vreinterpretq_u64_f16): Likewise. > (vreinterpretq_u64_f32): Likewise. > (vreinterpretq_u8_f16): Likewise. > (vreinterpretq_u8_f32): Likewise. > (vreinterpretq_f16_f32): Likewise. > (vreinterpretq_f16_s16): Likewise. > (vreinterpretq_f16_s32): Likewise. > (vreinterpretq_f16_s64): Likewise. > (vreinterpretq_f16_s8): Likewise. > (vreinterpretq_f16_u16): Likewise. > (vreinterpretq_f16_u32): Likewise. > (vreinterpretq_f16_u64): Likewise. > (vreinterpretq_f16_u8): Likewise. > (vreinterpretq_f32_f16): Likewise. > (vreinterpretq_f32_s16): Likewise. > (vreinterpretq_f32_s32): Likewise. > (vreinterpretq_f32_s64): Likewise. > (vreinterpretq_f32_s8): Likewise. > (vreinterpretq_f32_u16): Likewise. > (vreinterpretq_f32_u32): Likewise. > (vreinterpretq_f32_u64): Likewise. > (vreinterpretq_f32_u8): Likewise. > (vreinterpretq_s16_f16): Likewise. > (vreinterpretq_s16_f32): Likewise. > (vreinterpretq_s64_f16): Likewise. > (vreinterpretq_s64_f32): Likewise. > (vreinterpretq_s8_f16): Likewise. > (vreinterpretq_s8_f32): Likewise. > (__arm_vreinterpretq_f16): Likewise. > (__arm_vreinterpretq_f32): Likewise. > (__arm_vreinterpretq_s16): Likewise. > (__arm_vreinterpretq_s32): Likewise. > (__arm_vreinterpretq_s64): Likewise. > (__arm_vreinterpretq_s8): Likewise. > (__arm_vreinterpretq_u16): Likewise. > (__arm_vreinterpretq_u32): Likewise. > (__arm_vreinterpretq_u64): Likewise. > (__arm_vreinterpretq_u8): Likewise. > * config/arm/arm_mve_types.h (__arm_vreinterpretq_s16_s32): > Remove. > (__arm_vreinterpretq_s16_s64): Likewise. > (__arm_vreinterpretq_s16_s8): Likewise. > (__arm_vreinterpretq_s16_u16): Likewise. > (__arm_vreinterpretq_s16_u32): Likewise. > (__arm_vreinterpretq_s16_u64): Likewise. > (__arm_vreinterpretq_s16_u8): Likewise. > (__arm_vreinterpretq_s32_s16): Likewise. > (__arm_vreinterpretq_s32_s64): Likewise. > (__arm_vreinterpretq_s32_s8): Likewise. > (__arm_vreinterpretq_s32_u16): Likewise. > (__arm_vreinterpretq_s32_u32): Likewise. > (__arm_vreinterpretq_s32_u64): Likewise. > (__arm_vreinterpretq_s32_u8): Likewise. > (__arm_vreinterpretq_s64_s16): Likewise. > (__arm_vreinterpretq_s64_s32): Likewise. > (__arm_vreinterpretq_s64_s8): Likewise. > (__arm_vreinterpretq_s64_u16): Likewise. > (__arm_vreinterpretq_s64_u32): Likewise. > (__arm_vreinterpretq_s64_u64): Likewise. > (__arm_vreinterpretq_s64_u8): Likewise. > (__arm_vreinterpretq_s8_s16): Likewise. > (__arm_vreinterpretq_s8_s32): Likewise. > (__arm_vreinterpretq_s8_s64): Likewise. > (__arm_vreinterpretq_s8_u16): Likewise. > (__arm_vreinterpretq_s8_u32): Likewise. > (__arm_vreinterpretq_s8_u64): Likewise. > (__arm_vreinterpretq_s8_u8): Likewise. > (__arm_vreinterpretq_u16_s16): Likewise. > (__arm_vreinterpretq_u16_s32): Likewise. > (__arm_vreinterpretq_u16_s64): Likewise. > (__arm_vreinterpretq_u16_s8): Likewise. > (__arm_vreinterpretq_u16_u32): Likewise. > (__arm_vreinterpretq_u16_u64): Likewise. > (__arm_vreinterpretq_u16_u8): Likewise. > (__arm_vreinterpretq_u32_s16): Likewise. > (__arm_vreinterpretq_u32_s32): Likewise. > (__arm_vreinterpretq_u32_s64): Likewise. > (__arm_vreinterpretq_u32_s8): Likewise. > (__arm_vreinterpretq_u32_u16): Likewise. > (__arm_vreinterpretq_u32_u64): Likewise. > (__arm_vreinterpretq_u32_u8): Likewise. > (__arm_vreinterpretq_u64_s16): Likewise. > (__arm_vreinterpretq_u64_s32): Likewise. > (__arm_vreinterpretq_u64_s64): Likewise. > (__arm_vreinterpretq_u64_s8): Likewise. > (__arm_vreinterpretq_u64_u16): Likewise. > (__arm_vreinterpretq_u64_u32): Likewise. > (__arm_vreinterpretq_u64_u8): Likewise. > (__arm_vreinterpretq_u8_s16): Likewise. > (__arm_vreinterpretq_u8_s32): Likewise. > (__arm_vreinterpretq_u8_s64): Likewise. > (__arm_vreinterpretq_u8_s8): Likewise. > (__arm_vreinterpretq_u8_u16): Likewise. > (__arm_vreinterpretq_u8_u32): Likewise. > (__arm_vreinterpretq_u8_u64): Likewise. > (__arm_vreinterpretq_s32_f16): Likewise. > (__arm_vreinterpretq_s32_f32): Likewise. > (__arm_vreinterpretq_s16_f16): Likewise. > (__arm_vreinterpretq_s16_f32): Likewise. > (__arm_vreinterpretq_s64_f16): Likewise. > (__arm_vreinterpretq_s64_f32): Likewise. > (__arm_vreinterpretq_s8_f16): Likewise. > (__arm_vreinterpretq_s8_f32): Likewise. > (__arm_vreinterpretq_u16_f16): Likewise. > (__arm_vreinterpretq_u16_f32): Likewise. > (__arm_vreinterpretq_u32_f16): Likewise. > (__arm_vreinterpretq_u32_f32): Likewise. > (__arm_vreinterpretq_u64_f16): Likewise. > (__arm_vreinterpretq_u64_f32): Likewise. > (__arm_vreinterpretq_u8_f16): Likewise. > (__arm_vreinterpretq_u8_f32): Likewise. > (__arm_vreinterpretq_f16_f32): Likewise. > (__arm_vreinterpretq_f16_s16): Likewise. > (__arm_vreinterpretq_f16_s32): Likewise. > (__arm_vreinterpretq_f16_s64): Likewise. > (__arm_vreinterpretq_f16_s8): Likewise. > (__arm_vreinterpretq_f16_u16): Likewise. > (__arm_vreinterpretq_f16_u32): Likewise. > (__arm_vreinterpretq_f16_u64): Likewise. > (__arm_vreinterpretq_f16_u8): Likewise. > (__arm_vreinterpretq_f32_f16): Likewise. > (__arm_vreinterpretq_f32_s16): Likewise. > (__arm_vreinterpretq_f32_s32): Likewise. > (__arm_vreinterpretq_f32_s64): Likewise. > (__arm_vreinterpretq_f32_s8): Likewise. > (__arm_vreinterpretq_f32_u16): Likewise. > (__arm_vreinterpretq_f32_u32): Likewise. > (__arm_vreinterpretq_f32_u64): Likewise. > (__arm_vreinterpretq_f32_u8): Likewise. > (__arm_vreinterpretq_s16): Likewise. > (__arm_vreinterpretq_s32): Likewise. > (__arm_vreinterpretq_s64): Likewise. > (__arm_vreinterpretq_s8): Likewise. > (__arm_vreinterpretq_u16): Likewise. > (__arm_vreinterpretq_u32): Likewise. > (__arm_vreinterpretq_u64): Likewise. > (__arm_vreinterpretq_u8): Likewise. > (__arm_vreinterpretq_f16): Likewise. > (__arm_vreinterpretq_f32): Likewise. > * config/arm/mve.md (@arm_mve_reinterpret<mode>): New > pattern. > * config/arm/unspecs.md: (REINTERPRET): New unspec. > > gcc/testsuite/ > * g++.target/arm/mve.exp: Add general-c++ and general directories. > * g++.target/arm/mve/general-c++/nomve_fp_1.c: New test. > * g++.target/arm/mve/general-c++/vreinterpretq_1.C: New test. > * gcc.target/arm/mve/general-c/nomve_fp_1.c: New test. > * gcc.target/arm/mve/general-c/vreinterpretq_1.c: New test. > --- > gcc/config/arm/arm-mve-builtins-base.cc | 29 + > gcc/config/arm/arm-mve-builtins-base.def | 2 + > gcc/config/arm/arm-mve-builtins-base.h | 2 + > gcc/config/arm/arm-mve-builtins-shapes.cc | 28 + > gcc/config/arm/arm-mve-builtins-shapes.h | 8 + > gcc/config/arm/arm-mve-builtins.cc | 60 + > gcc/config/arm/arm_mve.h | 300 ---- > gcc/config/arm/arm_mve_types.h | 1365 +---------------- > gcc/config/arm/mve.md | 18 + > gcc/config/arm/unspecs.md | 1 + > gcc/testsuite/g++.target/arm/mve.exp | 8 +- > .../arm/mve/general-c++/nomve_fp_1.c | 15 + > .../arm/mve/general-c++/vreinterpretq_1.C | 25 + > .../gcc.target/arm/mve/general-c/nomve_fp_1.c | 15 + > .../arm/mve/general-c/vreinterpretq_1.c | 25 + > 15 files changed, 286 insertions(+), 1615 deletions(-) > create mode 100644 gcc/testsuite/g++.target/arm/mve/general- > c++/nomve_fp_1.c > create mode 100644 gcc/testsuite/g++.target/arm/mve/general- > c++/vreinterpretq_1.C > create mode 100644 gcc/testsuite/gcc.target/arm/mve/general- > c/nomve_fp_1.c > create mode 100644 gcc/testsuite/gcc.target/arm/mve/general- > c/vreinterpretq_1.c > > diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm- > mve-builtins-base.cc > index e9f285faf2b..ad8d500afc6 100644 > --- a/gcc/config/arm/arm-mve-builtins-base.cc > +++ b/gcc/config/arm/arm-mve-builtins-base.cc > @@ -38,8 +38,37 @@ using namespace arm_mve; > > namespace { > > +/* Implements vreinterpretq_* intrinsics. */ > +class vreinterpretq_impl : public quiet<function_base> > +{ > + gimple * > + fold (gimple_folder &f) const override > + { > + /* Punt to rtl if the effect of the reinterpret on registers does not > + conform to GCC's endianness model. */ > + if (!targetm.can_change_mode_class (f.vector_mode (0), > + f.vector_mode (1), VFP_REGS)) > + return NULL; > +
So we punt to an RTL pattern here if we cannot change mode class... [snip] > diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md > index 35eab6c94bf..ab688396f97 100644 > --- a/gcc/config/arm/mve.md > +++ b/gcc/config/arm/mve.md > @@ -10561,3 +10561,21 @@ (define_expand > "vcond_mask_<mode><MVE_vpred>" > } > DONE; > }) > + > +;; Reinterpret operand 1 in operand 0's mode, without changing its contents. > +(define_expand "@arm_mve_reinterpret<mode>" > + [(set (match_operand:MVE_vecs 0 "register_operand") > + (unspec:MVE_vecs > + [(match_operand 1 "arm_any_register_operand")] > + REINTERPRET))] > + "(TARGET_HAVE_MVE && VALID_MVE_SI_MODE (<MODE>mode)) > + || (TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE > (<MODE>mode))" > + { > + machine_mode src_mode = GET_MODE (operands[1]); > + if (targetm.can_change_mode_class (<MODE>mode, src_mode, > VFP_REGS)) > + { > + emit_move_insn (operands[0], gen_lowpart (<MODE>mode, > operands[1])); > + DONE; > + } > + } > +) ... But we still check can_change_mode_class in this pattern and if it's not true we emit the new REINTERPRET unspec without a corresponding define_insn pattern. Won't that ICE? Would this case occur on big-endian targets? Thanks, Kyrill > diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md > index 84384ee798d..dccda283573 100644 > --- a/gcc/config/arm/unspecs.md > +++ b/gcc/config/arm/unspecs.md > @@ -1255,4 +1255,5 @@ (define_c_enum "unspec" [ > SQRSHRL_64 > SQRSHRL_48 > VSHLCQ_M_ > + REINTERPRET > ])