> 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
>
> <https://github.com/gcc-mirror/gcc/commit/42ce61eaefc4db70e2e7ea2d8ef091daa458eb48
> >
Yes, march=rv32imaf_zca/mabi=ilp32 still not able to select
march=rv32imac/mabi=ilp32.
In my opinion that in order to imply C from zca and f ext, the arch must
contain zcf, because C+F is equivalent to F+Zca+Zcf and vice versa. The arch
rv32imaf_zca contains F and zca but no zcf so we cannot imply C and therefore
multilb rv32imac/mabi=ilp32 cannot be selected.
------------------------------------------------------------------
发件人:Kito Cheng <kito.ch...@gmail.com>
发送时间:2025年5月28日(周三) 18:11
收件人:yunzezhu<yunze...@linux.alibaba.com>
抄 送:"gcc-patches"<gcc-patches@gcc.gnu.org>
主 题:Re: [PATCH] [RFC] RISC-V: Add extra check to help choosing multilib with
equivalent arch.
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
<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
>