I thought this issue should be fixed when we implement those
implication rules correctly? Does march=rv32imaf_zca/mabi=ilp32 still
not able select march=rv32imac/mabi=ilp32 still happen after this[1]
patch?

[1] 
https://github.com/gcc-mirror/gcc/commit/42ce61eaefc4db70e2e7ea2d8ef091daa458eb48

On Wed, May 28, 2025 at 4:04 PM <yunze...@linux.alibaba.com> wrote:
>
> From: Yunze Zhu <yunze...@linux.alibaba.com>
>
> Currently when choosing multilib set for target like 
> march=rv32imaf_zca/mabi=ilp32,
> gnu toolchain reports "Cannot find suitable multilib set".
> This is because in current dependent extension zca implies c when has 
> combinations of extensions: Zca, F_Zca_Zcf or FD_Zca_Zcf_Zcd,
> and f_zca is not one of these combinations and therefore extension c can not 
> be implied,
> and multilib set march=rv32imac/mabi=ilp32 cannot be selected.
> The most accurate method to fix this problem is changing multilib in 
> MULTILIB_REQUIRED: march=rv32imac/mabi=ilp32
> to an equivalent one: march=rv32ima_zca/mabi=ilp32.
> However, this method may cause compatibility issues with multilib path in 
> previos toolchain.
> There is an alternative method that add an extra check in multilib selection 
> functions,
> which checks whether c extension in multilibs is subset of zc* extensions in 
> arch string.
> By this method not only totally matched multilib sets but equivalent multilib 
> subsets could be selected.
>
> gcc/ChangeLog:
>
>         * common/config/riscv/riscv-common.cc 
> (riscv_subset_list::match_score_inc_p): New Function.
>         * config/riscv/riscv-subset.h: New Function.
> ---
>  gcc/common/config/riscv/riscv-common.cc | 27 +++++++++++++++++++++++++
>  gcc/config/riscv/riscv-subset.h         |  2 ++
>  2 files changed, 29 insertions(+)
>
> diff --git a/gcc/common/config/riscv/riscv-common.cc 
> b/gcc/common/config/riscv/riscv-common.cc
> index a6d8763f032..f43899bb413 100644
> --- a/gcc/common/config/riscv/riscv-common.cc
> +++ b/gcc/common/config/riscv/riscv-common.cc
> @@ -412,12 +412,39 @@ riscv_subset_list::match_score (riscv_subset_list 
> *list) const
>    for (s = list->m_head; s != NULL; s = s->next)
>      if (this->lookup (s->name.c_str ()) != NULL)
>        score++;
> +    else if (this->match_score_inc_p (s->name.c_str (), list))
> +      score++;
>      else
>        return 0;
>
>    return score;
>  }
>
> +/* Check if given extension is equivalent to one or group of extensions
> +in given subset list.  */
> +bool
> +riscv_subset_list::match_score_inc_p (std::string name,
> +                                    riscv_subset_list *multilib) const
> +{
> +  if (name.compare ("c") != 0 || this->lookup ("zca") == NULL)
> +    return false;
> +
> +  /* Check equivalent requirment when having d extension in multilib.  */
> +  if (multilib->lookup ("d") != NULL)
> +    {
> +      if (multilib->xlen () == 32)
> +       return this->lookup ("zcf") != NULL && this->lookup ("zcd") != NULL;
> +      else
> +       return this->lookup ("zcd") != NULL;
> +    }
> +
> +  /* Check equivalent requirment when having f extension in multilib.  */
> +  if (multilib->lookup ("f") != NULL && multilib->xlen () == 32)
> +    return this->lookup ("zcf") != NULL;
> +
> +  return true;
> +}
> +
>  /* Get the rank for single-letter subsets, lower value meaning higher
>     priority.  */
>
> diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
> index c5d9fab4de9..f80210cd755 100644
> --- a/gcc/config/riscv/riscv-subset.h
> +++ b/gcc/config/riscv/riscv-subset.h
> @@ -114,6 +114,8 @@ public:
>
>    int match_score (riscv_subset_list *) const;
>
> +  bool match_score_inc_p (std::string, riscv_subset_list *) const;
> +
>    void set_loc (location_t);
>
>    void set_allow_adding_dup (bool v) { m_allow_adding_dup = v; }
> --
> 2.47.1
>

Reply via email to