On Fri, Sep 6, 2024 at 7:31 PM Jin Ma <ji...@linux.alibaba.com> wrote:
>
> When we use flto, the function list of rvv will be generated twice,
> once in the cc1 phase and once in the lto phase. However, due to
> the different generation methods, the two lists are different.
>
> For example, when there is no zvfh or zvfhmin in arch, it is
> generated by calling function "riscv_pragma_intrinsic". since the
> TARGET_VECTOR_ELEN_FP_16 is enabled before rvv function generation,
> a list of rvv functions related to float16 will be generated. In
> the lto phase, the rvv function list is generated only by calling
> the function "riscv_init_builtins", but the TARGET_VECTOR_ELEN_FP_16
> is disabled, so that the float16-related rvv function list cannot
> be generated like cc1. This will cause confusion, resulting in
> matching tothe wrong function due to inconsistent fcode in the lto
> phase, eventually leading to ICE.
>
> So I think we should be consistent with their generated lists, which
> is exactly what this patch does.
>
> But there is still a problem here. If we use "-fchecking", we still
> have ICE. This is because in the lto phase, after the rvv function
> list is generated and before the expand_builtin, the ggc_grow will
> be called to clean up the memory, resulting in
> "(* registered_functions)[code]->decl" being cleaned up to
> "<ggc_freed 0x7ffff6830c00>, and finally ICE".
>
> I think this is wrong and needs to be fixed, maybe we shouldn't
> use "ggc_alloc<registered_function> ()", or is there another better
> way to implement it?

>From the root we're marking the registered_functions vector via
the

template<typename T>
void
gt_ggc_mx (vec<T, va_gc> *v)

overload which will eventually mark registered_function * but since
you do not provide a gt_ggc_mx overload for the pointer type
this pointer will _not_ be marked.

> I'm trying to fix it here. Any comments here?
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-c.cc (struct pragma_intrinsic_flags): Mov
>         to riscv-protos.h.
>         (riscv_pragma_intrinsic_flags_pollute): Mov to 
> riscv-vector-builtins.c.
>         (riscv_pragma_intrinsic_flags_restore): Likewise.
>         (riscv_pragma_intrinsic): Likewise.
>         * config/riscv/riscv-protos.h (struct pragma_intrinsic_flags):
>         New.
>         (riscv_pragma_intrinsic_flags_restore): New.
>         (riscv_pragma_intrinsic_flags_pollute): New.
>         * config/riscv/riscv-vector-builtins.cc 
> (riscv_pragma_intrinsic_flags_pollute): New.
>         (riscv_pragma_intrinsic_flags_restore): New.
>         (handle_pragma_vector_for_lto): New.
>         (init_builtins): Correct the processing logic for lto.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/base/bug-10.c: New test.
> ---
>  gcc/config/riscv/riscv-c.cc                   | 70 +---------------
>  gcc/config/riscv/riscv-protos.h               | 13 +++
>  gcc/config/riscv/riscv-vector-builtins.cc     | 83 ++++++++++++++++++-
>  .../gcc.target/riscv/rvv/base/bug-10.c        | 18 ++++
>  4 files changed, 114 insertions(+), 70 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
>
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index 71112d9c66d7..7037ecc1268a 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -34,72 +34,6 @@ along with GCC; see the file COPYING3.  If not see
>
>  #define builtin_define(TXT) cpp_define (pfile, TXT)
>
> -struct pragma_intrinsic_flags
> -{
> -  int intrinsic_target_flags;
> -
> -  int intrinsic_riscv_vector_elen_flags;
> -  int intrinsic_riscv_zvl_flags;
> -  int intrinsic_riscv_zvb_subext;
> -  int intrinsic_riscv_zvk_subext;
> -};
> -
> -static void
> -riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
> -{
> -  flags->intrinsic_target_flags = target_flags;
> -  flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
> -  flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
> -  flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
> -  flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
> -
> -  target_flags = target_flags
> -    | MASK_VECTOR;
> -
> -  riscv_zvl_flags = riscv_zvl_flags
> -    | MASK_ZVL32B
> -    | MASK_ZVL64B
> -    | MASK_ZVL128B;
> -
> -  riscv_vector_elen_flags = riscv_vector_elen_flags
> -    | MASK_VECTOR_ELEN_32
> -    | MASK_VECTOR_ELEN_64
> -    | MASK_VECTOR_ELEN_FP_16
> -    | MASK_VECTOR_ELEN_FP_32
> -    | MASK_VECTOR_ELEN_FP_64;
> -
> -  riscv_zvb_subext = riscv_zvb_subext
> -    | MASK_ZVBB
> -    | MASK_ZVBC
> -    | MASK_ZVKB;
> -
> -  riscv_zvk_subext = riscv_zvk_subext
> -    | MASK_ZVKG
> -    | MASK_ZVKNED
> -    | MASK_ZVKNHA
> -    | MASK_ZVKNHB
> -    | MASK_ZVKSED
> -    | MASK_ZVKSH
> -    | MASK_ZVKN
> -    | MASK_ZVKNC
> -    | MASK_ZVKNG
> -    | MASK_ZVKS
> -    | MASK_ZVKSC
> -    | MASK_ZVKSG
> -    | MASK_ZVKT;
> -}
> -
> -static void
> -riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
> -{
> -  target_flags = flags->intrinsic_target_flags;
> -
> -  riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
> -  riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
> -  riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
> -  riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
> -}
> -
>  static int
>  riscv_ext_version_value (unsigned major, unsigned minor)
>  {
> @@ -269,14 +203,14 @@ riscv_pragma_intrinsic (cpp_reader *)
>      {
>        struct pragma_intrinsic_flags backup_flags;
>
> -      riscv_pragma_intrinsic_flags_pollute (&backup_flags);
> +      riscv_vector::riscv_pragma_intrinsic_flags_pollute (&backup_flags);
>
>        riscv_option_override ();
>        init_adjust_machine_modes ();
>        riscv_vector::reinit_builtins ();
>        riscv_vector::handle_pragma_vector ();
>
> -      riscv_pragma_intrinsic_flags_restore (&backup_flags);
> +      riscv_vector::riscv_pragma_intrinsic_flags_restore (&backup_flags);
>
>        /* Re-initialize after the flags are restored.  */
>        riscv_option_override ();
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index 3358e3887b95..651df2310da6 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -102,6 +102,15 @@ struct riscv_address_info {
>    int shift;
>  };
>
> +struct pragma_intrinsic_flags
> +{
> +  int intrinsic_target_flags;
> +  int intrinsic_riscv_vector_elen_flags;
> +  int intrinsic_riscv_zvl_flags;
> +  int intrinsic_riscv_zvb_subext;
> +  int intrinsic_riscv_zvk_subext;
> +};
> +
>  /* Routines implemented in riscv.cc.  */
>  extern const char *riscv_asm_output_opcode (FILE *asm_out_file, const char 
> *p);
>  extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx);
> @@ -569,6 +578,10 @@ enum avl_type
>    VLS = 2,
>  };
>  /* Routines implemented in riscv-vector-builtins.cc.  */
> +void
> +riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *);
> +void
> +riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *);
>  void init_builtins (void);
>  void reinit_builtins (void);
>  const char *mangle_builtin_type (const_tree);
> diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
> b/gcc/config/riscv/riscv-vector-builtins.cc
> index 41730c483ee1..c6ddbeea71e7 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -4505,6 +4505,83 @@ builtin_type_p (const_tree type)
>    return lookup_vector_type_attribute (type);
>  }
>
> +void
> +riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
> +{
> +  flags->intrinsic_target_flags = target_flags;
> +  flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
> +  flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
> +  flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
> +  flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
> +
> +  target_flags = target_flags
> +    | MASK_VECTOR;
> +
> +  riscv_zvl_flags = riscv_zvl_flags
> +    | MASK_ZVL32B
> +    | MASK_ZVL64B
> +    | MASK_ZVL128B;
> +
> +  riscv_vector_elen_flags = riscv_vector_elen_flags
> +    | MASK_VECTOR_ELEN_32
> +    | MASK_VECTOR_ELEN_64
> +    | MASK_VECTOR_ELEN_FP_16
> +    | MASK_VECTOR_ELEN_FP_32
> +    | MASK_VECTOR_ELEN_FP_64;
> +
> +  riscv_zvb_subext = riscv_zvb_subext
> +    | MASK_ZVBB
> +    | MASK_ZVBC
> +    | MASK_ZVKB;
> +
> +  riscv_zvk_subext = riscv_zvk_subext
> +    | MASK_ZVKG
> +    | MASK_ZVKNED
> +    | MASK_ZVKNHA
> +    | MASK_ZVKNHB
> +    | MASK_ZVKSED
> +    | MASK_ZVKSH
> +    | MASK_ZVKN
> +    | MASK_ZVKNC
> +    | MASK_ZVKNG
> +    | MASK_ZVKS
> +    | MASK_ZVKSC
> +    | MASK_ZVKSG
> +    | MASK_ZVKT;
> +}
> +
> +void
> +riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
> +{
> +  target_flags = flags->intrinsic_target_flags;
> +
> +  riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
> +  riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
> +  riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
> +  riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
> +}
> +
> +/* Helper for init_builtins in LTO.  */
> +static void
> +handle_pragma_vector_for_lto ()
> +{
> +  struct pragma_intrinsic_flags backup_flags;
> +
> +  riscv_pragma_intrinsic_flags_pollute (&backup_flags);
> +
> +  riscv_option_override ();
> +  init_adjust_machine_modes ();
> +
> +  register_builtin_types ();
> +
> +  handle_pragma_vector ();
> +  riscv_pragma_intrinsic_flags_restore (&backup_flags);
> +
> +  /* Re-initialize after the flags are restored.  */
> +  riscv_option_override ();
> +  init_adjust_machine_modes ();
> +}
> +
>  /* Initialize all compiler built-ins related to RVV that should be
>     defined at start-up.  */
>  void
> @@ -4513,9 +4590,11 @@ init_builtins ()
>    rvv_switcher rvv;
>    if (!TARGET_VECTOR)
>      return;
> -  register_builtin_types ();
> +
>    if (in_lto_p)
> -    handle_pragma_vector ();
> +    handle_pragma_vector_for_lto ();
> +  else
> +    register_builtin_types ();
>  }
>
>  /* Reinitialize builtins similar to init_builtins,  but only the null
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
> new file mode 100644
> index 000000000000..c6b49da0768e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
> @@ -0,0 +1,18 @@
> +/* Test that we do not have ice when compile */
> +
> +/* { dg-do run } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=zvl -flto -O2 
> -fno-checking" } */
> +
> +#include <riscv_vector.h>
> +
> +int
> +main ()
> +{
> +  size_t vl = 8;
> +  vint32m1_t vs1 = {};
> +  vint32m1_t vs2 = {};
> +
> +  __volatile__ vint32m1_t vd = __riscv_vadd_vv_i32m1(vs1, vs2, vl);
> +
> +  return 0;
> +}
> --
> 2.17.1
>

Reply via email to