https://gcc.gnu.org/g:4157d59413a5f35808603e06de06cfb388811a65

commit 4157d59413a5f35808603e06de06cfb388811a65
Author: Christoph Müllner <christoph.muell...@vrull.eu>
Date:   Sat Jul 6 17:03:18 2024 +0200

    RISC-V: Allow adding enabled extension via target arch attributes
    
    The set of enabled extensions can be extended via target arch function
    attributes by listing each extension with a '+' prefix and a comma as
    list separator.  E.g.:
      __attribute__((target("arch=+zba,+zbb"))) void foo();
    
    The programmer intends to ensure that one or more extensions
    are enabled when building the code.  This is independent of the arch
    string that is passed at build time via the -march= option.
    
    Therefore, it is reasonable to allow enabling extensions via target arch
    attributes, which have already been enabled via the -march= string.
    
    The subset list code already supports such duplication for implied
    extensions.  This patch adds an interface so the subset list
    parser can be switched into a mode where duplication is allowed.
    
    This commit fixes the following regressed test cases:
    * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-39.c
    * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-42.c
    * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-43.c
    * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-44.c
    * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-45.c
    * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-46.c
    
    gcc/ChangeLog:
    
            * common/config/riscv/riscv-common.cc (riscv_subset_list::add):
            Allow adding enabled extension if m_allow_adding_dup is set.
            * config/riscv/riscv-subset.h: Add m_allow_adding_dup and setter.
            * config/riscv/riscv-target-attr.cc 
(riscv_target_attr_parser::parse_arch):
            Allow adding enabled extensions.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/pr115554.c: Change expected fail to expected 
pass.
            * gcc.target/riscv/target-attr-16.c: New test.
    
    Signed-off-by: Christoph Müllner <christoph.muell...@vrull.eu>
    (cherry picked from commit 61c21a719e205f70bd046c6a0275d1a3fd6341a4)

Diff:
---
 gcc/common/config/riscv/riscv-common.cc         | 17 +++++++++------
 gcc/config/riscv/riscv-subset.h                 |  5 +++++
 gcc/config/riscv/riscv-target-attr.cc           |  3 +++
 gcc/testsuite/gcc.target/riscv/pr115554.c       |  2 --
 gcc/testsuite/gcc.target/riscv/target-attr-16.c | 28 +++++++++++++++++++++++++
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 8e9beb6801f9..682826c0e344 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -702,12 +702,17 @@ riscv_subset_list::add (const char *subset, int 
major_version,
          ext->minor_version = minor_version;
        }
       else
-       error_at (
-         m_loc,
-         "%<-march=%s%>: extension %qs appear more than one time",
-         m_arch,
-         subset);
-
+       {
+         /* The extension is already in the list.  */
+         if (!m_allow_adding_dup
+             || ext->major_version != major_version
+             || ext->minor_version != minor_version)
+           error_at (
+             m_loc,
+             "%<-march=%s%>: extension %qs appear more than one time",
+             m_arch,
+             subset);
+       }
       return;
     }
   else if (strlen (subset) == 1 && !standard_extensions_p (subset))
diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
index 279716feab57..dace4de65753 100644
--- a/gcc/config/riscv/riscv-subset.h
+++ b/gcc/config/riscv/riscv-subset.h
@@ -65,6 +65,9 @@ private:
   /* Number of subsets. */
   unsigned m_subset_num;
 
+  /* Allow adding the same extension more than once.  */
+  bool m_allow_adding_dup;
+
   riscv_subset_list (const char *, location_t);
 
   const char *parsing_subset_version (const char *, const char *, unsigned *,
@@ -109,6 +112,8 @@ public:
 
   void set_loc (location_t);
 
+  void set_allow_adding_dup (bool v) { m_allow_adding_dup = v; }
+
   void finalize ();
 };
 
diff --git a/gcc/config/riscv/riscv-target-attr.cc 
b/gcc/config/riscv/riscv-target-attr.cc
index 317806143949..57235c9c0a7e 100644
--- a/gcc/config/riscv/riscv-target-attr.cc
+++ b/gcc/config/riscv/riscv-target-attr.cc
@@ -109,6 +109,8 @@ riscv_target_attr_parser::parse_arch (const char *str)
                      ? riscv_subset_list::parse (local_arch_str, m_loc)
                      : riscv_cmdline_subset_list ()->clone ();
       m_subset_list->set_loc (m_loc);
+      m_subset_list->set_allow_adding_dup (true);
+
       while (token)
        {
          if (token[0] != '+')
@@ -134,6 +136,7 @@ riscv_target_attr_parser::parse_arch (const char *str)
          token = strtok_r (NULL, ",", &str_to_check);
        }
 
+      m_subset_list->set_allow_adding_dup (false);
       m_subset_list->finalize ();
       return true;
     }
diff --git a/gcc/testsuite/gcc.target/riscv/pr115554.c 
b/gcc/testsuite/gcc.target/riscv/pr115554.c
index e7dcde6276fa..16d5f63aac0b 100644
--- a/gcc/testsuite/gcc.target/riscv/pr115554.c
+++ b/gcc/testsuite/gcc.target/riscv/pr115554.c
@@ -9,5 +9,3 @@ extern
 __attribute__((target("arch=+zbb")))
 __attribute__((target("arch=+zbb")))
 void bar(void);
-
-/* { dg-error "extension 'zbb' appear more than one time" "" { target *-*-* } 
0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/target-attr-16.c 
b/gcc/testsuite/gcc.target/riscv/target-attr-16.c
new file mode 100644
index 000000000000..1c7badccdeee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/target-attr-16.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zba" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zba" { target { rv64 } } } */
+
+__attribute__((target("arch=+zba,+zbb")))
+void foo1 (void)
+{
+}
+
+__attribute__((target("arch=+zbb,+zbb")))
+void foo2 (void)
+{
+}
+
+__attribute__((target("arch=+zba")))
+__attribute__((target("arch=+zbb")))
+void foo (void)
+{
+}
+
+__attribute__((target("arch=+zbb")))
+__attribute__((target("arch=+zbb")))
+void bar (void)
+{
+}
+
+/* { dg-final { scan-assembler-times ".option arch, 
rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zba1p0_zbb1p0"
 4 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times ".option arch, 
rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zba1p0_zbb1p0"
 4 { target { rv64 } } } } */

Reply via email to