https://gcc.gnu.org/g:fb0dad07be32276b35bae92a7a3c51fcd3daa972

commit fb0dad07be32276b35bae92a7a3c51fcd3daa972
Author: Paul-Antoine Arras <par...@baylibre.com>
Date:   Wed Nov 20 15:28:58 2024 +0100

    OpenMP: common C/C++ testcases for dispatch + adjust_args
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
            * c-c++-common/gomp/adjust-args-1.c: New test.
            * c-c++-common/gomp/adjust-args-2.c: New test.
            * c-c++-common/gomp/declare-variant-dup-match-clause.c: New test.
            * c-c++-common/gomp/dispatch-1.c: New test.
            * c-c++-common/gomp/dispatch-2.c: New test.
            * c-c++-common/gomp/dispatch-3.c: New test.
            * c-c++-common/gomp/dispatch-4.c: New test.
            * c-c++-common/gomp/dispatch-5.c: New test.
            * c-c++-common/gomp/dispatch-6.c: New test.
            * c-c++-common/gomp/dispatch-7.c: New test.
            * c-c++-common/gomp/dispatch-8.c: New test.
            * c-c++-common/gomp/dispatch-9.c: New test.
            * c-c++-common/gomp/dispatch-10.c: New test.
    
    libgomp/ChangeLog:
    
            * testsuite/libgomp.c-c++-common/dispatch-1.c: New test.
            * testsuite/libgomp.c-c++-common/dispatch-2.c: New test.
    
    (cherry picked from commit 377eff7c38e8df1388b0a1eeb6afdbcaf12c3551)

Diff:
---
 gcc/testsuite/ChangeLog.omp                        | 20 ++++++
 gcc/testsuite/c-c++-common/gomp/adjust-args-1.c    | 30 ++++++++
 gcc/testsuite/c-c++-common/gomp/adjust-args-2.c    | 31 ++++++++
 .../c-c++-common/gomp/declare-variant-2.c          |  4 +-
 .../gomp/declare-variant-dup-match-clause.c        |  6 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c       | 71 ++++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-10.c      | 36 ++++++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c       | 28 ++++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c       | 12 ++++
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c       | 18 +++++
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c       | 34 +++++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c       | 18 +++++
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c       | 21 ++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-8.c       | 63 ++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-9.c       | 17 +++++
 libgomp/ChangeLog.omp                              |  8 +++
 .../testsuite/libgomp.c-c++-common/dispatch-1.c    | 76 ++++++++++++++++++++
 .../testsuite/libgomp.c-c++-common/dispatch-2.c    | 84 ++++++++++++++++++++++
 18 files changed, 575 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 2162805e5708..ccec4308bf22 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,23 @@
+2025-01-27  Paul-Antoine Arras  <par...@baylibre.com>
+
+       Backported from master:
+       2024-11-20  Paul-Antoine Arras  <par...@baylibre.com>
+
+       * c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
+       * c-c++-common/gomp/adjust-args-1.c: New test.
+       * c-c++-common/gomp/adjust-args-2.c: New test.
+       * c-c++-common/gomp/declare-variant-dup-match-clause.c: New test.
+       * c-c++-common/gomp/dispatch-1.c: New test.
+       * c-c++-common/gomp/dispatch-2.c: New test.
+       * c-c++-common/gomp/dispatch-3.c: New test.
+       * c-c++-common/gomp/dispatch-4.c: New test.
+       * c-c++-common/gomp/dispatch-5.c: New test.
+       * c-c++-common/gomp/dispatch-6.c: New test.
+       * c-c++-common/gomp/dispatch-7.c: New test.
+       * c-c++-common/gomp/dispatch-8.c: New test.
+       * c-c++-common/gomp/dispatch-9.c: New test.
+       * c-c++-common/gomp/dispatch-10.c: New test.
+
 2025-01-27  Paul-Antoine Arras  <par...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000000000000..728abe620922
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000000000000..d2a4a5f4ec45
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match 
(construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp dispatch device" "gimple" } } 
*/
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c 
b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
index 43657486c996..27c1cdff0443 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
@@ -8,9 +8,9 @@ void f3 (void);
 void f4 (void);
 #pragma omp declare variant match(user={condition(0)}) /* { dg-error "expected 
'\\(' before 'match'" } */
 void f5 (void);
-#pragma omp declare variant (f1)       /* { dg-error "expected 'match' before 
end of line" } */
+#pragma omp declare variant (f1)       /* { dg-error "expected 'match' clause 
before end of line" } */
 void f6 (void);
-#pragma omp declare variant (f1) simd  /* { dg-error "expected 'match' before 
'simd'" } */
+#pragma omp declare variant (f1) simd  /* { dg-error "expected 'match' clause 
before 'simd'" } */
 void f7 (void);
 #pragma omp declare variant (f1) match /* { dg-error "expected '\\(' before 
end of line" } */
 void f8 (void);
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-dup-match-clause.c 
b/gcc/testsuite/c-c++-common/gomp/declare-variant-dup-match-clause.c
new file mode 100644
index 000000000000..14dc681b59de
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-dup-match-clause.c
@@ -0,0 +1,6 @@
+/* Check that errors are detected if a match clause appears more than once, 
+   even if compatible.  */
+
+void f();
+#pragma omp declare variant(f) match(construct={target}) 
match(construct={target})  /* { dg-error "too many 'match' clauses" } */
+void g(); 
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-1.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-1.c
new file mode 100644
index 000000000000..2a4e939d0002
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-1.c
@@ -0,0 +1,71 @@
+#include <stdint.h>
+
+int f0 (int, long, double);
+void f2 (void);
+int f3 (void);
+void (*f4) (void);
+void f5 (int*, int);
+
+int *pp (void);
+int dd (void);
+
+void f1 (void)
+{
+  int a, c;
+  long b;
+  double x;
+  struct {int a; float b; short c;} s, *sp;
+  int arr[3];
+
+#pragma omp dispatch
+  c = f0 (a, b, x);
+#pragma omp dispatch
+  x = f0 (a * 4, 2 - b, x * x);
+#pragma omp dispatch
+  s.a = f0 (a, sp->c, x);
+#pragma omp dispatch
+  sp->c = f0 (s.a - 2, b / 3, x * 5);
+#pragma omp dispatch
+  arr[0] = f0 (arr[1], !b, arr[2]);
+#pragma omp dispatch
+  (*sp).c = f0 (s.a, b, x);
+#pragma omp dispatch
+  sp->b = f0 (s.a++, b % 4, --x);
+#pragma omp dispatch
+  f0 (f3(), b, s.b);
+#pragma omp dispatch
+  f2 ();
+#pragma omp dispatch
+  f4 ();
+#pragma omp dispatch
+  f5 (pp(), pp()[dd()]);
+  
+#pragma omp dispatch nocontext(sp->a * x + arr[2])
+  f2 ();
+#pragma omp dispatch nocontext(arr - (intptr_t)(x / s.b))
+  f2 ();
+#pragma omp dispatch nocontext(x == s.c || b != c)
+  f2 ();
+#pragma omp dispatch novariants(b << sp->c)
+  f2 ();
+#pragma omp dispatch novariants(!arr | s.a)
+  f2 ();
+#pragma omp dispatch novariants(s.c ? f3() : a & c)
+  f2 ();
+#pragma omp dispatch nowait
+  f2 ();
+#pragma omp dispatch device(-25373654)
+  f2 ();
+#pragma omp dispatch device(b * (int)(x - sp->b))
+  f2 ();
+#pragma omp dispatch is_device_ptr(arr)
+  f2 ();
+#pragma omp dispatch is_device_ptr(sp)
+  f2 ();
+#pragma omp dispatch depend(inout: sp)
+  f2 ();
+#pragma omp dispatch depend(inoutset: arr[:2])
+  f2 ();
+#pragma omp dispatch depend(out: arr)
+  f2 ();
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-10.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-10.c
new file mode 100644
index 000000000000..40b3fc89a123
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-10.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int *f();
+
+struct t {
+  int *a, *b;
+};
+
+void construct(int *x, int *y);
+void noconstruct(int *x, int *y);
+
+#pragma omp declare variant(construct) match(construct={dispatch}) 
adjust_args(need_device_ptr: x,y)
+#pragma omp declare variant(noconstruct) match(implementation={vendor(gnu)})
+void bar(int *x, int *y);
+
+int nocontext, novariant;
+
+void sub(struct t *s, void *y)
+{
+    bar( f(), s->b);
+ #pragma omp dispatch device(0) is_device_ptr(s)
+    bar( f(), s->b);
+    
+    bar( (int *) y, s->b);
+ #pragma omp dispatch device(0) is_device_ptr(y)
+    bar( (int *) y, s->b);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device" 2 
"gimple" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device" 4 
"gimple" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device 
\\(0\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device 
\\(D\\.\[0-9\]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_mapped_ptr" 3 "gimple" 
} } */
+/* { dg-final { scan-tree-dump-times "D\\.\[0-9\]+ = s->b;\[\r\n\]* 
*D\\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(D\\.\[0-9\]+, 0\\);" 2 "gimple" 
} } */
+/* { dg-final { scan-tree-dump-times "D\\.\[0-9\]+ = f \\(\\);\[\r\n\]* 
*D\\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(D\\.\[0-9\]+, 0\\);" 1 "gimple" 
} } */
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-2.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-2.c
new file mode 100644
index 000000000000..24ab9545b73e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f0 (void);
+int f1 (void);
+#pragma omp declare variant (f0) match (construct={dispatch})
+#pragma omp declare variant (f1) match (implementation={vendor(gnu)})
+int f2 (void);
+
+int test (void)
+{
+  int a;
+#pragma omp dispatch
+  a = f2 ();
+#pragma omp dispatch novariants(1)
+  a = f2 ();
+#pragma omp dispatch novariants(0)
+  a = f2 ();
+#pragma omp dispatch nocontext(1)
+  a = f2 ();
+#pragma omp dispatch nocontext(0)
+  a = f2 ();
+  return a;
+}
+
+/* { dg-final { scan-tree-dump-times "a = f0 \\\(\\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "a = f1 \\\(\\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "a = f2 \\\(\\\);" 1 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-3.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-3.c
new file mode 100644
index 000000000000..dba1d4ffdc8c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+void f2 (void);
+
+void test (void)
+{
+#pragma omp dispatch  /* { dg-final { scan-tree-dump-not "#pragma omp task" 
"gimple" } } */
+  f2 ();
+#pragma omp dispatch nowait /* { dg-final { scan-tree-dump-not "nowait" 
"gimple" } } */
+  f2 ();
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-4.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-4.c
new file mode 100644
index 000000000000..ac746f755beb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-4.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+void f2 (int a);
+
+void test (void)
+{
+  int a;
+
+#pragma omp dispatch device(-25373654)
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device 
\\(-25373654\\);" 1 "gimple" } } */
+  f2 (a);
+#pragma omp dispatch device(a + a)
+/* { dg-final { scan-tree-dump-times "(D\.\[0-9]+) = a \\* 2;.*#pragma omp 
dispatch.*__builtin_omp_set_default_device \\(\\1\\);.*f2 \\(a\\)" 2 "gimple" } 
} */
+  f2 (a);
+}
+
+/* { dg-final { scan-tree-dump-times "(D\.\[0-9]+) = 
__builtin_omp_get_default_device \\(\\);.*__builtin_omp_set_default_device 
\\(\\1\\);" 4 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-5.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-5.c
new file mode 100644
index 000000000000..608c6d9f154e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-5.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+void f1 (void* p, int arr[]);
+#pragma omp declare variant (f1) match (construct={dispatch}) adjust_args 
(need_device_ptr: p, arr)
+void f2 (void* p, int arr[]);
+
+void test (void)
+{
+  void *p;
+  int arr[2];
+
+/* Note there are multiple matches because every variable capturing matches in 
addition,
+   i.e. scan-tree-dump-times = 1 plus number of captures used for backward 
references.
+
+   For the first scan-tree-dump, on some targets the 
__builtin_omp_get_mapped_ptr get
+   swapped. As the counting does not work well with variable-name capturing, 
it only
+   uses 'scan-tree-dump' and not 'scan-tree-dump-times'.  */
+
+#pragma omp dispatch
+/* { dg-final { scan-tree-dump "#pragma omp dispatch\[ \t\n\r\{]*int 
(D\.\[0-9]+);\[ \t\n\r]*void \\* (D\.\[0-9]+);\[ \t\n\r]*void \\* 
(D\.\[0-9]+);\[ \t\n\r]*\\1 = __builtin_omp_get_default_device \\(\\);\[ 
\t\n\r]*\\2 = __builtin_omp_get_mapped_ptr \\(&arr, \\1\\);\[ \t\n\r]*\\3 = 
__builtin_omp_get_mapped_ptr \\(p, \\1\\);\[ \t\n\r]*f1 \\(\\3, \\2\\);|#pragma 
omp dispatch\[ \t\n\r\{]*int (D\.\[0-9]+);\[ \t\n\r]*void \\* (D\.\[0-9]+);\[ 
\t\n\r]*void \\* (D\.\[0-9]+);\[ \t\n\r]*\\4 = __builtin_omp_get_default_device 
\\(\\);\[ \t\n\r]*\\5 = __builtin_omp_get_mapped_ptr \\(p, \\4\\);\[ 
\t\n\r]*\\6 = __builtin_omp_get_mapped_ptr \\(&arr, \\4\\);\[ \t\n\r]*f1 
\\(\\5, \\6\\);" "gimple" } } */
+  f2 (p, arr);
+#pragma omp dispatch is_device_ptr(p)
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch 
is_device_ptr\\(p\\)\[ \t\n\r\{]*int (D\.\[0-9]+);\[ \t\n\r]*void \\* 
(D\.\[0-9]+);\[ \t\n\r]*\\1 = __builtin_omp_get_default_device \\(\\);\[ 
\t\n\r]*\\2 = __builtin_omp_get_mapped_ptr \\(&arr, \\1\\);\[ \t\n\r]*f1 \\(p, 
\\2\\);" 3 "gimple" } } */
+  f2 (p, arr);
+#pragma omp dispatch is_device_ptr(arr)
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch 
is_device_ptr\\(arr\\)\[ \t\n\r\{]*int (D\.\[0-9]+);\[ \t\n\r]*void \\* 
(D\.\[0-9]+);\[ \t\n\r]*\\1 = __builtin_omp_get_default_device \\(\\);\[ 
\t\n\r]*\\2 = __builtin_omp_get_mapped_ptr \\(p, \\1\\);\[ \t\n\r]*f1 \\(\\2, 
&arr\\);" 3 "gimple" } } */
+  f2 (p, arr);
+#pragma omp dispatch is_device_ptr(p, arr)
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch 
is_device_ptr\\(arr\\) is_device_ptr\\(p\\)\[ \t\n\r\{]*f1 \\(p, &arr\\);" 1 
"gimple" } } */
+  f2 (p, arr);
+}
+
+
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-6.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-6.c
new file mode 100644
index 000000000000..4e900bb5e8da
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-6.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-ompexp" } */
+
+void f2 (void* p);
+
+void test (void)
+{
+  void *p;
+
+#pragma omp dispatch
+/* { dg-final { scan-tree-dump-not "__builtin_GOMP_task " "ompexp" } } */
+  f2 (p);
+#pragma omp dispatch depend(inout: p)
+/* { dg-final { scan-tree-dump-times "(D\.\[0-9]+)\\\[2] = &p;\[ 
\n]*__builtin_GOMP_taskwait_depend \\(&\\1\\);" 2 "ompexp" } } */
+  f2 (p);
+}
+
+
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-7.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-7.c
new file mode 100644
index 000000000000..44a62608eb0b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-7.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f0 (void);
+int f1 (void);
+#pragma omp declare variant (f0) match (construct={dispatch})
+#pragma omp declare variant (f1) match (implementation={vendor(gnu)})
+int f2 (void);
+
+int test (void)
+{
+  int a, n;
+#pragma omp dispatch novariants(n < 1024) nocontext(n > 1024)
+  a = f2 ();
+  return a;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch nocontext\\(0\\) 
novariants\\(0\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "a = f2 \\\(\\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "a = f1 \\\(\\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "a = f0 \\\(\\\);" 1 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-8.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-8.c
new file mode 100644
index 000000000000..11713554a826
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-8.c
@@ -0,0 +1,63 @@
+int g1() { return 100; }
+int g2() { return 200; }
+
+#pragma omp declare variant (g1) match 
(construct={dispatch},user={condition(1)})
+#pragma omp declare variant (g2) match (user={condition(1)})
+int g() { return 300; }
+
+
+int f1(int x) { return 1 + x; }
+int f2(int x) { return 2 + x; }
+
+#pragma omp declare variant (f1) match 
(construct={dispatch},user={condition(1)})
+#pragma omp declare variant (f2) match (user={condition(1)})
+int f(int x) { return 3 + x; }
+
+
+void
+test ()
+{
+  int res;
+
+  // Call f2(g2()) due to user condition(1)
+  res = f (g ());
+  __builtin_printf("%d\n", res);
+  if (res != 202)
+    __builtin_abort ();
+
+  // Call 'f1(g1())' due to construct 'dispatch' and user conditional(1)
+  #pragma omp dispatch
+    res = f (g ());
+  __builtin_printf("%d\n", res);
+  if (res != 101)
+     __builtin_abort ();
+
+  // Call 'f2(g2())' due to nocontext (i.e. ignore construct 'dispatch') and 
user conditional(1)
+  #pragma omp dispatch nocontext(1)
+    res = f (g ());
+  __builtin_printf("%d\n", res);
+  if (res != 202)
+     __builtin_abort ();
+
+  // Call 'f' due to 'novariants'
+  // Call 'g1' due to construct 'dispatch' and user conditional(1)
+  #pragma omp dispatch novariants(1)
+    res = f (g ());
+  __builtin_printf("%d\n", res);   /* ACTUAL RESULT: 303, i.e. 'g' and not 
'g1' was called */
+  if (res != 103)
+     __builtin_abort ();
+
+  // Call 'f' due to 'novariants'
+  // Call 'g2' due to  nocontext (i.e. ignore construct 'dispatch') and user 
conditional(1)
+  #pragma omp dispatch novariants(1) nocontext(1)
+    res = f (g ());
+  __builtin_printf("%d\n", res);   /* ACTUAL RESULT: 303, i.e. 'g' and not 
'g2' was called */
+  if (res != 203)
+     __builtin_abort ();
+}
+
+int
+main ()
+{
+  test ();
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-9.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-9.c
new file mode 100644
index 000000000000..b4b46b946fdc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-9.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-original -fdump-tree-gimple" } */
+
+/* Check that the right call to f is wrapped in a GOMP_DISPATCH internal 
function
+   before translation and that it is stripped during gimplification. */
+
+int f(int);
+void g(int *x)
+{
+  #pragma omp dispatch
+  x[f(1)] = f(f(2));
+  //        ^ only this call to f is a dispatch call
+}
+
+/* { dg-final { scan-tree-dump "\.GOMP_DISPATCH \\(f \\(f \\(2\\)\\)\\)" 
"original" } } */
+/* { dg-final { scan-tree-dump-times "\.GOMP_DISPATCH" 1 "original" } } */
+/* { dg-final { scan-tree-dump-not "\.GOMP_DISPATCH" "gimple" } } */
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index 04bdec462c29..65232a1b8612 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,11 @@
+2025-01-27  Paul-Antoine Arras  <par...@baylibre.com>
+
+       Backported from master:
+       2024-11-20  Paul-Antoine Arras  <par...@baylibre.com>
+
+       * testsuite/libgomp.c-c++-common/dispatch-1.c: New test.
+       * testsuite/libgomp.c-c++-common/dispatch-2.c: New test.
+
 2025-01-23  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/libgomp/testsuite/libgomp.c-c++-common/dispatch-1.c 
b/libgomp/testsuite/libgomp.c-c++-common/dispatch-1.c
new file mode 100644
index 000000000000..0efc075a8596
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/dispatch-1.c
@@ -0,0 +1,76 @@
+// Adapted from OpenMP examples
+
+#include <omp.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int baz (double *d_bv, const double *d_av, int n)
+{
+#pragma omp distribute parallel for
+  for (int i = 0; i < n; i++)
+    d_bv[i] = d_av[i] * i;
+  return -3;
+}
+
+int bar (double *d_bv, const double *d_av, int n)
+{
+#pragma omp target is_device_ptr(d_bv, d_av)
+  for (int i = 0; i < n; i++)
+    d_bv[i] = d_av[i] * i;
+  return -2;
+}
+
+#pragma omp declare variant(bar) match(construct={dispatch}) 
adjust_args(need_device_ptr: bv, av)
+#pragma omp declare variant(baz) match(implementation={vendor(gnu)})
+int foo (double *bv, const double *av, int n)
+{
+  for (int i = 0; i < n; i++)
+    bv[i] = av[i] * i;
+  return -1;
+}
+
+int test (int n)
+{
+  const double e = 2.71828;
+
+  double *av = (double *) malloc (n * sizeof (*av));
+  double *bv = (double *) malloc (n * sizeof (*bv));
+  double *d_bv = (double *) malloc (n * sizeof (*d_bv));
+
+  for (int i = 0; i < n; i++)
+    {
+      av[i] = e * i;
+      bv[i] = 0.0;
+      d_bv[i] = 0.0;
+    }
+
+  int f, last_dev = omp_get_num_devices () - 1;
+#pragma omp target data map(to: av[:n]) map(from: d_bv[:n]) device(last_dev) 
if (n == 1024)
+  {
+    #pragma omp dispatch nocontext(n > 1024) novariants(n < 1024) 
device(last_dev)
+    f = foo (d_bv, av, n);
+  }
+
+  foo (bv, av, n);
+  for (int i = 0; i < n; i++)
+    {
+      if (d_bv[i] != bv[i])
+       {
+         fprintf (stderr, "ERROR at %d: %lf (act) != %lf (exp)\n", i, d_bv[i], 
bv[i]);
+         return 1;
+       }
+    }
+    return f;
+}
+
+int
+main (void)
+{
+  int ret = test(1023);
+  if (ret != -1) return 1;
+  ret = test(1024);
+  if (ret != -2) return 1;
+  ret = test(1025);
+  if (ret != -3) return 1;
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/dispatch-2.c 
b/libgomp/testsuite/libgomp.c-c++-common/dispatch-2.c
new file mode 100644
index 000000000000..faa0d8a1d1c1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/dispatch-2.c
@@ -0,0 +1,84 @@
+// Adapted from OpenMP examples
+
+#include <omp.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int baz (double *d_bv, const double *d_av, int n);
+int bar (double *d_bv, const double *d_av, int n); 
+
+#pragma omp declare variant(bar) match(construct={dispatch}) 
adjust_args(need_device_ptr: f_bv, f_av)
+#pragma omp declare variant(baz) match(implementation={vendor(gnu)})
+int foo (double *f_bv, const double *f_av, int n);
+
+int baz (double *bv, const double *av, int n);
+int bar (double *bv, const double *av, int n); 
+
+int foo (double *bv, const double *av, int n)
+{
+  for (int i = 0; i < n; i++)
+    bv[i] = av[i] * i;
+  return -1;
+}
+
+int baz (double *d_bv, const double *d_av, int n)
+{
+#pragma omp distribute parallel for
+  for (int i = 0; i < n; i++)
+    d_bv[i] = d_av[i] * i;
+  return -3;
+}
+
+int bar (double *d_bv, const double *d_av, int n)
+{
+#pragma omp target is_device_ptr(d_bv, d_av)
+  for (int i = 0; i < n; i++)
+    d_bv[i] = d_av[i] * i;
+  return -2;
+}
+
+int test (int n)
+{
+  const double e = 2.71828;
+
+  double *av = (double *) malloc (n * sizeof (*av));
+  double *bv = (double *) malloc (n * sizeof (*bv));
+  double *d_bv = (double *) malloc (n * sizeof (*d_bv));
+
+  for (int i = 0; i < n; i++)
+    {
+      av[i] = e * i;
+      bv[i] = 0.0;
+      d_bv[i] = 0.0;
+    }
+
+  int f, last_dev = omp_get_num_devices () - 1;
+#pragma omp target data map(to: av[:n]) map(from: d_bv[:n]) device(last_dev) 
if (n == 1024)
+  {
+    #pragma omp dispatch nocontext(n > 1024) novariants(n < 1024) 
device(last_dev)
+    f = foo (d_bv, av, n);
+  }
+
+  foo (bv, av, n);
+  for (int i = 0; i < n; i++)
+    {
+      if (d_bv[i] != bv[i])
+       {
+         fprintf (stderr, "ERROR at %d: %lf (act) != %lf (exp)\n", i, d_bv[i], 
bv[i]);
+         return 1;
+       }
+    }
+    return f;
+}
+
+int
+main (void)
+{
+  int ret = test(1023);
+  if (ret != -1) return 1;
+  ret = test(1024);
+  if (ret != -2) return 1;
+  ret = test(1025);
+  if (ret != -3) return 1;
+  return 0;
+}

Reply via email to