]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: fmv: Prevent FMV being combined with other cloning/renaming extensions.
authorAlfie Richards <alfie.richards@arm.com>
Tue, 30 Sep 2025 12:25:25 +0000 (12:25 +0000)
committerAlfie Richards <alfie.richards@arm.com>
Thu, 2 Oct 2025 08:29:07 +0000 (08:29 +0000)
This patch adds exclusions and diagnostics to prevent function multi-versioning
being used with omp simd pragmas and renaming extensions.

This behaviour is forbidden by the ACLE as the expected behaviour is not clear.

gcc/c-family/ChangeLog:

* c-attribs.cc (attr_target_clones_exclusions): Add simd and omp
exclusions.
(attr_target_version_exclusions): New definition with simd and omp
exclusions.
(attr_omp_declare_simd_exclusions): New definition with target_version
and clones exclusions.
(attr_simd_exclusions): Ditto.
(c_common_gnu_attributes): Add new target_version, simd, and omp
declare simd variables.

gcc/c/ChangeLog:

* c-decl.cc (maybe_mark_function_versioned): Add diagnostic.
* c-parser.cc (c_finish_omp_declare_simd): Add diagnostic.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/mv-error11.c: New test.
* gcc.target/aarch64/mv-error12.c: New test.

gcc/c-family/c-attribs.cc
gcc/c/c-decl.cc
gcc/c/c-parser.cc
gcc/testsuite/gcc.target/aarch64/mv-error11.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/mv-error12.c [new file with mode: 0644]

index df9ff9947a890ef493534fdb5e290a7afed53304..5bc5183f421df9fa05de0cb241fd81ed76c13db7 100644 (file)
@@ -249,6 +249,29 @@ static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
   ATTR_EXCL ("always_inline", true, true, true),
   ATTR_EXCL ("target", TARGET_HAS_FMV_TARGET_ATTRIBUTE,
             TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE),
+  ATTR_EXCL ("omp declare simd", true, true, true),
+  ATTR_EXCL ("simd", true, true, true),
+  ATTR_EXCL (NULL, false, false, false),
+};
+
+static const struct attribute_spec::exclusions attr_target_version_exclusions[] =
+{
+  ATTR_EXCL ("omp declare simd", true, true, true),
+  ATTR_EXCL ("simd", true, true, true),
+  ATTR_EXCL (NULL, false, false, false),
+};
+
+static const struct attribute_spec::exclusions attr_omp_declare_simd_exclusions[] =
+{
+  ATTR_EXCL ("target_version", true, true, true),
+  ATTR_EXCL ("target_clones", true, true, true),
+  ATTR_EXCL (NULL, false, false, false),
+};
+
+static const struct attribute_spec::exclusions attr_simd_exclusions[] =
+{
+  ATTR_EXCL ("target_version", true, true, true),
+  ATTR_EXCL ("target_clones", true, true, true),
   ATTR_EXCL (NULL, false, false, false),
 };
 
@@ -536,7 +559,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
                              attr_target_exclusions },
   { "target_version",         1, 1, true, false, false, false,
                              handle_target_version_attribute,
-                             NULL },
+                             attr_target_version_exclusions},
   { "target_clones",          1, -1, true, false, false, false,
                              handle_target_clones_attribute,
                              attr_target_clones_exclusions },
@@ -563,7 +586,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
   { "returns_nonnull",        0, 0, false, true, true, false,
                              handle_returns_nonnull_attribute, NULL },
   { "omp declare simd",       0, -1, true,  false, false, false,
-                             handle_omp_declare_simd_attribute, NULL },
+                             handle_omp_declare_simd_attribute,
+                             attr_omp_declare_simd_exclusions },
   { "omp declare variant base", 0, -1, true,  false, false, false,
                              handle_omp_declare_variant_attribute, NULL },
   { "omp declare variant variant", 0, -1, true,  false, false, false,
@@ -572,7 +596,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
                              false, false,
                              handle_omp_declare_variant_attribute, NULL },
   { "simd",                  0, 1, true,  false, false, false,
-                             handle_simd_attribute, NULL },
+                             handle_simd_attribute, attr_simd_exclusions },
   { "omp declare target",     0, -1, true, false, false, false,
                              handle_omp_declare_target_attribute, NULL },
   { "omp declare target link", 0, 0, true, false, false, false,
index 825487529d067ac8a3ded459cbfe42e9b5de755d..632bbf057a33b5eb194f6b172fb988d6f9783f1a 100644 (file)
@@ -2094,6 +2094,12 @@ maybe_mark_function_versioned (tree decl)
 {
   if (!DECL_FUNCTION_VERSIONED (decl))
     {
+      /* Check if the name of the function has been overridden.  */
+      if (DECL_ASSEMBLER_NAME_SET_P (decl)
+         && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))[0] == '*')
+       error_at (DECL_SOURCE_LOCATION (decl),
+                 "cannot use function multiversioning on a renamed function");
+
       /* We need to insert function version now to make sure the correct
         pre-mangled assembler name is recorded.  */
       cgraph_node *node = cgraph_node::get_create (decl);
index df44a915ed4fb23e75fd634478495b02b8d4beb7..7c2452644bdeb2cd8789e71136240cdcce640f47 100644 (file)
@@ -27776,6 +27776,13 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
       clauses[0].type = CPP_EOF;
       return;
     }
+  if (DECL_FUNCTION_VERSIONED (fndecl))
+    {
+      error_at (DECL_SOURCE_LOCATION (fndecl),
+               "%<#pragma omp declare %s%> cannot be used with function "
+               "multi-versioning", kind);
+      return;
+    }
 
   if (parms == NULL_TREE)
     parms = DECL_ARGUMENTS (fndecl);
diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error11.c b/gcc/testsuite/gcc.target/aarch64/mv-error11.c
new file mode 100644 (file)
index 0000000..0fdd660
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+int fn () asm("name");
+int fn () { return 1; } /* { dg-error "cannot use function multiversioning on a renamed function" } */
+int fn [[gnu::target_version("sve")]] () { return 1; }
+
+int fn2 [[gnu::target_version("sve")]] () asm("name"); /* { dg-warning ".asm. declaration ignored due to conflict with previous rename" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error12.c b/gcc/testsuite/gcc.target/aarch64/mv-error12.c
new file mode 100644 (file)
index 0000000..45da85a
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+/* { dg-require-ifunc "" } */
+
+#pragma omp declare simd
+int fn [[gnu::target_version("sve")]] () { return 1; } /* { dg-error ".#pragma omp declare simd. cannot be used with function multi-versioning" } */
+
+#pragma omp declare simd
+int fn2 () { return 1; }
+
+int fn2 [[gnu::target_version("sve")]] (); /* { dg-warning "ignoring attribute .target_version. because it conflicts with attribute .omp declare simd." } */
+
+int fn3 [[gnu::target_version("sve")]] [[gnu::simd]] () { return 1; } /* { dg-warning "ignoring attribute .simd. because it conflicts with attribute .target_version." } */