aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandra Loosemore <sloosemore@baylibre.com>2025-02-09 21:34:36 +0000
committerSandra Loosemore <sloosemore@baylibre.com>2025-05-15 20:25:51 +0000
commit3dfe9733eabd74f21999dde36166bdedc5d06b1c (patch)
treeebc4543f3135e60e664faa3867c5845441a14bdb
parentd5a1822a5ccaa2ce7c35f04fcdcedfe92e209d84 (diff)
downloadgcc-3dfe9733eabd74f21999dde36166bdedc5d06b1c.zip
gcc-3dfe9733eabd74f21999dde36166bdedc5d06b1c.tar.gz
gcc-3dfe9733eabd74f21999dde36166bdedc5d06b1c.tar.bz2
OpenMP: C/C++ common testcases for "omp begin declare variant"
gcc/testsuite/ChangeLog * c-c++-common/gomp/delim-declare-variant-1.c: New. * c-c++-common/gomp/delim-declare-variant-2.c: New. * c-c++-common/gomp/delim-declare-variant-3.c: New. * c-c++-common/gomp/delim-declare-variant-4.c: New. * c-c++-common/gomp/delim-declare-variant-5.c: New. * c-c++-common/gomp/delim-declare-variant-6.c: New. * c-c++-common/gomp/delim-declare-variant-7.c: New. libgomp/ChangeLog * testsuite/libgomp.c-c++-common/delim-declare-variant-1.c: New.
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-1.c55
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-2.c66
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-3.c50
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-4.c31
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-5.c26
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-6.c71
-rw-r--r--gcc/testsuite/c-c++-common/gomp/delim-declare-variant-7.c27
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/delim-declare-variant-1.c45
8 files changed, 371 insertions, 0 deletions
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-1.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-1.c
new file mode 100644
index 0000000..28cac0d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-1.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+/* Check basic functionality for the delimited form of "declare variant"
+ - no error re duplicate definitions
+ - variants are registered and correctly resolved at call site. */
+
+int foo (int a)
+{
+ return a;
+}
+
+int bar (int x)
+{
+ return x;
+}
+
+#pragma omp begin declare variant match (construct={target})
+int foo (int a)
+{
+ return a + 1;
+}
+
+int bar (int x)
+{
+ return x * 2;
+}
+#pragma omp end declare variant
+
+/* Because of the high score value, this variant for "bar" should always be
+ selected even when the one above also matches. */
+#pragma omp begin declare variant match (implementation={vendor(score(10000):"gnu")})
+int bar (int x)
+{
+ return x * 4;
+}
+#pragma omp end declare variant
+
+int main (void)
+{
+ if (foo (42) != 42) __builtin_abort ();
+ if (bar (3) != 12) __builtin_abort ();
+#pragma omp target
+ {
+ if (foo (42) != 43) __builtin_abort ();
+ if (bar (3) != 12) __builtin_abort ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "omp declare variant base \\(foo.ompvariant." 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "omp declare variant base \\(bar.ompvariant." 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "foo \\(42\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "foo\\.ompvariant. \\(42\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "bar \\(3\\)" 0 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "bar\\.ompvariant. \\(3\\)" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-2.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-2.c
new file mode 100644
index 0000000..03bfe27
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-2.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-foffload=disable -fdump-tree-original" } */
+
+/* Check for elision of preprocessed code in a begin/end declare variant
+ construct when it can be determined at parse time that the selector
+ can never match. */
+
+int foobar (int x, int y)
+{
+ return x * y;
+}
+
+int baz (int x)
+{
+ return x;
+}
+
+#pragma omp begin declare variant match (implementation={vendor("acme")}) /* { dg-warning "unknown property" } */
+int foobar (int x, int y)
+{
+ random junk that would ordinarily cause a parse error;
+ return x + y;
+}
+#pragma omp end declare variant
+
+#pragma omp begin declare variant match (device={kind(fpga)})
+int foobar (int x, int y)
+{
+ random junk that would ordinarily cause a parse error;
+ return x + y;
+}
+#pragma omp end declare variant
+
+/* Per the OpenMP specification, elision only happens when the implementation
+ or device selectors cannot match; the user/condition selector doesn't
+ matter for this. */
+#pragma omp begin declare variant match (user={condition (0)})
+int foobar (int x, int y)
+{
+ return x + y;
+}
+#pragma omp end declare variant
+
+/* Check that we're finding the right "omp end declare variant" when
+ constructs are nested. */
+#pragma omp begin declare variant match (implementation={vendor("acme")}) /* { dg-warning "unknown property" } */
+ #pragma omp begin declare variant match (device={kind(fpga)})
+ int baz (int x)
+ {
+ random junk that would ordinarily cause a parse error;
+ return x + 1;
+ }
+ #pragma omp end declare variant
+ #pragma omp begin declare variant match (device={kind(host)})
+ int baz (int x)
+ {
+ random junk that would ordinarily cause a parse error;
+ return x + 2;
+ }
+ #pragma omp end declare variant
+#pragma omp end declare variant
+
+/* { dg-final { scan-tree-dump-times "foobar.ompvariant" 1 "original" } } */
+/* { dg-final { scan-tree-dump-not "baz.ompvariant" "original" } } */
+
+
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-3.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-3.c
new file mode 100644
index 0000000..63d10d7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-3.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+
+/* Check that an error is diagnosed when a function defined in a
+ "begin declare variant" construct doesn't have a visible declaration
+ at that point.
+
+ The spec is not completely clear on this; it says the base function must be
+ "declared elsewhere without an associated declare variant directive",
+ without defining what "elsewhere" means. Particularly in C++ it would be
+ incorrect to inject such a declaration at the point of the variant
+ definition (think of a variant for a class method that is defined with a
+ qualified name outside of the class declaration, for instance). The C++
+ front end could differentiate between cases where base declaration injection
+ is allowed vs not, but for now it seems simplest just to require that a
+ definition always be visible. */
+
+/* This declaration of baz is incompatible with the variant below. */
+extern double baz (double, double);
+
+/* This is not a function at all. */
+extern int quux;
+
+#pragma omp begin declare variant match (construct={target})
+int foo (int a) /* { dg-error "no previous declaration of base function" } */
+{
+ return a + 1;
+}
+
+int bar (int x) /* { dg-error "no previous declaration of base function" } */
+{
+ return x * 2;
+}
+
+int baz (int x) /* { dg-error "variant function definition does not match previous declaration of .baz." } */
+{
+ return x * 2;
+}
+
+int quux (int x, int y) /* { dg-error "variant function definition does not match previous declaration of .quux." } */
+{
+ return x + y;
+}
+#pragma omp end declare variant
+
+/* This later definition of foo doesn't count for resolving the variant
+ above. */
+int foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-4.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-4.c
new file mode 100644
index 0000000..f6726ab
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-4.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+
+/* Check that a proper error is diagnosed if an "omp begin declare variant"
+ construct has an invalid selector, and that this causes the whole variant
+ to be skipped over rather than a duplicate definition error. */
+
+int foo (int a)
+{
+ return a;
+}
+
+#pragma omp begin declare variant match (construct=target) /* { dg-error "expected '\{' before 'target'" } */
+int foo (int a)
+{
+ return a + 1;
+}
+
+#pragma omp end declare variant
+
+int bar (int x)
+{
+ return x;
+}
+
+#pragma omp begin declare variant match (gibberish = {blah(1)}) /* { dg-error "expected context selector set name" } */
+int bar (int x)
+{
+ return x + 2;
+}
+
+#pragma omp end declare variant
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-5.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-5.c
new file mode 100644
index 0000000..4e1645b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-5.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+
+/* Check that the simd trait is rejected in the match clause for
+ "begin declare variant". */
+
+int foo (int a)
+{
+ return a;
+}
+
+int bar (int x)
+{
+ return x;
+}
+
+#pragma omp begin declare variant match (construct={target, simd}) /* { dg-error "the 'simd' selector is not permitted" } */
+int foo (int a)
+{
+ return a + 1;
+}
+
+int bar (int x)
+{
+ return x * 2;
+}
+#pragma omp end declare variant
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-6.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-6.c
new file mode 100644
index 0000000..9b03b00
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-6.c
@@ -0,0 +1,71 @@
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-additional-options "-fdump-tree-gimple -foffload=disable" } */
+
+/* Test merging of context selectors for nested "begin declare variant"
+ directives.
+
+ The spec (TR12) says: "the effective context selectors of the outer
+ directive are appended do the context selector of the inner directive to
+ form the effective context selector of the inner directive. If a
+ trait-set-selector is present on both directives, the trait-selector list of
+ the outer directive is appended to the trait-selector list of the inner
+ directive after equivalent trait-selectors have been removed from the outer
+ list." */
+
+int f1 (int x) { return x; }
+int f2 (int x) { return x; }
+int f3 (int x) { return x; }
+int f4 (int x) { return x; }
+int f5 (int x) { return x; }
+
+/* Check that duplicate traits can be detected, even when the properties
+ use different forms. (If these were considered different, it would
+ trigger an error instead.) */
+#pragma omp begin declare variant match (implementation={vendor(gnu)})
+#pragma omp begin declare variant match (implementation={vendor("gnu")})
+int f1 (int x) { return -x; }
+#pragma omp end declare variant
+#pragma omp end declare variant
+
+#pragma omp begin declare variant match (implementation={vendor("gnu")})
+#pragma omp begin declare variant match (implementation={vendor(gnu)})
+int f2 (int x) { return -x; }
+#pragma omp end declare variant
+#pragma omp end declare variant
+
+/* Check that non-duplicate traits are collected from both inner and outer. */
+
+#pragma omp begin declare variant match (device={kind("host")})
+#pragma omp begin declare variant match (device={arch("x86_64")})
+int f3 (int x) { return -x; }
+#pragma omp end declare variant
+#pragma omp end declare variant
+/* { dg-final { scan-tree-dump "f3\\.ompvariant.*kind \\(.host.\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "f3\\.ompvariant.*arch \\(.x86_64.\\)" "gimple" } } */
+
+/* Check that traits for construct selectors merge as expected. */
+
+#pragma omp begin declare variant match (construct={parallel, for})
+#pragma omp begin declare variant match (construct={teams})
+int f4 (int x) { return -x; }
+#pragma omp end declare variant
+#pragma omp end declare variant
+/* { dg-final { scan-tree-dump "f4\\.ompvariant.*teams, parallel, for" "gimple" } } */
+
+/* Check that multiple trait sets are collected. */
+
+extern int flag;
+
+#pragma omp begin declare variant match (construct={parallel, for})
+#pragma omp begin declare variant match (construct={teams})
+#pragma omp begin declare variant match (user={condition(flag)})
+#pragma omp begin declare variant match (device={kind("host")})
+int f5 (int x) { return -x; }
+#pragma omp end declare variant
+#pragma omp end declare variant
+#pragma omp end declare variant
+#pragma omp end declare variant
+/* { dg-final { scan-tree-dump "f5\\.ompvariant.*teams, parallel, for" "gimple" } } */
+/* { dg-final { scan-tree-dump "f5\\.ompvariant.*flag" "gimple" } } */
+/* { dg-final { scan-tree-dump "f5\\.ompvariant.*kind \\(.host.\\)" "gimple" } } */
+
diff --git a/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-7.c b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-7.c
new file mode 100644
index 0000000..49a1d53
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/delim-declare-variant-7.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+/* Test that merging of context selectors from an enclosing "begin declare
+ variant" directive applies to nested regular "declare variant" directives
+ (not just nested "begin declare variant", which is tested elsewhere). */
+
+extern int foo1 (int);
+extern int foo2 (int);
+
+#pragma omp begin declare variant match (implementation={vendor(gnu)})
+
+#pragma omp declare variant (foo1) \
+ match (construct={parallel,for})
+#pragma omp declare variant (foo2) \
+ match (device={kind(any)})
+extern int foo (int);
+
+#pragma omp end declare variant
+
+int foo (int x)
+{
+ return x + 42;
+}
+
+/* { dg-final { scan-tree-dump-times "omp declare variant base" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "vendor \\(.gnu.\\)" 2 "gimple" } } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/delim-declare-variant-1.c b/libgomp/testsuite/libgomp.c-c++-common/delim-declare-variant-1.c
new file mode 100644
index 0000000..916f8a6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/delim-declare-variant-1.c
@@ -0,0 +1,45 @@
+/* Check basic functionality for the delimited form of "declare variant"
+ - no error re duplicate definitions
+ - variants are registered and correctly resolved at call site. */
+
+int foo (int a)
+{
+ return a;
+}
+
+int bar (int x)
+{
+ return x;
+}
+
+#pragma omp begin declare variant match (construct={target})
+int foo (int a)
+{
+ return a + 1;
+}
+
+int bar (int x)
+{
+ return x * 2;
+}
+#pragma omp end declare variant
+
+/* Because of the high score value, this variant for "bar" should always be
+ selected even when the one above also matches. */
+#pragma omp begin declare variant match (implementation={vendor(score(10000):"gnu")})
+int bar (int x)
+{
+ return x * 4;
+}
+#pragma omp end declare variant
+
+int main (void)
+{
+ if (foo (42) != 42) __builtin_abort ();
+ if (bar (3) != 12) __builtin_abort ();
+#pragma omp target
+ {
+ if (foo (42) != 43) __builtin_abort ();
+ if (bar (3) != 12) __builtin_abort ();
+ }
+}