https://github.com/ravurvi20 updated 
https://github.com/llvm/llvm-project/pull/128640

>From 6ebd5991788608fbd104ea9c23230912044462d3 Mon Sep 17 00:00:00 2001
From: Urvi Rav <urvi.ra...@gmail.com>
Date: Tue, 25 Feb 2025 00:49:07 -0600
Subject: [PATCH 1/3] default clause replaced by otherwise clause for
 metadirective

---
 .../clang/Basic/DiagnosticParseKinds.td       |  4 ++
 clang/lib/Parse/ParseOpenMP.cpp               | 20 ++++++
 clang/test/OpenMP/metadirective_messages.cpp  | 61 +++++++++++++------
 3 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index c513dab810d1f..4b8449e9ee9b6 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1657,6 +1657,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/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 42e6aac681c1c..3b86847e937a2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2759,6 +2759,19 @@ StmtResult 
Parser::ParseOpenMPDeclarativeOrExecutableDirective(
       OpenMPClauseKind CKind = Tok.isAnnotation()
                                    ? OMPC_unknown
                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
+      // Check if the clause is unrecognized.
+      if (getLangOpts().OpenMP < 52 &&
+          (CKind == OMPC_unknown || CKind == OMPC_otherwise)) {
+        Diag(Tok, diag::err_omp_unknown_clause)
+            << PP.getSpelling(Tok) << "metadirective";
+      }
+      if (getLangOpts().OpenMP >= 52 && CKind == OMPC_unknown) {
+        Diag(Tok, diag::err_omp_unknown_clause)
+            << PP.getSpelling(Tok) << "metadirective";
+      }
+      if (CKind == OMPC_default && getLangOpts().OpenMP >= 52) {
+        Diag(Tok, diag::warn_omp_default_deprecated);
+      }
       SourceLocation Loc = ConsumeToken();
 
       // Parse '('.
@@ -2785,6 +2798,13 @@ 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_messages.cpp 
b/clang/test/OpenMP/metadirective_messages.cpp
index 7fce9fa446058..40ea37845fdff 100644
--- a/clang/test/OpenMP/metadirective_messages.cpp
+++ b/clang/test/OpenMP/metadirective_messages.cpp
@@ -2,21 +2,48 @@
 
 // RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -verify -fopenmp-simd -x c++ 
-std=c++14 -fexceptions -fcxx-exceptions %s
 
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -verify=expected,omp52 -fopenmp 
-fopenmp-version=52 -ferror-limit 100 -o - %s -Wuninitialized
+
 void foo() {
-#pragma omp metadirective // expected-error {{expected expression}}
-  ;
-#pragma omp metadirective when() // expected-error {{expected valid context 
selector in when clause}} expected-error {{expected expression}} 
expected-warning {{expected identifier or string literal describing a context 
set; set skipped}} expected-note {{context set options are: 'construct' 
'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored 
set spans until here}}
-  ;
-#pragma omp metadirective when(device{}) // expected-warning {{expected '=' 
after the context set name "device"; '=' assumed}} expected-warning {{expected 
identifier or string literal describing a context selector; selector skipped}} 
expected-note {{context selector options are: 'kind' 'arch' 'isa'}} 
expected-note {{the ignored selector spans until here}} expected-error 
{{expected valid context selector in when clause}} expected-error {{expected 
expression}}
-  ;
-#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)} : ) default(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 = {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}}
-  ;
-}
+  #if _OPENMP >= 202111
+    #pragma omp metadirective // omp52-error {{expected expression}}
+      ;
+    #pragma omp metadirective when() // omp52-error {{expected valid context 
selector in when clause}} expected-error {{expected expression}} 
expected-warning {{expected identifier or string literal describing a context 
set; set skipped}} expected-note {{context set options are: 'construct' 
'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored 
set spans until here}}
+      ;
+    #pragma omp metadirective when(device{}) // omp52-warning {{expected '=' 
after the context set name "device"; '=' assumed}} expected-warning {{expected 
identifier or string literal describing a context selector; selector skipped}} 
expected-note {{context selector options are: 'kind' 'arch' 'isa'}} 
expected-note {{the ignored selector spans until here}} expected-error 
{{expected valid context selector in when clause}} expected-error {{expected 
expression}}
+      ;
+    #pragma omp metadirective when(device{arch(nvptx)}) // omp52-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)}: ) otherwise() // 
omp52-warning {{expected '=' after the context set name "device"; '=' assumed}}
+      ;
+    #pragma omp metadirective when(device = {arch(nvptx)} : ) otherwise(xyz) 
// omp52-error {{expected an OpenMP directive}} expected-error {{use of 
undeclared identifier 'xyz'}}
+      ;
+    #pragma omp metadirective when(device = {arch(nvptx)} : parallel 
otherwise() // omp52-error {{expected ',' or ')' in 'when' clause}} 
expected-error {{expected expression}}
+      ;
+    #pragma omp metadirective when(device = {isa("some-unsupported-feature")} 
: parallel) otherwise(single) // omp52-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() // omp52-warning {{'default' clause for 'metadirective' is 
deprecated; use 'otherwise' instead}}
+      ;
+    #pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz() 
//omp52-error {{unknown clause 'xyz' in metadirective}} 
+      ;
+  #else
+    #pragma omp metadirective // expected-error {{expected expression}}
+      ;
+    #pragma omp metadirective when() // expected-error {{expected valid 
context selector in when clause}} expected-error {{expected expression}} 
expected-warning {{expected identifier or string literal describing a context 
set; set skipped}} expected-note {{context set options are: 'construct' 
'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored 
set spans until here}}
+      ;
+    #pragma omp metadirective when(device{}) // expected-warning {{expected 
'=' after the context set name "device"; '=' assumed}} expected-warning 
{{expected identifier or string literal describing a context selector; selector 
skipped}} expected-note {{context selector options are: 'kind' 'arch' 'isa'}} 
expected-note {{the ignored selector spans until here}} expected-error 
{{expected valid context selector in when clause}} expected-error {{expected 
expression}}
+      ;
+    #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)} : ) default(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 = {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 = {arch(nvptx)} : parallel) xyz() 
//expected-error {{unknown clause 'xyz' in metadirective}} 
+      ;
+  #endif
+  }
\ No newline at end of file

>From 24fe1cf564887de244bf36be44f0664a909332c3 Mon Sep 17 00:00:00 2001
From: urvi-rav <urvi....@hpe.com>
Date: Wed, 2 Apr 2025 00:34:55 -0500
Subject: [PATCH 2/3] Update ParseOpenMP.cpp and error messages

---
 .../clang/Basic/DiagnosticParseKinds.td       |  2 +-
 clang/lib/Parse/ParseOpenMP.cpp               |  8 +++----
 clang/test/OpenMP/metadirective_ast_print.c   | 21 ++++++++++++-------
 clang/test/OpenMP/metadirective_messages.cpp  |  6 ++++--
 4 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index d7346829b047c..0eb496109b5bc 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1661,7 +1661,7 @@ 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">;
+    : Error<"expected an OpenMP clause">;
 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<
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 44375c8849736..21474712ba920 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2760,13 +2760,13 @@ StmtResult 
Parser::ParseOpenMPDeclarativeOrExecutableDirective(
                                    ? OMPC_unknown
                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
       // Check if the clause is unrecognized.
-      if (getLangOpts().OpenMP < 52 &&
-          (CKind == OMPC_unknown || CKind == OMPC_otherwise)) {
+      if (CKind == OMPC_unknown) {
         Diag(Tok, diag::err_omp_unknown_clause)
             << PP.getSpelling(Tok) << "metadirective";
       }
-      if (getLangOpts().OpenMP >= 52 && CKind == OMPC_unknown) {
-        Diag(Tok, diag::err_omp_unknown_clause)
+      if (getLangOpts().OpenMP < 52 &&
+          CKind == OMPC_otherwise) {
+        Diag(Tok, diag::err_omp_unexpected_clause)
             << PP.getSpelling(Tok) << "metadirective";
       }
       if (CKind == OMPC_default && getLangOpts().OpenMP >= 52) {
diff --git a/clang/test/OpenMP/metadirective_ast_print.c 
b/clang/test/OpenMP/metadirective_ast_print.c
index 851f08ce37ee7..4cabc92dd6d30 100644
--- a/clang/test/OpenMP/metadirective_ast_print.c
+++ b/clang/test/OpenMP/metadirective_ast_print.c
@@ -78,10 +78,7 @@ void foo(void) {
   for (int i = 0; i < 16; i++)
     ;
 
-#pragma omp metadirective when(user = {condition(0)}   \
-                              : parallel for) otherwise()
-  for (int i=0; i<10; i++)
-    ;
+
 #pragma omp metadirective when(user = {condition(0)}   \
                               : parallel for)
   for (int i=0; i<10; i++)
@@ -92,10 +89,7 @@ void foo(void) {
   for (int i=0; i<10; i++)
     ;
 
-#pragma omp metadirective when(user = {condition(1)}   \
-                              : parallel for) otherwise()
-  for (int i=0; i<10; i++)
-    ;
+
 #pragma omp metadirective when(user = {condition(1)}   \
                               : parallel for)
   for (int i=0; i<10; i++)
@@ -105,6 +99,17 @@ void foo(void) {
                                                    : parallel) 
default(parallel for)
   for (int i=0; i<10; i++)
     ;
+#if _OPENMP >= 202111
+    #pragma omp metadirective when(user = {condition(0)}       \
+                 : parallel for) otherwise()
+      for (int i=0; i<10; i++)
+        ;
+    
+    #pragma omp metadirective when(user = {condition(1)}       \
+                : parallel for) otherwise()
+      for (int i=0; i<10; i++)
+        ;
+#endif
 }
 
 // CHECK: void bar(void);
diff --git a/clang/test/OpenMP/metadirective_messages.cpp 
b/clang/test/OpenMP/metadirective_messages.cpp
index 40ea37845fdff..ac2a5330cbad3 100644
--- a/clang/test/OpenMP/metadirective_messages.cpp
+++ b/clang/test/OpenMP/metadirective_messages.cpp
@@ -24,7 +24,7 @@ void foo() {
       ;
     #pragma omp metadirective when(device = {arch(nvptx)} : parallel) 
default() // omp52-warning {{'default' clause for 'metadirective' is 
deprecated; use 'otherwise' instead}}
       ;
-    #pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz() 
//omp52-error {{unknown clause 'xyz' in metadirective}} 
+    #pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz() 
//omp52-error {{expected an OpenMP clause}} 
       ;
   #else
     #pragma omp metadirective // expected-error {{expected expression}}
@@ -43,7 +43,9 @@ void foo() {
       ;
     #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 = {arch(nvptx)} : parallel) xyz() 
//expected-error {{unknown clause 'xyz' in metadirective}} 
+    #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}} //expected-error{{unexpected OpenMP clause 'otherwise' in directive 
'#pragma omp metadirective'}}
+      ;
+    #pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz() 
//expected-error {{expected an OpenMP clause}} 
       ;
   #endif
   }
\ No newline at end of file

>From 44a253954921ed7ae363afb3ccca80827c0fc11e Mon Sep 17 00:00:00 2001
From: urvi-rav <urvi....@hpe.com>
Date: Wed, 2 Apr 2025 02:14:31 -0500
Subject: [PATCH 3/3] Update LIT test cases

---
 clang/lib/Parse/ParseOpenMP.cpp               |   3 +-
 clang/test/OpenMP/metadirective_default.cpp   | 198 ++++++++++++++++++
 clang/test/OpenMP/metadirective_otherwise.cpp | 179 ++++++++--------
 3 files changed, 281 insertions(+), 99 deletions(-)
 create mode 100644 clang/test/OpenMP/metadirective_default.cpp

diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 21474712ba920..89c5750d6c63f 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2764,8 +2764,7 @@ StmtResult 
Parser::ParseOpenMPDeclarativeOrExecutableDirective(
         Diag(Tok, diag::err_omp_unknown_clause)
             << PP.getSpelling(Tok) << "metadirective";
       }
-      if (getLangOpts().OpenMP < 52 &&
-          CKind == OMPC_otherwise) {
+      if (getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise) {
         Diag(Tok, diag::err_omp_unexpected_clause)
             << PP.getSpelling(Tok) << "metadirective";
       }
diff --git a/clang/test/OpenMP/metadirective_default.cpp 
b/clang/test/OpenMP/metadirective_default.cpp
new file mode 100644
index 0000000000000..ab269f41b9380
--- /dev/null
+++ b/clang/test/OpenMP/metadirective_default.cpp
@@ -0,0 +1,198 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux 
-emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void func1() {
+
+#pragma omp metadirective when(user = {condition(0)}   \
+                              : parallel for)
+  for (int i = 0; i < 100; i++)
+    ;
+
+#pragma omp metadirective when(user = {condition(0)}                   \
+                              : parallel for)                          \
+  when(implementation = {extension(match_none)}                                
\
+       : parallel) default(parallel for)
+
+  for (int i = 0; i < 100; i++)
+    ;
+
+
+}
+
+// CHECK-LABEL: define dso_local void @_Z5func1v()
+// CHECK:       entry
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 100
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 
0, ptr @_Z5func1v.omp_outlined)
+// CHECK-NEXT:    ret void
+// CHECK-NEXT: }
+
+// CHECK-LABEL: define internal void @_Z5func1v.omp_outlined
+// CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]],
+// CHECK-SAME:  ptr noalias noundef [[DOTBOUND_TID_:%.*]])
+// CHECK-NEXT: entry
+// CHECK-NEXT:    [[GLOB_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[BOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[GLOB_TID__ADDR]], align 8
+// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[BOUND_TID__ADDR]], align 8
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    br label %for.cond
+// CHECK:for.cond:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 100
+// CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK:for.body:
+// CHECK-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK:for.inc:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
+// CHECK-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK:for.end:
+// CHECK-NEXT:  ret void
+// CHECK-NEXT:}
+
+void func2() {
+
+#pragma omp metadirective when(user = {condition(1)}   \
+                              : parallel for)
+  for (int i = 0; i < 100; i++)
+    ;
+}
+
+// CHECK-LABEL: define dso_local void @_Z5func2v()
+// CHECK:       entry
+// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr 
@[[GLOB2:[0-9]+]], i32 0, ptr @_Z5func2v.omp_outlined)
+// CHECK-NEXT:    ret void
+// CHECK-NEXT: }
+
+// CHECK-LABEL: define internal void @_Z5func2v.omp_outlined
+// CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]],
+// CHECK-SAME:  ptr noalias noundef [[DOTBOUND_TID_:%.*]])
+// CHECK-NEXT: entry
+// CHECK-NEXT:    [[GLOB_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[BOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK:       [[OMP_IV:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[TMP:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_LB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_UB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[GLOB_TID__ADDR]], align 8
+// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[BOUND_TID__ADDR]], align 8
+// CHECK:       store i32 0, ptr [[OMP_LB:%.*]], align 4
+// CHECK-NEXT:  store i32 99, ptr [[OMP_UB:%.*]], align 4
+// CHECK-NEXT:  store i32 1, ptr [[OMP_STRIDE:%.*]], align 4
+// CHECK-NEXT:  store i32 0, ptr [[OMP_IS_LAST:%.*]], align 4
+// CHECK-NEXT:  [[TID_PTR:%.*]] = load ptr, ptr [[GLOBAL_TID_ADDR:%.*]], align 
8
+// CHECK-NEXT:  [[TID_VAL:%.*]] = load i32, ptr [[TID_PTR]], align 4
+// CHECK-NEXT:  call void @__kmpc_for_static_init_4(ptr @2, i32 [[TID_VAL]], 
i32 34, ptr [[OMP_IS_LAST]], ptr [[OMP_LB]], ptr [[OMP_UB]], ptr 
[[OMP_STRIDE]], i32 1, i32 1)
+// CHECK-NEXT:  [[UB_VAL:%.*]] = load i32, ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  [[CMP:%.*]] = icmp sgt i32 [[UB_VAL]], 99
+// CHECK-NEXT:  br i1 [[CMP]], label [[COND_TRUE:%.*]], label 
[[COND_FALSE:%.*]]
+// CHECK: cond.true:
+// CHECK-NEXT:  br label [[COND_END:%.*]]
+
+// CHECK:cond.false:
+// CHECK-NEXT:  [[UB_VAL:%.*]] = load i32, ptr [[OMP_UB:%.*]], align 4
+// CHECK-NEXT:  br label [[COND_END]]
+
+// CHECK:cond.end:
+// CHECK-NEXT:  [[COND_PHI:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ 
[[UB_VAL]], [[COND_FALSE]] ]
+// CHECK-NEXT:  store i32 [[COND_PHI]], ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  [[LB_VAL:%.*]] = load i32, ptr [[OMP_LB]], align 4
+// CHECK-NEXT:  store i32 [[LB_VAL]], ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  br label [[OMP_FOR_COND:%.*]]
+
+// CHECK:omp.inner.for.cond:
+// CHECK-NEXT:  [[IV_VAL:%.*]] = load i32, ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  [[UB_VAL2:%.*]] = load i32, ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  [[CMP1:%.*]] = icmp sle i32 [[IV_VAL]], [[UB_VAL2]]
+// CHECK-NEXT:  br i1 [[CMP1]], label [[OMP_FOR_BODY:%.*]], label 
[[OMP_FOR_END:%.*]]
+
+// CHECK:omp.inner.for.body:
+// CHECK-NEXT:  [[IV_VAL2:%.*]] = load i32, ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  [[MUL:%.*]] = mul nsw i32 [[IV_VAL2]], 1
+// CHECK-NEXT:  [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:  store i32 [[ADD]], ptr [[I]], align 4
+// CHECK-NEXT:  br label [[OMP_BODY_CONTINUE:%.*]]
+
+// CHECK:omp.body.continue:
+// CHECK-NEXT:  br label [[OMP_FOR_INC:%.*]]
+
+// CHECK:omp.inner.for.inc:
+// CHECK-NEXT:  [[IV_VAL3:%.*]] = load i32, ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  [[ADD2:%.*]] = add nsw i32 [[IV_VAL3]], 1
+// CHECK-NEXT:  store i32 [[ADD2]], ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  br label [[OMP_FOR_COND]]
+
+// CHECK:omp.inner.for.end:
+// CHECK-NEXT:  br label [[OMP_LOOP_EXIT:%.*]]
+
+// CHECK:omp.loop.exit:
+// CHECK-NEXT:  call void @__kmpc_for_static_fini(ptr @2, i32 [[TID:%.*]])
+// CHECK-NEXT:  ret void
+// CHECK-NEXT: }
+
+void func3() {
+#pragma omp metadirective when(user = {condition(0)}                   \
+                              : parallel for)                          \
+  when(implementation = {extension(match_none)}                                
\
+       : parallel) default(parallel for)
+
+  for (int i = 0; i < 100; i++)
+    ;
+
+}
+
+// CHECK-LABEL: define dso_local void @_Z5func3v()
+// CHECK:       entry
+// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 
0, ptr @_Z5func3v.omp_outlined)
+// CHECK-NEXT:    ret void
+// CHECK-NEXT:   }
+
+// CHECK-LABEL: define internal void @_Z5func3v.omp_outlined
+// CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]],
+// CHECK-SAME:  ptr noalias noundef [[DOTBOUND_TID_:%.*]])
+// CHECK-NEXT:  entry
+// CHECK-NEXT:    [[GLOB_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[BOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[GLOB_TID__ADDR]], align 8
+// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[BOUND_TID__ADDR]], align 8
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    br label %for.cond
+// CHECK:for.cond:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 100
+// CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK:for.body:
+// CHECK-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK:for.inc:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
+// CHECK-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK:for.end:
+// CHECK-NEXT:  ret void
+// CHECK-NEXT:}
+
+#endif
diff --git a/clang/test/OpenMP/metadirective_otherwise.cpp 
b/clang/test/OpenMP/metadirective_otherwise.cpp
index 0533350c84eed..df614e11dc67f 100644
--- a/clang/test/OpenMP/metadirective_otherwise.cpp
+++ b/clang/test/OpenMP/metadirective_otherwise.cpp
@@ -1,105 +1,33 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux 
-emit-llvm %s -o - | FileCheck %s
-// expected-no-diagnostics
-
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -DOMP52 -triple 
x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+//expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
 
-void func1() {
-#pragma omp metadirective when(user = {condition(0)}   \
-                              : parallel for) otherwise()
-  for (int i = 0; i < 100; i++)
-    ;
-
-#pragma omp metadirective when(user = {condition(0)}   \
-                              : parallel for)
-  for (int i = 0; i < 100; i++)
-    ;
-
-#pragma omp metadirective when(user = {condition(0)}                   \
-                              : parallel for)                          \
-  when(implementation = {extension(match_none)}                                
\
-       : parallel) default(parallel for)
-
-  for (int i = 0; i < 100; i++)
-    ;
-
-
-}
-
-// CHECK-LABEL: define dso_local void @_Z5func1v()
-// CHECK:       entry
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[I1:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 100
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    store i32 0, ptr [[I1]], align 4
-// CHECK-NEXT:    br label %[[FOR_COND2:.*]]
-// CHECK:       [[FOR_COND2]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I1]], align 4
-// CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[TMP2]], 100
-// CHECK-NEXT:    br i1 [[CMP3]], label %[[FOR_BODY4:.*]], label 
%[[FOR_END7:.*]]
-// CHECK:       [[FOR_BODY4]]:
-// CHECK-NEXT:    br label %[[FOR_INC5:.*]]
-// CHECK:       [[FOR_INC5]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[I1]], align 4
-// CHECK-NEXT:    [[INC6:%.*]] = add nsw i32 [[TMP3]], 1
-// CHECK-NEXT:    store i32 [[INC6]], ptr [[I1]], align 4
-// CHECK-NEXT:    br label %[[FOR_COND2]], !llvm.loop [[LOOP5:![0-9]+]]
-// CHECK:       [[FOR_END7]]:
-// CHECK:    ret void
-
-void func2() {
-#pragma omp metadirective when(user = {condition(1)}   \
-                              : parallel for) otherwise()
-  for (int i = 0; i < 100; i++)
-    ;
-
-#pragma omp metadirective when(user = {condition(1)}   \
-                              : parallel for)
-  for (int i = 0; i < 100; i++)
-    ;
-}
-
-// CHECK-LABEL: define dso_local void @_Z5func2v()
-// CHECK:       entry
-// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr 
@[[GLOB2:[0-9]+]], i32 0, ptr @_Z5func2v.omp_outlined)
-// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr 
@[[GLOB2]], i32 0, ptr @_Z5func2v.omp_outlined.1)
-// CHECK-NEXT:    ret void
-
-
-void func3() {
-#pragma omp metadirective when(user = {condition(0)}                   \
-                              : parallel for)                          \
-  when(implementation = {extension(match_none)}                                
\
-       : parallel) default(parallel for)
-
-  for (int i = 0; i < 100; i++)
-    ;
-
-}
+#ifdef OMP52
+void func4(){
+  #pragma omp metadirective when(user = {condition(0)}  \
+                 : parallel for) otherwise(parallel)
+      for (int i = 0; i < 100; i++)
+        ;
+  
+  #pragma omp metadirective when(user = {condition(1)}  \
+                : parallel for) otherwise()
+      for (int i = 0; i < 100; i++)
+        ;
+  }
+#endif
 
-// CHECK-LABEL: define dso_local void @_Z5func3v()
-// CHECK:       entry
-// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 
0, ptr @_Z5func3v.omp_outlined)
-// CHECK-NEXT:    ret void
-// CHECK-NEXT:   }
+// CHECK-LABEL: define dso_local void @_Z5func4v()
+// CHECK: entry
+// CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 0, 
ptr @_Z5func4v.omp_outlined)
+// CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 0, 
ptr @_Z5func4v.omp_outlined.1)
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
 
-// CHECK-LABEL: define internal void @_Z5func3v.omp_outlined
+// CHECK-LABEL: define internal void @_Z5func4v.omp_outlined
 // CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]],
 // CHECK-SAME:  ptr noalias noundef [[DOTBOUND_TID_:%.*]])
-// CHECK-NEXT:  entry
+// CHECK: entry
 // CHECK-NEXT:    [[GLOB_TID__ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    [[BOUND_TID__ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
@@ -117,9 +45,66 @@ void func3() {
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
 // CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
-// CHECK-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK-NEXT:    br label [[FOR_COND:%.*]], !llvm.loop ![[LOOPID:[0-9]+]]
 // CHECK:for.end:
 // CHECK-NEXT:  ret void
 // CHECK-NEXT:}
 
-#endif
+// CHECK-LABEL: define internal void @_Z5func4v.omp_outlined.1
+// CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]],
+// CHECK-SAME:  ptr noalias noundef [[DOTBOUND_TID_:%.*]])
+// CHECK-NEXT:  entry
+// CHECK-NEXT:    [[GLOB_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[BOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK:       [[OMP_IV:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[TMP:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_LB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_UB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[OMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK-NEXT:  [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[GLOB_TID__ADDR]], align 8
+// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[BOUND_TID__ADDR]], align 8
+// CHECK:       store i32 0, ptr [[OMP_LB:%.*]], align 4
+// CHECK-NEXT:  store i32 99, ptr [[OMP_UB:%.*]], align 4
+// CHECK-NEXT:  store i32 1, ptr [[OMP_STRIDE:%.*]], align 4
+// CHECK-NEXT:  store i32 0, ptr [[OMP_IS_LAST:%.*]], align 4
+// CHECK-NEXT:  [[TID_PTR:%.*]] = load ptr, ptr [[GLOBAL_TID_ADDR:%.*]], align 
8
+// CHECK-NEXT:  [[TID:%.*]] = load i32, ptr [[TID_PTR]], align 4
+// CHECK-NEXT:  call void @__kmpc_for_static_init_4(ptr @2, i32 [[TID]], i32 
34, ptr [[OMP_IS_LAST]], ptr [[OMP_LB]], ptr [[OMP_UB]], ptr [[OMP_STRIDE]], 
i32 1, i32 1)
+// CHECK:       [[UB_VAL:%.*]] = load i32, ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  [[CMP:%.*]] = icmp sgt i32 [[UB_VAL]], 99
+// CHECK-NEXT:  br i1 [[CMP]], label %cond.true, label %cond.false
+// CHECK:       cond.true:
+// CHECK-NEXT:  br label %cond.end
+// CHECK:       cond.false:
+// CHECK-NEXT:  [[UB_NEW:%.*]] = load i32, ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  br label %cond.end
+// CHECK:       cond.end:
+// CHECK-NEXT:  [[FINAL_UB:%.*]] = phi i32 [ 99, %cond.true ], [ [[UB_NEW]], 
%cond.false ]
+// CHECK-NEXT:  store i32 [[FINAL_UB]], ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  [[LB_VAL:%.*]] = load i32, ptr [[OMP_LB]], align 4
+// CHECK-NEXT:  store i32 [[LB_VAL]], ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  br label %omp.inner.for.cond
+// CHECK:       omp.inner.for.cond:
+// CHECK-NEXT:  [[IV_VAL:%.*]] = load i32, ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  [[UB_FINAL:%.*]] = load i32, ptr [[OMP_UB]], align 4
+// CHECK-NEXT:  [[CMP_LOOP:%.*]] = icmp sle i32 [[IV_VAL]], [[UB_FINAL]]
+// CHECK-NEXT:  br i1 [[CMP_LOOP]], label %omp.inner.for.body, label 
%omp.inner.for.end
+// CHECK:       omp.inner.for.body:
+// CHECK-NEXT:  [[IV_NEW:%.*]] = load i32, ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  [[MUL:%.*]] = mul nsw i32 [[IV_NEW]], 1
+// CHECK-NEXT:  [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:  store i32 [[ADD]], ptr [[I]], align 4
+// CHECK-NEXT:  br label %omp.body.continue
+// CHECK:       omp.inner.for.inc:
+// CHECK-NEXT:  [[IV_CURR:%.*]] = load i32, ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  [[IV_NEXT:%.*]] = add nsw i32 [[IV_CURR]], 1
+// CHECK-NEXT:  store i32 [[IV_NEXT]], ptr [[OMP_IV]], align 4
+// CHECK-NEXT:  br label %omp.inner.for.cond
+// CHECK:       omp.loop.exit:
+// CHECK-NEXT:  call void @__kmpc_for_static_fini(ptr @2, i32 [[TID]])
+// CHECK-NEXT:  ret void
+// CHECK-NEXT: }
+
+#endif
\ No newline at end of file

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to