When 'a' is put into riscv_combine_info, 'a' will only be added into
arch string only if zaamo *AND* zalrsc is there, so zalrsc only won't
trigger that.

On Tue, Jun 18, 2024 at 1:35 PM Patrick O'Neill <patr...@rivosinc.com> wrote:
>
>
>
> On Mon, Jun 17, 2024 at 5:51 PM Kito Cheng <kito.ch...@gmail.com> wrote:
>>
>> Maybe just add 'a' to riscv_combine_info and other logic to keep the
>> same (e.g. keep the logic for skip_zaamo_zalrsc)?
>
>
> I did consider unconditionally upgrading zaamo/zalrsc to ‘a’ (I think that’s 
> what you’re suggesting w/ riscv_combine_info).
> That could cause issues if users are trying to compile for a zalrsc-only chip 
> with an old version of binutils. If we upgrade zalrsc -> ‘a’ for both cc1 and 
> binutils then cc1 will emit amo ops instead of their lr/sc equivalent.
> GCC would end up emitting insns that are illegal for the user-provided -march 
> string.
>
> Patrick
>
>>
>> On Tue, Jun 18, 2024 at 8:03 AM Patrick O'Neill <patr...@rivosinc.com> wrote:
>> >
>> > Binutils 2.42 and before don't support Zaamo/Zalrsc. Promote Zaamo/Zalrsc 
>> > to
>> > 'a' in the -march string when assembling.
>> >
>> > This change respects Zaamo/Zalrsc when generating code.
>> >
>> > Testcases that check for the default isa string will fail with the old 
>> > binutils
>> > since zaamo/zalrsc aren't emitted anymore. All other Zaamo/Zalrsc testcases
>> > pass.
>> >
>> > gcc/ChangeLog:
>> >
>> >         * common/config/riscv/riscv-common.cc
>> >         (riscv_subset_list::to_string): Add toggle to promote Zaamo/Zalrsc
>> >         extensions to 'a'.
>> >         (riscv_arch_str): Ditto.
>> >         (riscv_expand_arch): Ditto.
>> >         (riscv_expand_arch_from_cpu): Ditto.
>> >         (riscv_expand_arch_upgrade_exts): New function. Wrapper around
>> >         riscv_expand_arch to preserve the function signature.
>> >         (riscv_expand_arch_no_upgrade_exts): Ditto
>> >         (riscv_expand_arch_from_cpu_upgrade_exts): New function. Wrapper 
>> > around
>> >         riscv_expand_arch_from_cpu to preserve the function signature.
>> >         (riscv_expand_arch_from_cpu_no_upgrade_exts): Ditto.
>> >         * config/riscv/riscv-protos.h (riscv_arch_str): Add toggle to 
>> > function
>> >         prototype.
>> >         * config/riscv/riscv-subset.h: Ditto.
>> >         * config/riscv/riscv-target-attr.cc (riscv_process_target_attr):
>> >         * config/riscv/riscv.cc (riscv_emit_attribute):
>> >         (riscv_declare_function_name):
>> >         * config/riscv/riscv.h (riscv_expand_arch): Remove.
>> >         (riscv_expand_arch_from_cpu): Ditto.
>> >         (riscv_expand_arch_upgrade_exts): Add toggle wrapper functions.
>> >         (riscv_expand_arch_no_upgrade_exts): Ditto.
>> >         (riscv_expand_arch_from_cpu_upgrade_exts): Ditto.
>> >         (riscv_expand_arch_from_cpu_no_upgrade_exts): Ditto.
>> >         (EXTRA_SPEC_FUNCTIONS): Ditto.
>> >         (OPTION_DEFAULT_SPECS): Use non-upgraded march string when 
>> > invoking the
>> >         compiler.
>> >         (ASM_SPEC): Use upgraded march string when invoking the assembler.
>> >
>> > Signed-off-by: Patrick O'Neill <patr...@rivosinc.com>
>> > ---
>> > v3 ChangeLog:
>> > Rebased on non-promoting patch.
>> > Wrap all Zaamo/Zalrsc upgrade code in #ifndef to prevent compiler
>> > warnings about unused/potentially undefined variables.
>> > Silence unused parameter warning with a voidcast.
>> > ---
>> > RFC since I'm not sure if this upgrade behavior is more trouble than
>> > it's worth - this is a pretty invasive change. Happy to iterate further
>> > or just drop these changes.
>> > ---
>> >  gcc/common/config/riscv/riscv-common.cc | 111 +++++++++++++++++++++---
>> >  gcc/config/riscv/riscv-protos.h         |   3 +-
>> >  gcc/config/riscv/riscv-subset.h         |   2 +-
>> >  gcc/config/riscv/riscv-target-attr.cc   |   4 +-
>> >  gcc/config/riscv/riscv.cc               |   7 +-
>> >  gcc/config/riscv/riscv.h                |  46 ++++++----
>> >  6 files changed, 137 insertions(+), 36 deletions(-)
>> >
>> > diff --git a/gcc/common/config/riscv/riscv-common.cc 
>> > b/gcc/common/config/riscv/riscv-common.cc
>> > index 1dc1d9904c7..05c26f73b73 100644
>> > --- a/gcc/common/config/riscv/riscv-common.cc
>> > +++ b/gcc/common/config/riscv/riscv-common.cc
>> > @@ -907,7 +907,7 @@ riscv_subset_list::add (const char *subset, bool 
>> > implied_p)
>> >     VERSION_P to determine append version info or not.  */
>> >
>> >  std::string
>> > -riscv_subset_list::to_string (bool version_p) const
>> > +riscv_subset_list::to_string (bool version_p, bool upgrade_exts) const
>> >  {
>> >    std::ostringstream oss;
>> >    oss << "rv" << m_xlen;
>> > @@ -916,10 +916,17 @@ riscv_subset_list::to_string (bool version_p) const
>> >    riscv_subset_t *subset;
>> >
>> >    bool skip_zifencei = false;
>> > -  bool skip_zaamo_zalrsc = false;
>> >    bool skip_zicsr = false;
>> >    bool i2p0 = false;
>> >
>> > +#ifndef HAVE_AS_MARCH_ZAAMO_ZALRSC
>> > +  bool upgrade_zaamo_zalrsc = false;
>> > +  bool has_a_ext = false;
>> > +  bool insert_a_ext = false;
>> > +  bool inserted_a_ext = false;
>> > +  riscv_subset_t *a_subset;
>> > +#endif
>> > +
>> >    /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifencei is
>> >       included in the base ISA.  */
>> >    if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
>> > @@ -945,8 +952,33 @@ riscv_subset_list::to_string (bool version_p) const
>> >    skip_zifencei = true;
>> >  #endif
>> >  #ifndef HAVE_AS_MARCH_ZAAMO_ZALRSC
>> > -  /* Skip since binutils 2.42 and earlier don't recognize zaamo/zalrsc.  
>> > */
>> > -  skip_zaamo_zalrsc = true;
>> > +  /* Upgrade Zaamo/Zalrsc extensions to 'a' since binutils 2.42 and 
>> > earlier
>> > +     don't recognize zaamo/zalrsc.  */
>> > +  upgrade_zaamo_zalrsc = upgrade_exts;
>> > +  if (upgrade_zaamo_zalrsc)
>> > +    {
>> > +      for (subset = m_head; subset != NULL; subset = subset->next)
>> > +       {
>> > +         if (subset->name == "a")
>> > +           has_a_ext = true;
>> > +         if (subset->name == "zaamo" || subset->name == "zalrsc")
>> > +           insert_a_ext = true;
>> > +       }
>> > +      if (insert_a_ext && !has_a_ext)
>> > +       {
>> > +         unsigned int major_version = 0, minor_version = 0;
>> > +         get_default_version ("a", &major_version, &minor_version);
>> > +         a_subset = new riscv_subset_t ();
>> > +         a_subset->name = "a";
>> > +         a_subset->implied_p = false;
>> > +         a_subset->major_version = major_version;
>> > +         a_subset->minor_version = minor_version;
>> > +       }
>> > +    }
>> > +#else
>> > +  /* Silence unused parameter warning when HAVE_AS_MARCH_ZAAMO_ZALRSC is
>> > +     set.  */
>> > +  (void) upgrade_exts;
>> >  #endif
>> >
>> >    for (subset = m_head; subset != NULL; subset = subset->next)
>> > @@ -959,12 +991,29 @@ riscv_subset_list::to_string (bool version_p) const
>> >           subset->name == "zicsr")
>> >         continue;
>> >
>> > -      if (skip_zaamo_zalrsc && subset->name == "zaamo")
>> > +#ifndef HAVE_AS_MARCH_ZAAMO_ZALRSC
>> > +      if (upgrade_zaamo_zalrsc && subset->name == "zaamo")
>> >         continue;
>> >
>> > -      if (skip_zaamo_zalrsc && subset->name == "zalrsc")
>> > +      if (upgrade_zaamo_zalrsc && subset->name == "zalrsc")
>> >         continue;
>> >
>> > +      if (upgrade_zaamo_zalrsc && insert_a_ext && !has_a_ext && 
>> > !inserted_a_ext)
>> > +       {
>> > +         gcc_assert (a_subset);
>> > +         /* Insert `a` extension in cannonical order.  */
>> > +         if (subset_cmp (a_subset->name, subset->name) > 0)
>> > +           {
>> > +             oss << a_subset->name;
>> > +             if (version_p)
>> > +               oss << a_subset->major_version
>> > +                   << 'p'
>> > +                   << a_subset->minor_version;
>> > +             inserted_a_ext = true;
>> > +           }
>> > +       }
>> > +#endif
>> > +
>> >        /* For !version_p, we only separate extension with underline for
>> >          multi-letter extension.  */
>> >        if (!first &&
>> > @@ -984,6 +1033,14 @@ riscv_subset_list::to_string (bool version_p) const
>> >              << subset->minor_version;
>> >      }
>> >
>> > +#ifndef HAVE_AS_MARCH_ZAAMO_ZALRSC
>> > +  if (upgrade_zaamo_zalrsc && insert_a_ext && !has_a_ext)
>> > +    {
>> > +      gcc_assert (inserted_a_ext);
>> > +      free (a_subset);
>> > +    }
>> > +#endif
>> > +
>> >    return oss.str ();
>> >  }
>> >
>> > @@ -1598,10 +1655,10 @@ riscv_subset_list::finalize ()
>> >  /* Return the current arch string.  */
>> >
>> >  std::string
>> > -riscv_arch_str (bool version_p)
>> > +riscv_arch_str (bool version_p, bool upgrade_exts)
>> >  {
>> >    if (current_subset_list)
>> > -    return current_subset_list->to_string (version_p);
>> > +    return current_subset_list->to_string (version_p, upgrade_exts);
>> >    else
>> >      return std::string();
>> >  }
>> > @@ -1907,18 +1964,33 @@ riscv_handle_option (struct gcc_options *opts,
>> >
>> >  const char *
>> >  riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
>> > -                  const char **argv)
>> > +                  const char **argv,
>> > +                  bool upgrade_exts)
>> >  {
>> >    gcc_assert (argc == 1);
>> >    location_t loc = UNKNOWN_LOCATION;
>> >    riscv_parse_arch_string (argv[0], NULL, loc);
>> > -  const std::string arch = riscv_arch_str (false);
>> > +  const std::string arch = riscv_arch_str (/*version_p*/ false, 
>> > upgrade_exts);
>> >    if (arch.length())
>> >      return xasprintf ("-march=%s", arch.c_str());
>> >    else
>> >      return "";
>> >  }
>> >
>> > +const char *
>> > +riscv_expand_arch_upgrade_exts (int argc ATTRIBUTE_UNUSED,
>> > +                               const char **argv)
>> > +{
>> > +  return riscv_expand_arch (argc, argv, /*upgrade_exts*/ true);
>> > +}
>> > +
>> > +const char *
>> > +riscv_expand_arch_no_upgrade_exts (int argc ATTRIBUTE_UNUSED,
>> > +                                  const char **argv)
>> > +{
>> > +  return riscv_expand_arch (argc, argv, /*upgrade_exts*/ false);
>> > +}
>> > +
>> >  /* Expand default -mtune option from -mcpu option, use default 
>> > --with-tune value
>> >     if -mcpu don't have valid value.  */
>> >
>> > @@ -1938,7 +2010,8 @@ riscv_default_mtune (int argc, const char **argv)
>> >
>> >  const char *
>> >  riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED,
>> > -                           const char **argv)
>> > +                           const char **argv,
>> > +                           bool upgrade_exts)
>> >  {
>> >    gcc_assert (argc > 0 && argc <= 2);
>> >    const char *default_arch_str = NULL;
>> > @@ -1961,10 +2034,24 @@ riscv_expand_arch_from_cpu (int argc 
>> > ATTRIBUTE_UNUSED,
>> >    location_t loc = UNKNOWN_LOCATION;
>> >
>> >    riscv_parse_arch_string (arch_str, NULL, loc);
>> > -  const std::string arch = riscv_arch_str (false);
>> > +  const std::string arch = riscv_arch_str (/*version_p*/ false, 
>> > upgrade_exts);
>> >    return xasprintf ("-march=%s", arch.c_str());
>> >  }
>> >
>> > +const char *
>> > +riscv_expand_arch_from_cpu_upgrade_exts (int argc ATTRIBUTE_UNUSED,
>> > +                                        const char **argv)
>> > +{
>> > +  return riscv_expand_arch_from_cpu (argc, argv, /*upgrade_exts*/ true);
>> > +}
>> > +
>> > +const char *
>> > +riscv_expand_arch_from_cpu_no_upgrade_exts (int argc ATTRIBUTE_UNUSED,
>> > +                                           const char **argv)
>> > +{
>> > +  return riscv_expand_arch_from_cpu (argc, argv, /*upgrade_exts*/ false);
>> > +}
>> > +
>> >  /* Report error if not found suitable multilib.  */
>> >  const char *
>> >  riscv_multi_lib_check (int argc ATTRIBUTE_UNUSED,
>> > diff --git a/gcc/config/riscv/riscv-protos.h 
>> > b/gcc/config/riscv/riscv-protos.h
>> > index d6473d0cd85..06b33c9f330 100644
>> > --- a/gcc/config/riscv/riscv-protos.h
>> > +++ b/gcc/config/riscv/riscv-protos.h
>> > @@ -183,7 +183,8 @@ extern tree riscv_builtin_decl (unsigned int, bool);
>> >  extern void riscv_init_builtins (void);
>> >
>> >  /* Routines implemented in riscv-common.cc.  */
>> > -extern std::string riscv_arch_str (bool version_p = true);
>> > +extern std::string riscv_arch_str (bool version_p = true,
>> > +                                  bool upgrade_exts = false);
>> >  extern void riscv_parse_arch_string (const char *, struct gcc_options *, 
>> > location_t);
>> >
>> >  extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
>> > diff --git a/gcc/config/riscv/riscv-subset.h 
>> > b/gcc/config/riscv/riscv-subset.h
>> > index fe7f54d8bc5..8384aab63cb 100644
>> > --- a/gcc/config/riscv/riscv-subset.h
>> > +++ b/gcc/config/riscv/riscv-subset.h
>> > @@ -90,7 +90,7 @@ public:
>> >                           int major_version = RISCV_DONT_CARE_VERSION,
>> >                           int minor_version = RISCV_DONT_CARE_VERSION) 
>> > const;
>> >
>> > -  std::string to_string (bool) const;
>> > +  std::string to_string (bool, bool) const;
>> >
>> >    unsigned xlen () const {return m_xlen;};
>> >
>> > diff --git a/gcc/config/riscv/riscv-target-attr.cc 
>> > b/gcc/config/riscv/riscv-target-attr.cc
>> > index 19eb7b06d54..42c2b439e66 100644
>> > --- a/gcc/config/riscv/riscv-target-attr.cc
>> > +++ b/gcc/config/riscv/riscv-target-attr.cc
>> > @@ -367,7 +367,9 @@ riscv_process_target_attr (tree fndecl, tree args, 
>> > location_t loc,
>> >    /* Add the string of the target attribute to the fndecl hash table.  */
>> >    riscv_subset_list *subset_list = attr_parser.get_riscv_subset_list ();
>> >    if (subset_list)
>> > -    riscv_func_target_put (fndecl, subset_list->to_string (true));
>> > +    riscv_func_target_put (fndecl,
>> > +                          subset_list->to_string (/*version_p*/ true,
>> > +                                                  /*upgrade_exts*/ true));
>> >
>> >    return true;
>> >  }
>> > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
>> > index c17141d909a..09943389986 100644
>> > --- a/gcc/config/riscv/riscv.cc
>> > +++ b/gcc/config/riscv/riscv.cc
>> > @@ -9425,8 +9425,10 @@ riscv_sched_adjust_cost (rtx_insn *, int, rtx_insn 
>> > *insn, int cost,
>> >  static void
>> >  riscv_emit_attribute ()
>> >  {
>> > +  /* Upgrade extensions if necessary for the assember to understand
>> > +     Eg. Zalrsc -> a.  */
>> >    fprintf (asm_out_file, "\t.attribute arch, \"%s\"\n",
>> > -          riscv_arch_str ().c_str ());
>> > +          riscv_arch_str (/*version_p*/ true, /*upgrade_exts*/ 
>> > true).c_str ());
>> >
>> >    fprintf (asm_out_file, "\t.attribute unaligned_access, %d\n",
>> >             TARGET_STRICT_ALIGN ? 0 : 1);
>> > @@ -9468,7 +9470,8 @@ riscv_declare_function_name (FILE *stream, const 
>> > char *name, tree fndecl)
>> >        std::string *target_name = riscv_func_target_get (fndecl);
>> >        std::string isa = target_name != NULL
>> >         ? *target_name
>> > -       : riscv_cmdline_subset_list ()->to_string (true);
>> > +       : riscv_cmdline_subset_list ()->to_string (/*version_p*/ true,
>> > +                                                  /*upgrade_exts*/ true);
>> >        fprintf (stream, "\t.option arch, %s\n", isa.c_str ());
>> >        riscv_func_target_remove_and_destory (fndecl);
>> >
>> > diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
>> > index 57910eecd3e..55d0a842bf2 100644
>> > --- a/gcc/config/riscv/riscv.h
>> > +++ b/gcc/config/riscv/riscv.h
>> > @@ -46,17 +46,24 @@ along with GCC; see the file COPYING3.  If not see
>> >  #define RISCV_TUNE_STRING_DEFAULT "rocket"
>> >  #endif
>> >
>> > -extern const char *riscv_expand_arch (int argc, const char **argv);
>> > -extern const char *riscv_expand_arch_from_cpu (int argc, const char 
>> > **argv);
>> > +extern const char *riscv_expand_arch_upgrade_exts (int argc, const char 
>> > **argv);
>> > +extern const char *riscv_expand_arch_no_upgrade_exts (int argc,
>> > +                                                     const char **argv);
>> > +extern const char *riscv_expand_arch_from_cpu_upgrade_exts (int argc,
>> > +                                                           const char 
>> > **argv);
>> > +extern const char *riscv_expand_arch_from_cpu_no_upgrade_exts (int argc,
>> > +                                                              const char 
>> > **argv);
>> >  extern const char *riscv_default_mtune (int argc, const char **argv);
>> >  extern const char *riscv_multi_lib_check (int argc, const char **argv);
>> >  extern const char *riscv_arch_help (int argc, const char **argv);
>> >
>> > -# define EXTRA_SPEC_FUNCTIONS                                          \
>> > -  { "riscv_expand_arch", riscv_expand_arch },                          \
>> > -  { "riscv_expand_arch_from_cpu", riscv_expand_arch_from_cpu },           
>> >      \
>> > -  { "riscv_default_mtune", riscv_default_mtune },                      \
>> > -  { "riscv_multi_lib_check", riscv_multi_lib_check },                  \
>> > +# define EXTRA_SPEC_FUNCTIONS                                             
>> >         \
>> > +  { "riscv_expand_arch_u", riscv_expand_arch_upgrade_exts },              
>> >         \
>> > +  { "riscv_expand_arch_nu", riscv_expand_arch_no_upgrade_exts },          
>> >         \
>> > +  { "riscv_expand_arch_from_cpu_nu", 
>> > riscv_expand_arch_from_cpu_no_upgrade_exts }, \
>> > +  { "riscv_expand_arch_from_cpu_u", 
>> > riscv_expand_arch_from_cpu_upgrade_exts },    \
>> > +  { "riscv_default_mtune", riscv_default_mtune },                         
>> >         \
>> > +  { "riscv_multi_lib_check", riscv_multi_lib_check },                     
>> >         \
>> >    { "riscv_arch_help", riscv_arch_help },
>> >
>> >  /* Support for a compile-time default CPU, et cetera.  The rules are:
>> > @@ -68,15 +75,15 @@ extern const char *riscv_arch_help (int argc, const 
>> > char **argv);
>> >
>> >     But using default -march/-mtune value if -mcpu don't have valid 
>> > option.  */
>> >  #define OPTION_DEFAULT_SPECS \
>> > -  {"tune", "%{!mtune=*:"                                               \
>> > -          "  %{!mcpu=*:-mtune=%(VALUE)}"                               \
>> > -          "  %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}" },  \
>> > -  {"arch", "%{!march=*:"                                               \
>> > -          "  %{!mcpu=*:-march=%(VALUE)}"                               \
>> > -          "  %{mcpu=*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}" },  \
>> > -  {"abi", "%{!mabi=*:-mabi=%(VALUE)}" },                               \
>> > -  {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" },                   
>> >      \
>> > -  {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"},                \
>> > +  {"tune", "%{!mtune=*:"                                                 \
>> > +          "  %{!mcpu=*:-mtune=%(VALUE)}"                                 \
>> > +          "  %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}" },    \
>> > +  {"arch", "%{!march=*:"                                                 \
>> > +          "  %{!mcpu=*:-march=%(VALUE)}"                                 \
>> > +          "  %{mcpu=*:%:riscv_expand_arch_from_cpu_nu(%* %(VALUE))}}" }, \
>> > +  {"abi", "%{!mabi=*:-mabi=%(VALUE)}" },                                 \
>> > +  {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" },                   
>> >        \
>> > +  {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"},                   
>> >        \
>> >
>> >  #ifdef IN_LIBGCC2
>> >  #undef TARGET_64BIT
>> > @@ -103,7 +110,8 @@ extern const char *riscv_arch_help (int argc, const 
>> > char **argv);
>> >  #define ASM_SPEC "\
>> >  %(subtarget_asm_debugging_spec) \
>> >  %{" FPIE_OR_FPIC_SPEC ":-fpic} \
>> > -%{march=*} \
>> > +%{march=*:%:riscv_expand_arch_u(%*)} \
>> > +%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu_u(%*)}} \
>> >  %{mabi=*} \
>> >  %{mno-relax} \
>> >  %{mbig-endian} \
>> > @@ -116,8 +124,8 @@ ASM_MISA_SPEC
>> >  "%{march=help:%:riscv_arch_help()} "                           \
>> >  "%{print-supported-extensions:%:riscv_arch_help()} "           \
>> >  "%{-print-supported-extensions:%:riscv_arch_help()} "          \
>> > -"%{march=*:%:riscv_expand_arch(%*)} "                          \
>> > -"%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu(%*)}} "
>> > +"%{march=*:%:riscv_expand_arch_nu(%*)} "                       \
>> > +"%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu_nu(%*)}} "
>> >
>> >  #define TARGET_DEFAULT_CMODEL CM_MEDLOW
>> >
>> > --
>> > 2.34.1
>> >

Reply via email to