On 3/5/25 5:05 AM, Yuriy Kolerov wrote:
GCC must imply C extension from Zca extension when it's
possible. It's necessary for achieving compatibility
between different march strings which in fact may be
the same.

E.g., if rv32ic multilib configuration is presented in
GCC, then GCC will not choose this configuration for
linking if -march=rv32i_zca is passed.

Here is a more practical example. From RISC-V
Instruction Set Manual:

     Therefore common ISA strings can be updated as follows
     to include the relevant Zc extensions, for example:
         - RV32IMC becomes RV32IM_Zce
         - RV32IMCF becomes RV32IMF_Zce

With current implication rules this will not work well
if rv32imc configuration is presented and a user
passes -march=rv32im_zce. This is how we can check
this with a simple empty test.c source file:

$ riscv64-unknown-elf-gcc -march=rv32ic -mabi=ilp32 -mriscv-attribute -S test.c
$ grep "attribute arch" test.s
         .attribute arch, "rv32i2p1_c2p0_zca1p0"
$ riscv64-unknown-elf-gcc -march=rv32i_zce -mabi=ilp32 -mriscv-attribute -S 
test.c
$ grep "attribute arch" test.s
         .attribute arch, 
"rv32i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0"

According to current GCC these march strings are
incompatible: the first one contains c2p0 and the
second on doesn't.

To introduce such implication rule we need to carefully
cover all possible combinations with these extensions:
zca, zcf, zcd, F and D.

According to the same manual:

     As C defines the same instructions as Zca, Zcf and
     Zcd, the rule is that:
         - C always implies Zca
         - C+F implies Zcf (RV32 only)
         - C+D implies Zcd

Here is a full list of cases:

     1. rv32i_zca implies C.
     2. rv32if_zca_zcf implies C.
     3. rv32ifd_zca_zcf_zcd implies C.
     4. rv64i_zca implies C.
     5. rv64ifd_zca_zcd implies C.

        PR target/119122

gcc/ChangeLog:

        * common/config/riscv/riscv-common.cc: add a rule for
        Zca to C implication.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/arch-25.c: Fix dg-error expectation.
        * gcc.target/riscv/attribute-c-1.c: New test.
        * gcc.target/riscv/attribute-c-2.c: New test.
        * gcc.target/riscv/attribute-c-3.c: New test.
        * gcc.target/riscv/attribute-c-4.c: New test.
        * gcc.target/riscv/attribute-c-5.c: New test.
        * gcc.target/riscv/attribute-c-6.c: New test.
        * gcc.target/riscv/attribute-c-7.c: New test.
        * gcc.target/riscv/attribute-c-8.c: New test.
        * gcc.target/riscv/attribute-zce-1.c: Update Zce tests.
        * gcc.target/riscv/attribute-zce-2.c: Likewise.
        * gcc.target/riscv/attribute-zce-3.c: Likewise
        * gcc.target/riscv/attribute-zce-4.c: Likewise.
IMHO this is fairly non-intuitive and I wouldn't be terribly surprised if the implications nonsense ends up causing end-user confusion in the long term. But that's really an issue for RVI, not GCC.

2.94. MISA.C is probably a good additional reference here:

MISA.C is set if the following extensions are selected:
⚫ Zca and not F
⚫ Zca, Zcf and F is specified (RV32 only)
⚫ Zca, Zcf and Zcd if D is specified (RV32 only)
⚫ this configuration excludes Zcmp, Zcmt
⚫ Zca, Zcd if D is specified (RV64 only)
⚫ this configuration excludes Zcmp, Zcmt

Based on the above this patch looks correct to me. It's not a regression fix so it's really not the right time to include it though. Deferred to gcc-16.


Jeff

Reply via email to