Skip to content

[OpenMP] Allow OMP6.0 features. #122108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 29, 2025
Merged

[OpenMP] Allow OMP6.0 features. #122108

merged 8 commits into from
Jan 29, 2025

Conversation

zahiraam
Copy link
Contributor

@zahiraam zahiraam commented Jan 8, 2025

Add support for the -fopenmp-version=60 command line argument. It is needed for #119891 (#pragma omp stripe) which will be the first OpenMP 6.0 directive implemented. Add regression tests for Clang in -fopenmp-version=60 mode.

@zahiraam zahiraam marked this pull request as ready for review January 8, 2025 13:57
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang labels Jan 8, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 8, 2025

@llvm/pr-subscribers-clang

Author: Zahira Ammarguellat (zahiraam)

Changes

In #119891 we are introducing the support for #pragma omp stripe which is an OMP6.0 feature (see https://github.com/llvm/llvm-project/pull/119891/files#r1896944800). This PR changes the default option to 6.0.


Patch is 161.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/122108.diff

35 Files Affected:

  • (modified) clang/lib/Frontend/CompilerInvocation.cpp (+2-2)
  • (modified) clang/lib/Frontend/InitPreprocessor.cpp (+6-3)
  • (modified) clang/lib/Parse/ParseOpenMP.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+1-1)
  • (modified) clang/test/OpenMP/declare_mapper_messages.c (+9-11)
  • (modified) clang/test/OpenMP/declare_mapper_messages.cpp (+2-2)
  • (modified) clang/test/OpenMP/declare_reduction_messages.cpp (+3-3)
  • (modified) clang/test/OpenMP/declare_simd_ast_print.c (-2)
  • (modified) clang/test/OpenMP/declare_simd_ast_print.cpp (+11-11)
  • (modified) clang/test/OpenMP/declare_simd_codegen.cpp (+80-56)
  • (modified) clang/test/OpenMP/declare_simd_messages.cpp (+8-7)
  • (modified) clang/test/OpenMP/declare_target_ast_print.cpp (+32-43)
  • (modified) clang/test/OpenMP/declare_target_codegen.cpp (+12)
  • (modified) clang/test/OpenMP/declare_target_messages.cpp (+21-29)
  • (modified) clang/test/OpenMP/declare_target_only_one_side_compilation.cpp (+2-2)
  • (modified) clang/test/OpenMP/declare_target_variables_ast_print.cpp (+1-1)
  • (modified) clang/test/OpenMP/depobj_ast_print.cpp (+6-6)
  • (modified) clang/test/OpenMP/depobj_codegen.cpp (+13-8)
  • (modified) clang/test/OpenMP/depobj_messages.cpp (+6-6)
  • (modified) clang/test/OpenMP/distribute_parallel_for_ast_print.cpp (+6-6)
  • (modified) clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp (+2-2)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp (+6-6)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp (+2-2)
  • (modified) clang/test/OpenMP/distribute_simd_ast_print.cpp (+6-6)
  • (modified) clang/test/OpenMP/distribute_simd_misc_messages.c (+4-4)
  • (modified) clang/test/OpenMP/distribute_simd_reduction_messages.cpp (+2-2)
  • (modified) clang/test/OpenMP/error_ast_print.cpp (+6-6)
  • (modified) clang/test/OpenMP/error_codegen.cpp (+2-2)
  • (modified) clang/test/OpenMP/error_message.cpp (+2-2)
  • (modified) clang/test/OpenMP/flush_ast_print.cpp (+6-6)
  • (modified) clang/test/OpenMP/flush_codegen.cpp (+9-9)
  • (modified) clang/test/OpenMP/for_linear_codegen.cpp (+193-422)
  • (modified) clang/test/OpenMP/for_linear_messages.cpp (+2-2)
  • (modified) clang/test/OpenMP/for_reduction_messages.cpp (+2-2)
  • (modified) clang/test/OpenMP/for_simd_ast_print.cpp (+6-6)
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 348c56cc37da3f..edae9106432117 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4174,7 +4174,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
   }
 
   // Check if -fopenmp is specified and set default version to 5.0.
-  Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
+  Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 60 : 0;
   // Check if -fopenmp-simd is specified.
   bool IsSimdSpecified =
       Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
@@ -4192,7 +4192,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
   if (Opts.OpenMP || Opts.OpenMPSimd) {
     if (int Version = getLastArgIntValue(
             Args, OPT_fopenmp_version_EQ,
-            (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
+            (IsSimdSpecified || IsTargetSpecified) ? 60 : Opts.OpenMP, Diags))
       Opts.OpenMP = Version;
     // Provide diagnostic when a given target is not expected to be an OpenMP
     // device or host.
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 29723b573e771a..90289c8d81962a 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1460,12 +1460,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
     case 50:
       Builder.defineMacro("_OPENMP", "201811");
       break;
+    case 51:
+      Builder.defineMacro("_OPENMP", "202011");
+      break;
     case 52:
       Builder.defineMacro("_OPENMP", "202111");
       break;
-    default: // case 51:
-      // Default version is OpenMP 5.1
-      Builder.defineMacro("_OPENMP", "202011");
+    default:
+      // Default version is OpenMP 6.0
+      Builder.defineMacro("_OPENMP", "202411");
       break;
     }
   }
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index b4e973bc84a7b0..52adadf47e5103 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -4278,7 +4278,7 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) {
       Data.MapTypeModifiers.push_back(TypeModifier);
       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
       if (PP.LookAhead(0).isNot(tok::comma) &&
-          PP.LookAhead(0).isNot(tok::colon) && getLangOpts().OpenMP >= 52)
+          PP.LookAhead(0).isNot(tok::colon) && getLangOpts().OpenMP >= 61)
         Diag(Tok.getLocation(), diag::err_omp_missing_comma)
             << "map type modifier";
       ConsumeToken();
@@ -4289,7 +4289,7 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) {
       if (parseMapperModifier(Data))
         return true;
       if (Tok.isNot(tok::comma) && Tok.isNot(tok::colon) &&
-          getLangOpts().OpenMP >= 52)
+          getLangOpts().OpenMP >= 61)
         Diag(Data.MapTypeModifiersLoc.back(), diag::err_omp_missing_comma)
             << "map type modifier";
 
@@ -4325,7 +4325,7 @@ bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) {
       }
 
       Diag(Tok, diag::err_omp_unknown_map_type_modifier)
-          << (getLangOpts().OpenMP >= 51 ? (getLangOpts().OpenMP >= 52 ? 2 : 1)
+          << (getLangOpts().OpenMP >= 51 ? (getLangOpts().OpenMP >= 60 ? 2 : 1)
                                          : 0)
           << getLangOpts().OpenMPExtensions;
       ConsumeToken();
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 66ff92f554fc42..2bb8cfc3e74882 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -18407,7 +18407,7 @@ static bool actOnOMPReductionKindClause(
     // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
     // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
     // reduction identifier.
-    if (S.LangOpts.OpenMP > 52)
+    if (S.LangOpts.OpenMP > 60)
       BOK = BO_Comma;
     else
       BOK = BO_Add;
diff --git a/clang/test/OpenMP/declare_mapper_messages.c b/clang/test/OpenMP/declare_mapper_messages.c
index 288caca097648c..c9d1c10dea43e9 100644
--- a/clang/test/OpenMP/declare_mapper_messages.c
+++ b/clang/test/OpenMP/declare_mapper_messages.c
@@ -33,12 +33,10 @@ struct vec {                                                            // expec
 #pragma omp declare mapper(int v) map(v)                                // expected-error {{mapper type must be of struct, union or class type}}
 
 #ifndef OMP52
-// omp51-simd-error@+6 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}} 
-// omp50-error@+5 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'ompx_hold'}} 
-// omp51-error@+4 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}} 
-// expected-error@+3 {{only variable 'vvec' is allowed in map clauses of this 'omp declare mapper' directive}} 
-// expected-error@+2 {{expected at least one clause on '#pragma omp declare mapper' directive}}
-// expected-note@+1 {{'it' declared here}}
+// omp50-error@+4 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'ompx_hold'}}
+// omp50-error@+3 {{only variable 'vvec' is allowed in map clauses of this 'omp declare mapper' directive}}
+// omp50-error@+2 {{expected at least one clause on '#pragma omp declare mapper' directive}}
+// omp50-note@+1 {{'it' declared here}}
 #pragma omp declare mapper(id2: struct vec vvec) map(iterator(it=0:vvec.len:2), tofrom:vvec.data[it]) 
 
 #else
@@ -68,15 +66,15 @@ int fun(int arg) {
       {}
 #pragma omp target map(mapper(aa :vv)                                   // expected-error {{use of undeclared identifier 'aa'}} expected-error {{expected ')'}} expected-error {{call to undeclared function 'mapper'}} expected-note {{to match this '('}}
       {}
-#pragma omp target map(mapper(ab) :vv)                                  // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}}
+#pragma omp target map(mapper(ab) :vv)                                  // omp50-error {{missing map type}} // omp52-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}}
       {}
-#pragma omp target map(mapper(ab) :arr[0:2])                            // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}}
+#pragma omp target map(mapper(ab) :arr[0:2])                            // omp50-error {{missing map type}} // omp52-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}}
       {}
-#pragma omp target map(mapper(aa) :vv)                                  // expected-error {{missing map type}}
+#pragma omp target map(mapper(aa) :vv)                                  // omp50-error {{missing map type}} // omp52-error {{missing map type}}
       {}
-#pragma omp target map(mapper(aa) to:d)                                 // expected-error {{mapper type must be of struct, union or class type}} omp52-error{{missing ',' after map type modifier}}
+#pragma omp target map(mapper(aa) to:d)                                 // expected-error {{mapper type must be of struct, union or class type}}
       {}
-#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1) map(mapper(aa) to:arr[0]) // omp52-error 4 {{missing ',' after map type modifier}}
+#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1) map(mapper(aa) to:arr[0])
       {}
 
 #pragma omp target update to(mapper)                                    // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
diff --git a/clang/test/OpenMP/declare_mapper_messages.cpp b/clang/test/OpenMP/declare_mapper_messages.cpp
index f2101786f6ce02..2816c9c8f5a8ea 100644
--- a/clang/test/OpenMP/declare_mapper_messages.cpp
+++ b/clang/test/OpenMP/declare_mapper_messages.cpp
@@ -72,13 +72,13 @@ int fun(int arg) {
       {}
 #pragma omp target map(mapper(aa :vv)                                   // expected-error {{use of undeclared identifier 'aa'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
       {}
-#pragma omp target map(mapper(ab) :vv)                                  // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}}
+#pragma omp target map(mapper(ab) :vv)                                  // omp50-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}}
       {}
 #pragma omp target map(mapper(N2::) :vv)                                // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal OpenMP user-defined mapper identifier}}
       {}
 #pragma omp target map(mapper(N1::) :vv)                                // expected-error {{illegal OpenMP user-defined mapper identifier}}
       {}
-#pragma omp target map(mapper(aa) :vv)                                  // expected-error {{missing map type}}
+#pragma omp target map(mapper(aa) :vv)                                  // omp50-error {{missing map type}}
       {}
 #pragma omp target map(mapper(N1::aa) alloc:vv)                         // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'aa'}}
       {}
diff --git a/clang/test/OpenMP/declare_reduction_messages.cpp b/clang/test/OpenMP/declare_reduction_messages.cpp
index 752cc4fb05a123..cffc52b3f0c0e9 100644
--- a/clang/test/OpenMP/declare_reduction_messages.cpp
+++ b/clang/test/OpenMP/declare_reduction_messages.cpp
@@ -96,7 +96,7 @@ T foo(T arg) {
   #pragma omp parallel reduction (red1 : i)
   {
   }
-  #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
   {
   }
   }
@@ -110,7 +110,7 @@ T foo(T arg) {
   #pragma omp parallel reduction (red1 : i)
   {
   }
-  #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
   {
   }
   }
@@ -127,7 +127,7 @@ int main() {
   #pragma omp parallel reduction (::Class1<int>::fun : c1)
   {
   }
-  #pragma omp parallel reduction (::Class2<int>::fun : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+  #pragma omp parallel reduction (::Class2<int>::fun : i) // expected-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
   {
   }
   return fun(15) + foo(15); // expected-note {{in instantiation of function template specialization 'foo<int>' requested here}}
diff --git a/clang/test/OpenMP/declare_simd_ast_print.c b/clang/test/OpenMP/declare_simd_ast_print.c
index 990a6cd8c6507f..6ff08084b50833 100644
--- a/clang/test/OpenMP/declare_simd_ast_print.c
+++ b/clang/test/OpenMP/declare_simd_ast_print.c
@@ -12,12 +12,10 @@
 
 #pragma omp declare simd aligned(b : 64)
 #pragma omp declare simd simdlen(32) aligned(d, b)
-#pragma omp declare simd inbranch, uniform(d) linear(val(s1, s2) : 32)
 #pragma omp declare simd notinbranch simdlen(2), uniform(s1, s2) linear(d: s1)
 void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold));
 
 // CHECK: #pragma omp declare simd notinbranch simdlen(2) uniform(s1, s2) linear(val(d): s1){{$}}
-// CHECK-NEXT: #pragma omp declare simd inbranch uniform(d) linear(val(s1): 32) linear(val(s2): 32){{$}}
 // CHECK-NEXT: #pragma omp declare simd simdlen(32) aligned(d) aligned(b){{$}}
 // CHECK-NEXT: #pragma omp declare simd aligned(b: 64){{$}}
 // CHECK-NEXT: void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold))
diff --git a/clang/test/OpenMP/declare_simd_ast_print.cpp b/clang/test/OpenMP/declare_simd_ast_print.cpp
index 2704aae8617f2d..d6e4500ee643fd 100644
--- a/clang/test/OpenMP/declare_simd_ast_print.cpp
+++ b/clang/test/OpenMP/declare_simd_ast_print.cpp
@@ -63,22 +63,22 @@ class VV {
   // CHECK-NEXT: int add(int a, int b) __attribute__((cold))    {
   // CHECK-NEXT: return a + b;
   // CHECK-NEXT: }
-  #pragma omp declare simd uniform(this, a) linear(val(b): a)
+  #pragma omp declare simd uniform(this, a) linear(b: a)
   int add(int a, int b) __attribute__((cold)) { return a + b; }
 
-  // CHECK: #pragma omp declare simd aligned(b: 4) aligned(a) linear(ref(b): 4) linear(val(this)) linear(val(a))
+  // CHECK: #pragma omp declare simd aligned(b: 4) aligned(a) linear(val(b): 4) linear(val(this)) linear(val(a))
   // CHECK-NEXT: float taddpf(float *a, float *&b)     {
   // CHECK-NEXT: return *a + *b;
   // CHECK-NEXT: }
-  #pragma omp declare simd aligned (b: 4) aligned(a) linear(ref(b): 4) linear(this, a)
+  #pragma omp declare simd aligned (b: 4) aligned(a) linear(b: 4) linear(this, a)
   float taddpf(float *a, float *&b) { return *a + *b; }
 
 // CHECK: #pragma omp declare simd aligned(b: 8)
-// CHECK-NEXT: #pragma omp declare simd linear(uval(c): 8)
+// CHECK-NEXT: #pragma omp declare simd linear(val(c): 8)
 // CHECK-NEXT: int tadd(int (&b)[], int &c) {
 // CHECK-NEXT: return this->x[b[0]] + b[0];
 // CHECK-NEXT: }
-  #pragma omp declare simd linear(uval(c): 8)
+  #pragma omp declare simd linear(c: 8)
   #pragma omp declare simd aligned(b : 8)
   int tadd(int (&b)[], int &c) { return x[b[0]] + b[0]; }
 
@@ -89,7 +89,7 @@ class VV {
 // CHECK: template <int X, typename T> class TVV {
 // CHECK: #pragma omp declare simd simdlen(X)
 // CHECK-NEXT: int tadd(int a, int b) {
-// CHECK: #pragma omp declare simd aligned(a: X * 2) aligned(b) linear(ref(b): X)
+// CHECK: #pragma omp declare simd aligned(a: X * 2) aligned(b) linear(val(b): X)
 // CHECK-NEXT: float taddpf(float *a, T *&b) {
 // CHECK-NEXT: return *a + *b;
 // CHECK-NEXT: }
@@ -109,10 +109,10 @@ class TVV {
 // CHECK: #pragma omp declare simd simdlen(16)
 // CHECK-NEXT: int tadd(int a, int b);
 
-  #pragma omp declare simd aligned(a : X * 2) aligned(b) linear(ref(b): X)
+  #pragma omp declare simd aligned(a : X * 2) aligned(b) linear(b: X)
   float taddpf(float *a, T *&b) { return *a + *b; }
 
-// CHECK: #pragma omp declare simd aligned(a: 16 * 2) aligned(b) linear(ref(b): 16)
+// CHECK: #pragma omp declare simd aligned(a: 16 * 2) aligned(b) linear(val(b): 16)
 // CHECK-NEXT: float taddpf(float *a, float *&b) {
 // CHECK-NEXT: return *a + *b;
 // CHECK-NEXT: }
@@ -132,11 +132,11 @@ class TVV {
 };
 // CHECK: };
 
-// CHECK: #pragma omp declare simd simdlen(N) aligned(b: N * 2) linear(uval(c): N)
+// CHECK: #pragma omp declare simd simdlen(N) aligned(b: N * 2) linear(val(c): N)
 // CHECK: template <int N> void foo(int (&b)[N], float *&c)
-// CHECK: #pragma omp declare simd simdlen(64) aligned(b: 64 * 2) linear(uval(c): 64)
+// CHECK: #pragma omp declare simd simdlen(64) aligned(b: 64 * 2) linear(val(c): 64)
 // CHECK: template<> void foo<64>(int (&b)[64], float *&c)
-#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(uval(c): N)
+#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(c: N)
 template <int N>
 void foo(int (&b)[N], float *&c);
 
diff --git a/clang/test/OpenMP/declare_simd_codegen.cpp b/clang/test/OpenMP/declare_simd_codegen.cpp
index d7bd798798294e..cca036ba3e7748 100644
--- a/clang/test/OpenMP/declare_simd_codegen.cpp
+++ b/clang/test/OpenMP/declare_simd_codegen.cpp
@@ -48,13 +48,13 @@ void h(int *hp, int *hp2, int *hq, int *lin) {
 
 class VV {
 public:
-#pragma omp declare simd uniform(this, a) linear(val(b) : a)
+#pragma omp declare simd uniform(this, a) linear(b : a)
   int add(int a, int b) __attribute__((cold)) { return a + b; }
 
-#pragma omp declare simd aligned(b : 4) aligned(a) linear(ref(b) : 4) linear(this, a)
+#pragma omp declare simd aligned(b : 4) aligned(a) linear(b : 4) linear(this, a)
   float taddpf(float *a, float *&b) { return *a + *b; }
 
-#pragma omp declare simd linear(uval(c) : 8)
+#pragma omp declare simd linear(c : 8)
 #pragma omp declare simd aligned(b : 8)
   int tadd(int (&b)[], int &c) { return x[b[0]] + b[0]; }
 
@@ -68,7 +68,7 @@ class TVV {
 #pragma omp declare simd simdlen(X)
   int tadd(int a, int b) { return a + b; }
 
-#pragma omp declare simd aligned(a : X * 2) aligned(b) linear(ref(b) : X)
+#pragma omp declare simd aligned(a : X * 2) aligned(b) linear(b : X)
   float taddpf(float *a, T *&b) { return *a + *b; }
 
 #pragma omp declare simd
@@ -79,7 +79,7 @@ class TVV {
   int x[X];
 };
 
-#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(uval(c) : N)
+#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(c : N)
 template <int N>
 void foo(int (&b)[N], float *&c) {}
 
@@ -148,20 +148,20 @@ double One(int &a, int *b, int c, int &d, int *e, int f) {
 }
 
 // linear(val(x)) cases
-#pragma omp declare simd simdlen(4) linear(val(a):2) linear(val(b):4) \
-                                    linear(val(c):8) linear(val(d,e,f))
+#pragma omp declare simd simdlen(4) linear(a:2) linear(b:4) \
+                                    linear(c:8) linear(d,e,f)
 double Two(int &a, int *b, int c, int &d, int *e, int f) {
   return a + *b + c;
 }
 
 // linear(uval(x) case
-#pragma omp declare simd simdlen(4) linear(uval(a):2) linear(uval(b))
+#pragma omp declare simd simdlen(4) linear(a:2) linear(b)
 double Three(int &a, int &b) {
   return a;
 }
 
 // linear(ref(x) case
-#pragma omp declare simd simdlen(4) linear(ref(a):2) linear(ref(b))
+#pragma omp declare simd simdlen(4) linear(a:2) linear(b)
 double Four(int& a, int &b) {
   return a;
 }
@@ -169,9 +169,9 @@ double Four(int& a, int &b) {
 // Test reference parameters with variable stride.
 #pragma omp declare simd simdlen(4) uniform(a)               \
                          linear(b:2) linear(c:a)             \
-                         linear(val(d):4) linear(val(e):a)   \
-                         linear(uval(f):8) linear(uval(g):a) \
-                         linear(ref(h):16) linear(ref(i):a)
+                         linear(d:4) linear(e:a)   \
+                         linear(f:8) linear(g:a) \
+                         linear(h:16) linear(i:a)
 double Five(int a, short &b, short &c, short &d, short &e, short &f, short &g,
             short &h, short &i) {
   return a + int(b);
@@ -179,7 +179,7 @@ double Five(int a, short &b, short &c, short &d, short &e, short &f, short &g,
 
 // Test negative strides
 #pragma omp declare simd simdlen(4) linear(a:-2) linear(b:-8) \
-                                    linear(uval(c):-4) linear(ref(d):-16) \
+                                    linear(c:-4) linear(d:-16) \
                                     linear(e:-1) linear(f:-1) linear(g:0)
 double Six(int a, float *b, int &c, int *&d, char e, char *f, short g) {
  return a + int(*b) + c + *d + e + *f + g;
@@ -273,40 +273,40 @@ double Six(int a, float *b, int &c, int *&d, char e, char *f, short g) {
 // CHECK-DAG: "_ZGVeM16uuls1__ZN2VV3addEii"
 // CHECK-DAG: "_ZGVeN16uuls1__ZN2VV3addEii"
 
-// CHECK-DAG: "_ZGVbM4l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVbN4l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVcM8l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVcN8l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVdM8l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVdN8l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVeM16l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-// CHECK-DAG: "_ZGVeN16l40l4a16R32a4__ZN2VV6taddpfEPfRS0_"
-
-// CHECK-DAG: "...
[truncated]

@zahiraam zahiraam marked this pull request as draft January 8, 2025 13:58
@zahiraam zahiraam requested a review from alexey-bataev January 8, 2025 13:59
@zahiraam
Copy link
Contributor Author

zahiraam commented Jan 8, 2025

@alexey-bataev Can you please take a look at this draft PR? I think there are still some LIT tests failing but I want to make sure the changes I am proposing are correct before making further changes. I am not sure if the macro _OPENMP should be set to 202411 or if it should continue being equal to 202011.

@alexey-bataev
Copy link
Member

Not sure this level of support is enough to make 6.0 the default version. We're missing support for some 5.2 features still

@zahiraam
Copy link
Contributor Author

zahiraam commented Jan 8, 2025

Not sure this level of support is enough to make 6.0 the default version. We're missing support for some 5.2 features still

That's what I thought! So the macro should continue being set to `202011?

@alexey-bataev
Copy link
Member

Not sure this level of support is enough to make 6.0 the default version. We're missing support for some 5.2 features still

That's what I thought! So the macro should continue being set to `202011?

I think yes, unless we support most of the 6.0 features

Copy link
Contributor

@mjklemm mjklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

The PR seems to have two components:

  1. Upgrade the compiler code to be able to accept OpenMP 6.0 features
  2. switch the default to be OpenMP 6.0

Part 1 is fine, as the community is starting to implement 6.0 features and, therefore, we need the compiler to understand the notion of that new version.

Part 2 should be removed from this PR. If users want OpenMP 6.0 features they can specifically request that version via the command line (as Part 1 adds this). The default version should stay with 5.1 at this point until a reasonable fraction of OpenMP 6.0 has been implemented that warrants switching. At this point this is not the case.

Copy link
Contributor

@saiislam saiislam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with both points raised by @mjklemm .

Even when we make 6.0 as default, I am pretty sure that many more LIT tests need to be updated. Please see https://reviews.llvm.org/D129635 for last update exercise.

We also will have to ensure that testing coverage for 5.1 is not reduced by making 6.0 as default, which might require modifying some/many test cases manually.

What to do with 4.5 test coverage is another question we need to discuss.

@zahiraam zahiraam requested review from saiislam and mjklemm January 9, 2025 13:43
Copy link
Member

@alexey-bataev alexey-bataev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to change the caption and summary of PR, I assume

@zahiraam zahiraam changed the title [OpenMP] Change default version to OMP6.0. [OpenMP] Allow OMP6.0 features. Jan 9, 2025
@zahiraam zahiraam marked this pull request as ready for review January 9, 2025 18:22
@zahiraam
Copy link
Contributor Author

@mjklemm and @saiislam would you mind taking a look at this please? Thanks.

Copy link
Contributor

@saiislam saiislam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for revising the PR. I have added some comments.

To unblock #119891, wouldn't it be sufficient that -fopenmp-version=60 becomes a valid value? Do we need to modify all these tests to test only this flag?

@zahiraam
Copy link
Contributor Author

@mjklemm, @saiislam can you please review this? Thanks.

@mjklemm
Copy link
Contributor

mjklemm commented Jan 15, 2025

Please resolve open feedback items before the next round of reviews. Thanks.

@zahiraam
Copy link
Contributor Author

Please resolve open feedback items before the next round of reviews. Thanks.

Sorry I might have been ahead of myself!
I think this time I might have gotten it.

Copy link
Contributor

@mjklemm mjklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address @saiislam's questions. I also think that the title and description of the PR should reflect that this PR not only introduces the 6.0 flag, but also moves several of the tests to test against 5.1 and 6.0.

@Meinersbur
Copy link
Member

In #119891 we are introducing the support for #pragma omp stripe which is an OMP6.0 feature (see #119891 (files)). This PR changes the default option to 6.0.

Summary (which usually is the basis for the commit message) needs an update.

Suggestion:
Add support for the -fopenmp-version=60 command line argument. It is needed for #122108 (#pragma omp stripe) which will be the first OpenMP 6.0 directive implemented. Add regression tests for Clang in -fopenmp-version=60 mode.

@zahiraam
Copy link
Contributor Author

Thanks for revising the PR. I have added some comments.

To unblock #119891, wouldn't it be sufficient that -fopenmp-version=60 becomes a valid value? Do we need to modify all these tests to test only this flag?

Yes it's sufficient and that's what's done in #119891.
The edit in the LIT tests now are only addition of -fopen-version=60.

@zahiraam
Copy link
Contributor Author

Please address @saiislam's questions. I also think that the title and description of the PR should reflect that this PR not only introduces the 6.0 flag, but also moves several of the tests to test against 5.1 and 6.0.

I responded to the question.
The changes in the tests are against 6.0 only. I have only added run lines with fopenmp=6.0.

Copy link
Member

@Meinersbur Meinersbur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is necessary to test each value of -fopenmp-version= separately, but don't mind either as long it doesn't affect maintanability.

  • Instead of repeating each clang diagnositic, consider passing multiple values to -verify, e.g. -verify=omp51,omp60, -verify=omp51-or-before,omp60-or-later

  • Write expected diagnostics on separate lines using @<relative line>-syntax

@zahiraam
Copy link
Contributor Author

I don't think it is necessary to test each value of -fopenmp-version= separately, but don't mind either as long it doesn't affect maintanability.

  • Instead of repeating each clang diagnositic, consider passing multiple values to -verify, e.g. -verify=omp51,omp60, -verify=omp51-exact,omp60-or-lafter
  • Write expected diagnostics on separate lines using @<relative line>-syntax

I think this mostly applies to declare_target_messages.cpp and distribute_simd_misc_messages.c right? Should I change all the lines to the form @<relative line>-syntax?

@Meinersbur
Copy link
Member

Yes, I think that would be helpful. Also, avoid duplicating lines with multiple -verify= prefixes.

@zahiraam
Copy link
Contributor Author

Yes, I think that would be helpful. Also, avoid duplicating lines with multiple -verify= prefixes.

I have made an attempt to edit the 2 LIT tests. I had a hard time finding good names for the verify prefixes. Please don't hesitate to suggest better ones.
We could also use some DEFINE lines for even more readability. declare_target_messages.cpp would become something like this:

// DEFINE: %{limit} = -fnoopenmp-use-tls -ferror-limit 100 
// DEFINE: %{target_mac} = -fopenmp-targets=x86_64-apple-macos10.7.0
// DEFINE: %{aux_triple} = -aux-triple x86_64-apple-macos10.7.0
// DEFINE: %{openmp45} = -fopenmp -fopenmp-version=45
// DEFINE: %{openmp50} = -fopenmp -fopenmp-version=50
// DEFINE: %{openmp60} = -fopenmp -fopenmp-version=60

// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp45,omp45-to-51,omp45-to-51-var,omp45-to-51-clause,omp45-to-51-clause  %{openmp45} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51  %{openmp50} %{target_mac} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var  %{openmp60} %{target_mac} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51,dev5  %{openmp50} -fopenmp-is-target-device %{target_mac} %{aux_triple} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} -fopenmp-is-target-device %{target_mac} %{aux_triple} %{limit} -o - %s

// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51 -fopenmp-simd -fopenmp-version=50 %{target_mac} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var -fopenmp-simd -fopenmp-version=60 %{target_mac} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51 -fopenmp-simd -fopenmp-version=50 -fopenmp-is-target-device %{target_mac} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var -fopenmp-simd -fopenmp-version=60 -fopenmp-is-target-device %{target_mac} %{limit} -o - %s

// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp45,omp45-to-51,omp45-to-51-var,omp45-to-51-clause -fopenmp-version=45 -fopenmp-simd %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -DTESTEND=1 -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -I%S/Inputs -DTESTENDINC=1 -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp-simd %{limit} -o - %s

// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var -fopenmp -fopenmp-version=52 -DVERBOSE_MODE=1 %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} -DVERBOSE_MODE=1 %{limit} -o - %s

// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 %{openmp50} %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -o - %s
// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} %{limit} -o - %s


// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}}
#pragma omp end declare target 

// ompvar-error@+1 {{variable captured in declare target region must appear in a to clause}}
int a, b, z;
// expected-note@+1 {{defined as threadprivate or thread local}}
__thread int t;

// expected-error@+1 {{expected '(' after 'declare target'}}
#pragma omp declare target . 

#pragma omp declare target
void f();
// expected-warning@+1 {{extra tokens at the end of '#pragma omp end declare target' are ignored}}
#pragma omp end declare target shared(a) 

// omp52-error@+8 {{unexpected 'map' clause, only 'enter', 'link', 'device_type' or 'indirect' clauses expected}}
// omp52-error@+7 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp51-error@+6 {{unexpected 'map' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}} 
// omp51-error@+5 {{expected at least one 'to', 'link' or 'indirect' clause}}
// omp5-error@+4 {{unexpected 'map' clause, only 'to', 'link' or 'device_type' clauses expected}}
// omp5-error@+3 {{expected at least one 'to' or 'link' clause}}
// omp45-error@+2 {{unexpected 'map' clause, only 'to' or 'link' clauses expected}}
// omp45-error@+1 {{expected at least one 'to' or 'link' clause}} 
#pragma omp declare target map(a)

// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp45-to-51-error@+1 {{use of undeclared identifier 'foo1'}}
#pragma omp declare target to(foo1) 

// expected-error@+1 {{use of undeclared identifier 'foo2'}}
#pragma omp declare target link(foo2) 

// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// dev5-note@+2 {{marked as 'device_type(host)' here}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(f) device_type(host)

void q();
// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp5-and-51-warning@+2 {{more than one 'device_type' clause is specified}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(q) device_type(any) device_type(any) device_type(host) 

#if _OPENMP == 202011
// omp51-error@+1 {{directive '#pragma omp declare target' cannot contain more than one 'indirect' clause}}
#pragma omp declare target to(q) indirect(true) indirect(false)

// expected-note@+1 {{declared here}}
int xxx;
// omp51-error@+2 {{expression is not an integral constant expression}}
// omp51-note@+1 {{read of non-const variable 'xxx' is not allowed in a constant expression}}
#pragma omp declare target to(q) indirect(xxx)

constexpr bool fz() {return true;}
// omp51-error@+1 {{unexpected 'to' clause, only 'device_type', 'indirect' clauses expected}}
#pragma omp begin declare target to(q) indirect(fz()) device_type(nohost)
#pragma omp end declare target

// omp51-error@+1 {{unexpected 'to' clause, only 'device_type', 'indirect' clauses expected}}
#pragma omp begin declare target indirect to(xxx)
void bar();
#pragma omp end declare target

// omp51-error@+2 {{unexpected 'tofrom' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}}
// omp51-error@+1 {{expected at least one 'to', 'link' or 'indirect' clause}}
#pragma omp declare target tofrom(xxx)

// omp51-error@+1 {{only 'device_type(any)' clause is allowed with indirect clause}}
#pragma omp begin declare target device_type(host) indirect
void bar();
#pragma omp end declare target
#endif  // _OPENMP

void c();

// expected-note@+1 {{'func' defined here}}
void func() {} 

// omp52-error@+5 {{unexpected 'allocate' clause, only 'enter', 'link', 'device_type' or 'indirect' clauses expected}}
// omp51-error@+4 {{unexpected 'allocate' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}}
// omp5-error@+3 {{unexpected 'allocate' clause, only 'to', 'link' or 'device_type' clauses expected}}
// expected-error@+2 {{function name is not allowed in 'link' clause}}
// omp45-error@+1 {{unexpected 'allocate' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target link(func) allocate(a)

void bar();
void baz() {bar();}
// omp5-or-later-warning@+1 {{declaration marked as declare target after first use, it may lead to incorrect results}}
#pragma omp declare target(bar)

extern int b;

struct NonT {
  int a;
};

typedef int sint;

template <typename T>
T bla1() { return 0; }

#pragma omp declare target
template <typename T>
T bla2() { return 0; }
#pragma omp end declare target

template<>
float bla2() { return 1.0; }

#pragma omp declare target
void blub2() {
  bla2<float>();
  bla2<int>();
}
#pragma omp end declare target

void t2() {
#pragma omp target
  {
    bla2<float>();
    bla2<long>();
  }
}

#pragma omp declare target
  void abc();
#pragma omp end declare target
void cba();
// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}}
#pragma omp end declare target 

#pragma omp declare target
#pragma omp declare target
void def();
#pragma omp end declare target
void fed();

#pragma omp declare target
// expected-note@+1 {{defined as threadprivate or thread local}}
#pragma omp threadprivate(a) 
extern int b;
int g;

struct T {
  int a;
  virtual int method();
};

class VC {
  T member;
  NonT member1;
  public:
    virtual int method() { T a; return 0; }
};

struct C {
  NonT a;
  sint b;
  int method();
  int method1();
};

int C::method1() {
  return 0;
}

void foo(int p) {
// expected-error@+1 {{threadprivate variables cannot be used in target constructs}}
  a = 0; 
  b = 0;
// expected-error@+1 {{threadprivate variables cannot be used in target constructs}}
  t = 1; 
  C object;
  VC object1;
  g = object.method();
  g += object.method1();
  g += object1.method() + p;
  // dev5-error@+1 {{function with 'device_type(host)' is not available on device}}
  f(); 
  q();
  c();
}
#pragma omp declare target
void foo1() {
  // omp5-or-later-var-note@+1 {{variable 'z' is captured here}}
  [&](){ (void)(b+z);}(); 
}
#pragma omp end declare target

#pragma omp end declare target
#pragma omp end declare target
// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}}
#pragma omp end declare target 

int C::method() {
  return 0;
}

struct S {
#pragma omp declare target
  int v;
#pragma omp end declare target
};

void foo3() {
  return;
}

int *y;
int **w = &y;
int main (int argc, char **argv) {
  int a = 2;
// expected-error@+1 {{unexpected OpenMP directive '#pragma omp declare target'}}
#pragma omp declare target 
  int v;
// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}}
#pragma omp end declare target 
  foo(v);

  // omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
  // omp52-error@+1 {{unexpected 'to' clause, use 'enter' instead}}
#pragma omp declare target to(foo3) link(w)
  // omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}}
  // omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
  // omp45-to-51-var-error@+1 {{local variable 'a' should not be used in 'declare target' directive}}
#pragma omp declare target to(a) 
  return (0);
}

namespace {
#pragma omp declare target
  int x;
}
#pragma omp end declare target

// expected-error@+1 {{'S' used in declare target directive is not a variable or a function name}}
#pragma omp declare target link(S) 

// expected-error@+1 {{'x' appears multiple times in clauses on the same declare target directive}}
#pragma omp declare target (x, x) 
// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp45-to-51-clause-error@+1 {{'x' appears multiple times in clauses on the same declare target directive}}
#pragma omp declare target to(x) to(x)
// expected-error@+1 {{'x' must not appear in both clauses 'to' and 'link'}}
#pragma omp declare target link(x) 

void bazz() {}
// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// host5-note@+2 3 {{marked as 'device_type(nohost)' here}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} 
#pragma omp declare target to(bazz) device_type(nohost)
void bazzz() {bazz();}
// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(bazzz) device_type(nohost) 
// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}}
void any() {bazz();} 
// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}}
void host1() {bazz();}
// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// dev5-note@+2 3 {{marked as 'device_type(host)' here}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(host1) device_type(host)
//host5-error@+1 {{function with 'device_type(nohost)' is not available on host}}
void host2() {bazz();}
// omp52-error@+2 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+1 {{expected at least one 'enter', 'link' or 'indirect' clause}}
#pragma omp declare target to(host2) 
// dev5-error@+1 {{function with 'device_type(host)' is not available on device}}
void device() {host1();}
// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// host5-note@+2 2 {{marked as 'device_type(nohost)' here}} 
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(device) device_type(nohost)
void host3() {host1();} // dev5-error {{function with 'device_type(host)' is not available on device}}
// omp52-error@+2 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+1 {{expected at least one 'enter', 'link' or 'indirect' clause}}
#pragma omp declare target to(host3)

#pragma omp declare target
void any1() {any();}
// dev5-error@+1 {{function with 'device_type(host)' is not available on device}}
void any2() {host1();} 
// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}}
void any3() {device();}
void any4() {any2();}
#pragma omp end declare target

void any5() {any();}
void any6() {host1();}
// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}}
void any7() {device();}
void any8() {any2();}

int MultiDevTy;
// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(MultiDevTy) device_type(any)
// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// host-5-and-51-error@+2 {{'device_type(host)' does not match previously specified 'device_type(any)' for the same declaration}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(MultiDevTy) device_type(host)
// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// no-host5-and-51-error@+2 {{'device_type(nohost)' does not match previously specified 'device_type(any)' for the same declaration}}
// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}}
#pragma omp declare target to(MultiDevTy) device_type(nohost)

// expected-warning@+1 {{declaration is not declared in any declare target region}}
static int variable = 100; 
static float variable1 = 200;
// expected-warning@+1 {{declaration is not declared in any declare target region}}
static float variable2 = variable1;  

// expected-warning@+1 {{declaration is not declared in any declare target region}}
static int var = 1;  

static int var1 = 10;
static int *var2 = &var1;
// expected-warning@+1 {{declaration is not declared in any declare target region}}
static int **ptr1 = &var2;  

int arr[2] = {1,2};
// expected-warning@+1 {{declaration is not declared in any declare target region}}
int (*arrptr)[2] = &arr;  

class declare{
  public: int x;
          void print();
};
declare obj1;
// expected-warning@+1 {{declaration is not declared in any declare target region}}
declare *obj2 = &obj1;  

struct target{
  int x;
  void print();
};
// expected-warning@+1 {{declaration is not declared in any declare target region}}
static target S;  

#pragma omp declare target
// expected-note@+1 {{used here}}
int target_var = variable;  
// expected-note@+1 {{used here}}
float target_var1 = variable2;  
// expected-note@+1 {{used here}}
int *ptr = &var;  
// expected-note@+1 {{used here}}
int ***ptr2 = &ptr1; 
// expected-note@+1 {{used here}}
int (**ptr3)[2] = &arrptr;
// expected-note@+1 {{used here}}
declare **obj3 = &obj2;
// expected-note@+1 {{used here}}
target *S1 = &S;
#pragma omp end declare target

#if TESTENDINC
#include "unterminated_declare_target_include.h"
#elif TESTEND
// expected-warning@+1 {{expected '#pragma omp end declare target' at end of file to match '#pragma omp declare target'}}
#pragma omp declare target
#else
// expected-warning@+1 {{expected '#pragma omp end declare target' at end of file to match '#pragma omp begin declare target'}}
#pragma omp begin declare target
#endif

What do you think?

@zahiraam
Copy link
Contributor Author

ping @mjklemm.

Copy link
Member

@Meinersbur Meinersbur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nitpicks left. I will LGTM this after you applied them and nobody else has remarks.

Converting all the lines to @+ syntax would not have been necessary, only those you needed to change. I think it has become a lot more maintainable now. For prefix names, I have no better suggestion.

I'd sign off using // DEFINE: as well, but don't require it.

#pragma omp declare target (x, x)
// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}}
// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}}
// omp45-to-51-clause-error@+1 {{'x' appears multiple times in clauses on the same declare target directive}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So much better 👍

Copy link
Contributor

@saiislam saiislam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for sticking up with this patch @zahiraam.
It mostly looks ok to me, but please wait for @mjklemm and @Meinersbur reviews.

@zahiraam
Copy link
Contributor Author

@mjklemm @Meinersbur any more things to add? thanks.

Copy link
Contributor

@mjklemm mjklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@Meinersbur Meinersbur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

@zahiraam zahiraam merged commit 978e083 into llvm:main Jan 29, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants