Skip to content

Conversation

@ravurvi20
Copy link
Contributor

This PR replaces the default clause with the otherwise clause for the metadirective in OpenMP. The otherwise clause serves as a fallback condition when no directive from the when clauses is selected. In the when clause, context selectors define traits evaluated to determine the directive to be applied.

@github-actions
Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" flang:openmp clang:openmp OpenMP related changes to Clang labels Jan 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 30, 2025

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-clang

Author: Urvi Rav (ravurvi20)

Changes

This PR replaces the default clause with the otherwise clause for the metadirective in OpenMP. The otherwise clause serves as a fallback condition when no directive from the when clauses is selected. In the when clause, context selectors define traits evaluated to determine the directive to be applied.


Full diff: https://github.com/llvm/llvm-project/pull/125035.diff

14 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+4)
  • (modified) clang/lib/Basic/OpenMPKinds.cpp (+2)
  • (modified) clang/lib/Parse/ParseOpenMP.cpp (+15)
  • (modified) clang/test/OpenMP/metadirective_ast_print.c (+10-10)
  • (modified) clang/test/OpenMP/metadirective_device_arch_codegen.cpp (+1-1)
  • (modified) clang/test/OpenMP/metadirective_device_isa_codegen.cpp (+2-2)
  • (modified) clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp (+2-2)
  • (modified) clang/test/OpenMP/metadirective_device_kind_codegen.c (+1-1)
  • (modified) clang/test/OpenMP/metadirective_device_kind_codegen.cpp (+1-1)
  • (modified) clang/test/OpenMP/metadirective_empty.cpp (+2-2)
  • (modified) clang/test/OpenMP/metadirective_implementation_codegen.c (+6-6)
  • (modified) clang/test/OpenMP/metadirective_implementation_codegen.cpp (+6-6)
  • (modified) clang/test/OpenMP/metadirective_messages.cpp (+7-4)
  • (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+5)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 3309f59a981fc1..5b7cc463a7d08e 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1647,6 +1647,10 @@ def err_omp_expected_colon : Error<"missing ':' in %0">;
 def err_omp_missing_comma : Error< "missing ',' after %0">;
 def err_omp_expected_context_selector
     : Error<"expected valid context selector in %0">;
+def err_omp_unknown_clause
+    : Error<"unknown clause '%0' in %1">;
+def warn_omp_default_deprecated : Warning<"'default' clause for"
+  " 'metadirective' is deprecated; use 'otherwise' instead">, InGroup<Deprecated>;
 def err_omp_requires_out_inout_depend_type : Error<
   "reserved locator 'omp_all_memory' requires 'out' or 'inout' "
   "dependency types">;
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..a093f7a3b260ff 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -246,6 +246,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
   case OMPC_uses_allocators:
   case OMPC_affinity:
   case OMPC_when:
+  case OMPC_otherwise:
   case OMPC_append_args:
     break;
   default:
@@ -580,6 +581,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
   case OMPC_uses_allocators:
   case OMPC_affinity:
   case OMPC_when:
+  case OMPC_otherwise:
   case OMPC_append_args:
     break;
   default:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 89b83938f352df..673806ef28b9fc 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2743,6 +2743,15 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
       OpenMPClauseKind CKind = Tok.isAnnotation()
                                    ? OMPC_unknown
                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
+      // Check if the clause is unrecognized.
+      if (CKind == OMPC_unknown) {
+        Diag(Tok, diag::err_omp_unknown_clause)
+        << PP.getSpelling(Tok) << "metadirective";
+        return Directive;
+      }
+      if(CKind == OMPC_default) {
+        Diag(Tok, diag::warn_omp_default_deprecated);
+      }
       SourceLocation Loc = ConsumeToken();
 
       // Parse '('.
@@ -2769,6 +2778,12 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
           return Directive;
         }
       }
+      if (CKind == OMPC_otherwise) {
+        // Check for 'otherwise' keyword.
+        if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->getName() == "otherwise") {
+        ConsumeToken();  // Consume 'otherwise'
+        }
+      }
       // Skip Directive for now. We will parse directive in the second iteration
       int paren = 0;
       while (Tok.isNot(tok::r_paren) || paren != 0) {
diff --git a/clang/test/OpenMP/metadirective_ast_print.c b/clang/test/OpenMP/metadirective_ast_print.c
index d9ff7e76452160..28efaac5949427 100644
--- a/clang/test/OpenMP/metadirective_ast_print.c
+++ b/clang/test/OpenMP/metadirective_ast_print.c
@@ -15,18 +15,18 @@ void bar(void);
 #define N 10
 void foo(void) {
 #pragma omp metadirective when(device = {kind(cpu)} \
-                               : parallel) default()
+                               : parallel) otherwise()
   bar();
 #pragma omp metadirective when(implementation = {vendor(score(0)  \
                                                         : llvm)}, \
                                device = {kind(cpu)}               \
-                               : parallel) default(target teams)
+                               : parallel) otherwise(target teams)
   bar();
 #pragma omp metadirective when(device = {kind(gpu)}                                 \
                                : target teams) when(implementation = {vendor(llvm)} \
-                                                    : parallel) default()
+                                                    : parallel) otherwise()
   bar();
-#pragma omp metadirective default(target) when(implementation = {vendor(score(5)  \
+#pragma omp metadirective otherwise(target) when(implementation = {vendor(score(5)  \
                                                                         : llvm)}, \
                                                device = {kind(cpu, host)}         \
                                                : parallel)
@@ -40,15 +40,15 @@ void foo(void) {
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_all)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_any)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_none)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 
@@ -64,17 +64,17 @@ void foo(void) {
 
 #pragma omp metadirective when(device={arch("amdgcn")}: \
                                 teams distribute parallel for)\
-                                default(parallel for)
+                                otherwise(parallel for)
   for (int i = 0; i < 100; i++)
   ;
 
 #pragma omp metadirective when(implementation = {extension(match_all)} \
-                               : nothing) default(parallel for)
+                               : nothing) otherwise(parallel for)
   for (int i = 0; i < 16; i++)
     ;
 
 #pragma omp metadirective when(implementation = {extension(match_any)} \
-                               : parallel) default(nothing)
+                               : parallel) otherwise(nothing)
   for (int i = 0; i < 16; i++)
     ;
 }
diff --git a/clang/test/OpenMP/metadirective_device_arch_codegen.cpp b/clang/test/OpenMP/metadirective_device_arch_codegen.cpp
index eecae310d0a778..c44337b33d5b39 100644
--- a/clang/test/OpenMP/metadirective_device_arch_codegen.cpp
+++ b/clang/test/OpenMP/metadirective_device_arch_codegen.cpp
@@ -27,7 +27,7 @@ int metadirective1() {
    {
       #pragma omp metadirective \
                    when(device={arch("amdgcn")}: teams distribute parallel for) \
-                   default(parallel for)
+                   otherwise(parallel for)
 
          for (int i = 0; i < N; i++) {
 	    #pragma omp atomic write
diff --git a/clang/test/OpenMP/metadirective_device_isa_codegen.cpp b/clang/test/OpenMP/metadirective_device_isa_codegen.cpp
index 1d098063101d7e..1b9829f7a56cef 100644
--- a/clang/test/OpenMP/metadirective_device_isa_codegen.cpp
+++ b/clang/test/OpenMP/metadirective_device_isa_codegen.cpp
@@ -8,7 +8,7 @@ void bar();
 
 void x86_64_device_isa_selected() {
 #pragma omp metadirective when(device = {isa("sse2")} \
-                               : parallel) default(single)
+                               : parallel) otherwise(single)
   bar();
 }
 // CHECK-LABEL: void @_Z26x86_64_device_isa_selectedv()
@@ -21,7 +21,7 @@ void x86_64_device_isa_selected() {
 
 void x86_64_device_isa_not_selected() {
 #pragma omp metadirective when(device = {isa("some-unsupported-feature")} \
-                               : parallel) default(single)
+                               : parallel) otherwise(single)
   bar();
 }
 // CHECK-LABEL: void @_Z30x86_64_device_isa_not_selectedv()
diff --git a/clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp b/clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp
index cbb75c4a68376a..c2c7b72a8469fd 100644
--- a/clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp
+++ b/clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp
@@ -15,7 +15,7 @@ int amdgcn_device_isa_selected() {
   {
 #pragma omp metadirective                     \
     when(device = {isa("dpp")} \
-         : parallel) default(single)
+         : parallel) otherwise(single)
     threadCount++;
   }
 
@@ -38,7 +38,7 @@ int amdgcn_device_isa_not_selected() {
     when(device = {isa("sse")}                                 \
          : parallel)                                           \
         when(device = {isa("another-unsupported-gpu-feature")} \
-             : parallel) default(single)
+             : parallel) otherwise(single)
     threadCount++;
   }
 
diff --git a/clang/test/OpenMP/metadirective_device_kind_codegen.c b/clang/test/OpenMP/metadirective_device_kind_codegen.c
index f77f50426a16d4..0a8c54af2effd1 100644
--- a/clang/test/OpenMP/metadirective_device_kind_codegen.c
+++ b/clang/test/OpenMP/metadirective_device_kind_codegen.c
@@ -30,7 +30,7 @@ void foo(void) {
                                : parallel)
   bar();
 #pragma omp metadirective when(device = {kind(gpu)} \
-                               : target parallel for) default(parallel for)
+                               : target parallel for) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 }
diff --git a/clang/test/OpenMP/metadirective_device_kind_codegen.cpp b/clang/test/OpenMP/metadirective_device_kind_codegen.cpp
index bfbfec8b27e1e8..446fd646ef17fc 100644
--- a/clang/test/OpenMP/metadirective_device_kind_codegen.cpp
+++ b/clang/test/OpenMP/metadirective_device_kind_codegen.cpp
@@ -31,7 +31,7 @@ void foo() {
                                : parallel)
   bar();
 #pragma omp metadirective when(device = {kind(gpu)} \
-                               : target parallel for) default(parallel for)
+                               : target parallel for) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 }
diff --git a/clang/test/OpenMP/metadirective_empty.cpp b/clang/test/OpenMP/metadirective_empty.cpp
index b93ed722cb6e90..9fcd35e82292d9 100644
--- a/clang/test/OpenMP/metadirective_empty.cpp
+++ b/clang/test/OpenMP/metadirective_empty.cpp
@@ -11,12 +11,12 @@ void func() {
   // Test where a valid when clause contains empty directive.
   // The directive will be ignored and code for a serial for loop will be generated.
 #pragma omp metadirective when(implementation = {vendor(llvm)} \
-                               :) default(parallel for)
+                               :) otherwise(parallel for)
   for (int i = 0; i < N; i++)
     ;
 
 #pragma omp metadirective when(implementation = {vendor(llvm)} \
-                               :nothing) default(parallel for)
+                               :nothing) otherwise(parallel for)
   for (int i = 0; i < N; i++)
     ;
 }
diff --git a/clang/test/OpenMP/metadirective_implementation_codegen.c b/clang/test/OpenMP/metadirective_implementation_codegen.c
index da09b639d6d409..dc0bcbaebd0992 100644
--- a/clang/test/OpenMP/metadirective_implementation_codegen.c
+++ b/clang/test/OpenMP/metadirective_implementation_codegen.c
@@ -12,27 +12,27 @@ void foo(void) {
 #pragma omp metadirective when(implementation = {vendor(score(0)  \
                                                         : llvm)}, \
                                device = {kind(cpu)}               \
-                               : parallel) default(target teams)
+                               : parallel) otherwise(target teams)
   bar();
 #pragma omp metadirective when(device = {kind(gpu)}                                 \
                                : target teams) when(implementation = {vendor(llvm)} \
-                                                    : parallel) default()
+                                                    : parallel) otherwise()
   bar();
-#pragma omp metadirective default(target) when(implementation = {vendor(score(5)  \
+#pragma omp metadirective otherwise(target) when(implementation = {vendor(score(5)  \
                                                                         : llvm)}, \
                                                device = {kind(cpu, host)}         \
                                                : parallel)
   bar();
 #pragma omp metadirective when(implementation = {extension(match_all)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_any)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_none)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 }
diff --git a/clang/test/OpenMP/metadirective_implementation_codegen.cpp b/clang/test/OpenMP/metadirective_implementation_codegen.cpp
index b9f43d1a1e87cd..a20b2e2f14bcd4 100644
--- a/clang/test/OpenMP/metadirective_implementation_codegen.cpp
+++ b/clang/test/OpenMP/metadirective_implementation_codegen.cpp
@@ -12,27 +12,27 @@ void foo() {
 #pragma omp metadirective when(implementation = {vendor(score(0)  \
                                                         : llvm)}, \
                                device = {kind(cpu)}               \
-                               : parallel) default(target teams)
+                               : parallel) otherwise(target teams)
   bar();
 #pragma omp metadirective when(device = {kind(gpu)}                                 \
                                : target teams) when(implementation = {vendor(llvm)} \
-                                                    : parallel) default()
+                                                    : parallel) otherwise()
   bar();
-#pragma omp metadirective default(target) when(implementation = {vendor(score(5)  \
+#pragma omp metadirective otherwise(target) when(implementation = {vendor(score(5)  \
                                                                         : llvm)}, \
                                                device = {kind(cpu, host)}         \
                                                : parallel)
   bar();
 #pragma omp metadirective when(implementation = {extension(match_all)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_any)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 #pragma omp metadirective when(implementation = {extension(match_none)} \
-                               : parallel) default(parallel for)
+                               : parallel) otherwise(parallel for)
   for (int i = 0; i < 100; i++)
     ;
 }
diff --git a/clang/test/OpenMP/metadirective_messages.cpp b/clang/test/OpenMP/metadirective_messages.cpp
index b342a094a7870a..4c079b9b68e29c 100644
--- a/clang/test/OpenMP/metadirective_messages.cpp
+++ b/clang/test/OpenMP/metadirective_messages.cpp
@@ -11,12 +11,15 @@ void foo() {
   ;
 #pragma omp metadirective when(device{arch(nvptx)}) // expected-error {{missing ':' in when clause}} expected-error {{expected expression}} expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
   ;
-#pragma omp metadirective when(device{arch(nvptx)}: ) default() // expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
+#pragma omp metadirective when(device{arch(nvptx)}: ) otherwise() // expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
   ;
-#pragma omp metadirective when(device = {arch(nvptx)} : ) default(xyz) // expected-error {{expected an OpenMP directive}} expected-error {{use of undeclared identifier 'xyz'}}
+#pragma omp metadirective when(device = {arch(nvptx)} : ) otherwise(xyz) // expected-error {{expected an OpenMP directive}} expected-error {{use of undeclared identifier 'xyz'}}
   ;
-#pragma omp metadirective when(device = {arch(nvptx)} : parallel default() // expected-error {{expected ',' or ')' in 'when' clause}} expected-error {{expected expression}}
+#pragma omp metadirective when(device = {arch(nvptx)} : parallel otherwise() // expected-error {{expected ',' or ')' in 'when' clause}} expected-error {{expected expression}}
   ;
-#pragma omp metadirective when(device = {isa("some-unsupported-feature")} : parallel) default(single) // expected-warning {{isa trait 'some-unsupported-feature' is not known to the current target; verify the spelling or consider restricting the context selector with the 'arch' selector further}}
+#pragma omp metadirective when(device = {isa("some-unsupported-feature")} : parallel) otherwise(single) // expected-warning {{isa trait 'some-unsupported-feature' is not known to the current target; verify the spelling or consider restricting the context selector with the 'arch' selector further}}
   ;
+#pragma omp metadirective when(device = {arch(nvptx)} : parallel) default() // expected-warning {{'default' clause for 'metadirective' is deprecated; use 'otherwise' instead}}
+  ;
+#pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz(); //expected-error {{unknown clause 'xyz' in metadirective}} expected-error {{use of undeclared identifier 'xyz'}} expected-error {{expected expression}}
 }
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index a4c1964c3e88f5..e185a3b4e4b611 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -525,6 +525,8 @@ def OMPC_Weak : Clause<"weak"> {
 }
 def OMPC_When: Clause<"when"> {
 }
+def OMPC_Otherwise: Clause<"otherwise"> {
+}
 def OMPC_Write : Clause<"write"> {
   let clangClass = "OMPWriteClause";
 }
@@ -844,6 +846,9 @@ def OMP_Metadirective : Directive<"metadirective"> {
   let allowedClauses = [
     VersionedClause<OMPC_When>,
   ];
+  let allowedClauses = [
+    VersionedClause<OMPC_Otherwise>,
+  ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Default>,
   ];

@ravurvi20 ravurvi20 changed the title default clause replaced by otherwise clause in metadirective in OpenMP 5.2 default clause replaced by otherwise clause for metadirective in OpenMP 5.2 Jan 31, 2025
@ravurvi20 ravurvi20 closed this Feb 4, 2025
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 flang:openmp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants