From: Alfie Richards <[email protected]>
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: Add exclusions.
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 | 30 +++++++++++++++++--
gcc/c/c-decl.cc | 6 ++++
gcc/c/c-parser.cc | 7 +++++
gcc/testsuite/gcc.target/aarch64/mv-error11.c | 9 ++++++
gcc/testsuite/gcc.target/aarch64/mv-error12.c | 13 ++++++++
5 files changed, 62 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error11.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error12.c
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index df9ff9947a8..5bc5183f421 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -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,
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 825487529d0..eed87258d40 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -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);
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index df44a915ed4..7c2452644bd 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -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
index 00000000000..58c9b3fbfa6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mv-error11.c
@@ -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
index 00000000000..45da85a67b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mv-error12.c
@@ -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." } */
--
2.34.1