https://gcc.gnu.org/g:e7e5a1180b0e6b1be3ffd9c1222e492139607c67
commit e7e5a1180b0e6b1be3ffd9c1222e492139607c67 Author: Yuriy Kolerov <yuriy.kole...@synopsys.com> Date: Thu Apr 24 21:22:16 2025 -0600 [PATCH] RISC-V: Imply C from Zca whenever possible [PR119122] 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 (riscv_implied_info): 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. (cherry picked from commit 42ce61eaefc4db70e2e7ea2d8ef091daa458eb48) Diff: --- gcc/common/config/riscv/riscv-common.cc | 31 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/arch-25.c | 2 +- gcc/testsuite/gcc.target/riscv/attribute-c-1.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-2.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-3.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-4.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-5.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-6.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-7.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-c-8.c | 6 +++++ gcc/testsuite/gcc.target/riscv/attribute-zce-1.c | 2 +- gcc/testsuite/gcc.target/riscv/attribute-zce-2.c | 2 +- gcc/testsuite/gcc.target/riscv/attribute-zce-3.c | 2 +- gcc/testsuite/gcc.target/riscv/attribute-zce-4.c | 2 +- 14 files changed, 84 insertions(+), 5 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index b34409adf39c..15df22d53770 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -218,6 +218,37 @@ static const riscv_implied_info_t riscv_implied_info[] = { return subset_list->xlen () == 32 && subset_list->lookup ("f"); }}, + {"zca", "c", + [] (const riscv_subset_list *subset_list) -> bool + { + /* For RV32 Zca implies C for one of these combinations of + extensions: Zca, F_Zca_Zcf and FD_Zca_Zcf_Zcd. */ + if (subset_list->xlen () == 32) + { + if (subset_list->lookup ("d")) + return subset_list->lookup ("zcf") && subset_list->lookup ("zcd"); + + if (subset_list->lookup ("f")) + return subset_list->lookup ("zcf"); + + return true; + } + + /* For RV64 Zca implies C for one of these combinations of + extensions: Zca and FD_Zca_Zcd (Zcf is not available + for RV64). */ + if (subset_list->xlen () == 64) + { + if (subset_list->lookup ("d")) + return subset_list->lookup ("zcd"); + + return true; + } + + /* Do nothing for future RV128 specification. Behaviour + for this case is not yet well defined. */ + return false; + }}, {"smaia", "ssaia"}, {"smstateen", "ssstateen"}, diff --git a/gcc/testsuite/gcc.target/riscv/arch-25.c b/gcc/testsuite/gcc.target/riscv/arch-25.c index 3be4ade65a77..9201883dfb31 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-25.c +++ b/gcc/testsuite/gcc.target/riscv/arch-25.c @@ -2,4 +2,4 @@ /* { dg-options "-march=rv64i_zcf -mabi=lp64" } */ int foo() {} /* { dg-error "'-march=rv64i_zcf': zcf extension supports in rv32 only" "" { target *-*-* } 0 } */ -/* { dg-error "'-march=rv64i_zca_zcf': zcf extension supports in rv32 only" "" { target *-*-* } 0 } */ +/* { dg-error "'-march=rv64ic_zca_zcf': zcf extension supports in rv32 only" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-1.c b/gcc/testsuite/gcc.target/riscv/attribute-c-1.c new file mode 100644 index 000000000000..5627e16f6717 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32i_zca -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_c2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-2.c b/gcc/testsuite/gcc.target/riscv/attribute-c-2.c new file mode 100644 index 000000000000..4c7d5f902e30 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32if_zca -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_zicsr2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-3.c b/gcc/testsuite/gcc.target/riscv/attribute-c-3.c new file mode 100644 index 000000000000..7ff68f7749e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32if_zca_zcf -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcf1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-4.c b/gcc/testsuite/gcc.target/riscv/attribute-c-4.c new file mode 100644 index 000000000000..ef59b6580e43 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32ifd_zca_zcf -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcf1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-5.c b/gcc/testsuite/gcc.target/riscv/attribute-c-5.c new file mode 100644 index 000000000000..14e95516cc59 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-5.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32ifd_zca_zcf_zcd -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0_zcf1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-6.c b/gcc/testsuite/gcc.target/riscv/attribute-c-6.c new file mode 100644 index 000000000000..30cda5512a0a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64i_zca -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_c2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-7.c b/gcc/testsuite/gcc.target/riscv/attribute-c-7.c new file mode 100644 index 000000000000..b06388b0ce33 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-7.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64ifd_zca -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_d2p2_zicsr2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-8.c b/gcc/testsuite/gcc.target/riscv/attribute-c-8.c new file mode 100644 index 000000000000..fa760505d44e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-8.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64ifd_zca_zcd -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c index e477414d4d5c..fc86dbe2a005 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c index 7008eb5ea1fe..4504158dab13 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c index 89ebaaf40639..4ffc05119e62 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c index cacbcaac35f2..7ee8de2e3083 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */