Author: Zahira Ammarguellat
Date: 2026-03-12T05:07:40-07:00
New Revision: 754abc19f05dab4cce698178b08ff2d6f29f65d0

URL: 
https://github.com/llvm/llvm-project/commit/754abc19f05dab4cce698178b08ff2d6f29f65d0
DIFF: 
https://github.com/llvm/llvm-project/commit/754abc19f05dab4cce698178b08ff2d6f29f65d0.diff

LOG: [OpenMP] Add variable capture support for transparent clause expression. 
(#185419)

This patch extends the `transparent` clause implementation to properly
handle runtime variable expressions as the `impex-type` argument, as
required by the OpenMP specification:
`"The use of a variable in an impex-type expression causes an implicit
reference to the variable in all enclosing constructs. The impex-type
expression is evaluated in the context outside of the construct on which
the clause appears."`

Added: 
    

Modified: 
    clang/include/clang/AST/OpenMPClause.h
    clang/lib/AST/OpenMPClause.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/task_transparent_messages.cpp
    clang/test/OpenMP/task_transparent_serialization.cpp
    clang/test/OpenMP/taskloop_codegen.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index e6b9c47a90c76..af5d3f4698eda 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1506,7 +1506,9 @@ class OMPThreadsetClause final : public OMPClause {
 /// clause with OpenMP keyword 'omp_not_impex`. Other valid keywords that may
 /// appear in this clause are 'omp_import', 'omp_export' and 'omp_impex'.
 ///
-class OMPTransparentClause final : public OMPClause {
+class OMPTransparentClause final
+    : public OMPOneStmtClause<llvm::omp::OMPC_transparent, OMPClause>,
+      public OMPClauseWithPreInit {
   friend class OMPClauseReader;
 
   /// Location of '('.
@@ -1530,15 +1532,18 @@ class OMPTransparentClause final : public OMPClause {
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
   /// \param EndLoc Ending location of the clause.
-  OMPTransparentClause(Expr *ImpexTypeKind, SourceLocation StartLoc,
-                       SourceLocation LParenLoc, SourceLocation EndLoc)
-      : OMPClause(llvm::omp::OMPC_transparent, StartLoc, EndLoc),
-        LParenLoc(LParenLoc), ImpexType(ImpexTypeKind) {}
+  OMPTransparentClause(Expr *ImpexTypeKind, Stmt *HelperValStmt,
+                       OpenMPDirectiveKind CaptureRegion,
+                       SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc)
+      : OMPOneStmtClause(ImpexTypeKind, StartLoc, LParenLoc, EndLoc),
+        OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
+        ImpexType(ImpexTypeKind) {
+    setPreInitStmt(HelperValStmt, CaptureRegion);
+  }
 
   /// Build an empty clause.
-  OMPTransparentClause()
-      : OMPClause(llvm::omp::OMPC_transparent, SourceLocation(),
-                  SourceLocation()) {}
+  OMPTransparentClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
 
   /// Returns the location of '('.
   SourceLocation getLParenLoc() const { return LParenLoc; }

diff  --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 48ec1551d0607..d4826c3c6edca 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -109,6 +109,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const 
OMPClause *C) {
     return static_cast<const OMPDynGroupprivateClause *>(C);
   case OMPC_message:
     return static_cast<const OMPMessageClause *>(C);
+  case OMPC_transparent:
+    return static_cast<const OMPTransparentClause *>(C);
   case OMPC_default:
   case OMPC_proc_bind:
   case OMPC_safelen:
@@ -127,7 +129,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const 
OMPClause *C) {
   case OMPC_untied:
   case OMPC_mergeable:
   case OMPC_threadset:
-  case OMPC_transparent:
   case OMPC_threadprivate:
   case OMPC_groupprivate:
   case OMPC_flush:

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index e8a7c1d5e9288..bbb4f939028ec 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17514,25 +17514,38 @@ OMPClause 
*SemaOpenMP::ActOnOpenMPThreadsetClause(OpenMPThreadsetKind Kind,
       OMPThreadsetClause(Kind, KindLoc, StartLoc, LParenLoc, EndLoc);
 }
 
-static OMPClause *createTransparentClause(Sema &SemaRef, ASTContext &Ctx,
-                                          Expr *ImpexTypeArg,
-                                          SourceLocation StartLoc,
-                                          SourceLocation LParenLoc,
-                                          SourceLocation EndLoc) {
+static OMPClause *
+createTransparentClause(Sema &SemaRef, ASTContext &Ctx, Expr *ImpexTypeArg,
+                        Stmt *HelperValStmt, OpenMPDirectiveKind CaptureRegion,
+                        SourceLocation StartLoc, SourceLocation LParenLoc,
+                        SourceLocation EndLoc) {
   ExprResult ER = SemaRef.DefaultLvalueConversion(ImpexTypeArg);
   if (ER.isInvalid())
     return nullptr;
 
-  return new (Ctx) OMPTransparentClause(ER.get(), StartLoc, LParenLoc, EndLoc);
+  return new (Ctx) OMPTransparentClause(ER.get(), HelperValStmt, CaptureRegion,
+                                        StartLoc, LParenLoc, EndLoc);
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPTransparentClause(Expr *ImpexTypeArg,
                                                     SourceLocation StartLoc,
                                                     SourceLocation LParenLoc,
                                                     SourceLocation EndLoc) {
+  Stmt *HelperValStmt = nullptr;
+  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
+  OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
+      DKind, OMPC_transparent, getLangOpts().OpenMP);
+  if (CaptureRegion != OMPD_unknown &&
+      !SemaRef.CurContext->isDependentContext()) {
+    Expr *ValExpr = SemaRef.MakeFullExpr(ImpexTypeArg).get();
+    llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
+    ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
+    HelperValStmt = buildPreInits(getASTContext(), Captures);
+  }
   if (!ImpexTypeArg) {
     return new (getASTContext())
-        OMPTransparentClause(ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
+        OMPTransparentClause(ImpexTypeArg, HelperValStmt, CaptureRegion,
+                             StartLoc, LParenLoc, EndLoc);
   }
   QualType Ty = ImpexTypeArg->getType();
 
@@ -17547,14 +17560,15 @@ OMPClause 
*SemaOpenMP::ActOnOpenMPTransparentClause(Expr *ImpexTypeArg,
           << TypedefName;
       return nullptr;
     }
-    return createTransparentClause(SemaRef, getASTContext(), ImpexTypeArg,
-                                   StartLoc, LParenLoc, EndLoc);
+    return new (getASTContext())
+        OMPTransparentClause(ImpexTypeArg, HelperValStmt, CaptureRegion,
+                             StartLoc, LParenLoc, EndLoc);
   }
 
   if (Ty->isEnumeralType())
     return createTransparentClause(SemaRef, getASTContext(), ImpexTypeArg,
-                                   StartLoc, LParenLoc, EndLoc);
-
+                                   HelperValStmt, CaptureRegion, StartLoc,
+                                   LParenLoc, EndLoc);
   if (Ty->isIntegerType()) {
     if (isNonNegativeIntegerValue(ImpexTypeArg, SemaRef, OMPC_transparent,
                                   /*StrictlyPositive=*/false)) {
@@ -17568,12 +17582,16 @@ OMPClause 
*SemaOpenMP::ActOnOpenMPTransparentClause(Expr *ImpexTypeArg,
                 static_cast<int64_t>(SemaOpenMP::OpenMPImpexType::OMP_Export))
           SemaRef.Diag(StartLoc, diag::err_omp_transparent_invalid_value);
       }
-      return createTransparentClause(SemaRef, getASTContext(), ImpexTypeArg,
-                                     StartLoc, LParenLoc, EndLoc);
+      return new (getASTContext())
+          OMPTransparentClause(ImpexTypeArg, HelperValStmt, CaptureRegion,
+                               StartLoc, LParenLoc, EndLoc);
     }
   }
-  SemaRef.Diag(StartLoc, diag::err_omp_transparent_invalid_type) << Ty;
-  return nullptr;
+  if (!isNonNegativeIntegerValue(ImpexTypeArg, SemaRef, OMPC_transparent,
+                                 /*StrictlyPositive=*/true))
+    return nullptr;
+  return new (getASTContext()) OMPTransparentClause(
+      ImpexTypeArg, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPProcBindClause(ProcBindKind Kind,

diff  --git a/clang/test/OpenMP/task_transparent_messages.cpp 
b/clang/test/OpenMP/task_transparent_messages.cpp
index a58df6ba2a77b..8ad90fc80310f 100644
--- a/clang/test/OpenMP/task_transparent_messages.cpp
+++ b/clang/test/OpenMP/task_transparent_messages.cpp
@@ -31,13 +31,13 @@ void TestTaskTransparentWithErrors() {
 #pragma omp task transparent(omp_impex)
   // expected-error@+1{{invalid value for transparent clause, expected one of: 
omp_not_impex, omp_import, omp_export, omp_impex}}
 #pragma omp task transparent(5)
-  // expected-error@+1{{transparent clause cannot be applied to type: 'int *'}}
+  // expected-error@+1{{expression must have integral or unscoped enumeration 
type, not 'int *'}}
 #pragma omp task transparent(ptr)
-  // expected-error@+1{{transparent clause cannot be applied to type: 'int *'}}
+  // expected-error@+1{{expression must have integral or unscoped enumeration 
type, not 'int *'}}
 #pragma omp task transparent(&x)
-  // expected-error@+1{{transparent clause cannot be applied to type: 
'double'}}
+  // expected-error@+1{{expression must have integral or unscoped enumeration 
type, not 'double'}}
 #pragma omp task transparent(20.0)
-  // expected-error@+1{{transparent clause cannot be applied to type: 
'int[5]'}}
+  // expected-error@+1{{expression must have integral or unscoped enumeration 
type, not 'int[5]'}}
 #pragma omp task transparent(arr)
   for (int i = 0; i < 5; ++i) {}
 }

diff  --git a/clang/test/OpenMP/task_transparent_serialization.cpp 
b/clang/test/OpenMP/task_transparent_serialization.cpp
index 110bd608b41ab..5b3a915149705 100644
--- a/clang/test/OpenMP/task_transparent_serialization.cpp
+++ b/clang/test/OpenMP/task_transparent_serialization.cpp
@@ -11,108 +11,259 @@ extern const omp_impex_t omp_import;
 extern const omp_impex_t omp_export;
 extern const omp_impex_t omp_impex;
 
-template <typename T>
-class TransparentTemplate {
-public:
-  void TestTaskLoopImpex() {
-    #pragma omp taskloop transparent(omp_impex)
-    for (int i = 0; i < 10; ++i) {}
-  }
-};
-
-void TestTaskTransparent() {
-  int a;
-  omp_impex_t imp;
-#pragma omp task transparent(omp_not_impex)
-#pragma omp task transparent(imp)
-
-#pragma omp parallel
-  {
-#pragma omp task transparent(omp_export)
-    {
-#pragma omp taskloop transparent(omp_impex)
-      for (int i = 0; i < 5; ++i) {}
-    }
-  }
-  TransparentTemplate<int> obj;
-  obj.TestTaskLoopImpex();
-}
-#endif
-
-
 // CHECK: FunctionDecl {{.*}} TestTaskTransparent 'void ()'
 // CHECK: OMPTaskDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_not_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: OMPFirstprivateClause
 // CHECK-NEXT: DeclRefExpr {{.*}} 'omp_impex_t':'void **' lvalue Var {{.*}} 
'imp' 'omp_impex_t':'void **' refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'omp_impex_t':'void **' lvalue Var {{.*}} 
'imp' 'omp_impex_t':'void **' refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: OMPFirstprivateClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: OMPFirstprivateClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+// CHECK-NEXT: CapturedDecl
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: BinaryOperator {{.*}} 'int' '+'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:30> 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: IntegerLiteral {{.*}} <col:32> 'int' 1
+// CHECK-NEXT: CapturedStmt
+// CHEC-NEXT: CapturedDecl
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT:  OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_export' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
-// CHECK:  OMPTaskDirective
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK: CapturedStmt
+// CHECK: OMPTaskDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_export' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_export' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
+// CHECK-NEXT: BinaryOperator {{.*}} 'int' '+'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: IntegerLiteral {{.*}} <col:32> 'int' 1
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr{{.*}} 'const omp_impex_t':'void **const' lvalue Var 
{{.*}} 'omp_export' 'const omp_impex_t':'void **const'
+/// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_export' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_export' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
 // CHECK: OMPTaskLoopDirective
 // CHECK-NEXT: OMPTransparentClause
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'omp_impex_t':'void **' <LValueToRValue>
 // CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
 // CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_export' 'const omp_impex_t':'void **const'
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+// CHECK: OMPTaskLoopDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+template <typename T>
+class TransparentTemplate {
+public:
+  void TestTaskLoopImpex() {
+    #pragma omp taskloop transparent(omp_impex)
+    for (int i = 0; i < 10; ++i) {}
+  }
+};
+
+void TestTaskTransparent() {
+  int a;
+  omp_impex_t imp;
+#pragma omp task transparent(omp_not_impex)
+#pragma omp task transparent(imp)
+#pragma omp task transparent(a)
+#pragma omp task transparent(a+1)
+
+#pragma omp parallel
+  {
+#pragma omp task transparent(omp_export)
+    {
+#pragma omp taskloop transparent(omp_impex)
+      for (int i = 0; i < 5; ++i) {}
+    }
+  }
+  TransparentTemplate<int> obj;
+  obj.TestTaskLoopImpex();
+}
+
+
+// CHECK: FunctionDecl {{.*}} 
TestTransparentImplicitFirstprivateOnEnclosingTask1 'void ()'
+
+// outer task (1)
+// CHECK: OMPTaskDirective
+
+// 'a' is firstprivate on outer
+// CHECK-NEXT: OMPFirstprivateClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+
+// inner task (2)
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+void TestTransparentImplicitFirstprivateOnEnclosingTask1() {
+  int a;
+#pragma omp task                // (1)
+  {
+#pragma omp task transparent(a) // (2)
+    {}
+  }
+}
+
+// CHECK: FunctionDecl {{.*}} 
TestTransparentImplicitFirstprivateOnEnclosingTask2 'void ()'
+
+// outer task (1)
+// CHECK: OMPTaskDirective
+
+// 'a' is firstprivate on outer task (1)
+// CHECK-NEXT: OMPFirstprivateClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+
+// inner task (2)
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+
+// 'a' is firstprivate on outer task (2)
+// CHECK-NEXT: OMPFirstprivateClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+
+// inner task (3)
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: BinaryOperator {{.*}} 'int' '+'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
+// CHECK-NEXT: CapturedStmt
+void TestTransparentImplicitFirstprivateOnEnclosingTask2() {
+  int a;
+#pragma omp task                  // (1)
+  {
+#pragma omp task transparent(a)   // (2)
+#pragma omp task transparent(a+1) // (3)
+    {}
+  }
+}
+
+// CHECK: FunctionDecl {{.*}} 
TestTransparentImplicitFirstprivateOnEnclosingTask3 'void ()'
+
+// outer task (1)
+// CHECK: OMPTaskDirective
+
+// 'a' is firstprivate on outer task (1)
+// CHECK-NEXT: OMPFirstprivateClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
+
+// inner task (2)
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'a' 'int' 
refers_to_enclosing_variable_or_capture
+// CHECK-NEXT: CapturedStmt
 
+// inner task (3)
+// CHECK: OMPTaskDirective
+// CHECK-NEXT: OMPTransparentClause
+// CHECK-NEXT: DeclRefExpr {{.*}} 'const omp_impex_t':'void **const' lvalue 
Var {{.*}} 'omp_impex' 'const omp_impex_t':'void **const'
+// CHECK-NEXT: CapturedStmt
+void TestTransparentImplicitFirstprivateOnEnclosingTask3() {
+  int a;
+#pragma omp task                        // (1)
+  {
+#pragma omp task transparent(a)         // (2)
+#pragma omp task transparent(omp_impex) // (3)
+    {}
+  }
+}
 
+#endif
 

diff  --git a/clang/test/OpenMP/taskloop_codegen.cpp 
b/clang/test/OpenMP/taskloop_codegen.cpp
index b5bbf6e259c35..f401da5c791e9 100644
--- a/clang/test/OpenMP/taskloop_codegen.cpp
+++ b/clang/test/OpenMP/taskloop_codegen.cpp
@@ -265,6 +265,7 @@ void test_threadset()
 
 void test_transparent()
 {
+  int a;
 #pragma omp taskloop transparent priority(10)
   for (int i = 0; i < 10; ++i) {
   }
@@ -283,6 +284,12 @@ void test_transparent()
 #pragma omp taskloop transparent(omp_impex)
   for (int i = 0; i < 10; ++i) {
   }
+#pragma omp taskloop transparent(a)
+  for (int i = 0; i < 10; ++i) {
+  }
+#pragma omp taskloop transparent(a+1)
+  for (int i = 0; i < 10; ++i) {
+  }
 }
 
 #endif // OMP60
@@ -323,107 +330,141 @@ void test_transparent()
 // CHECK6-NEXT:       call void @__kmpc_end_taskgroup(ptr @1, i32 %[[TID0:.*]])
 // CHECK6-NEXT:       ret void
 
-// CHECK6: define void @_Z16test_transparentv
-// CHECK6: entry:
-// CHECK6:  [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON_18:%.*]], align 1
-// CHECK6:  [[TMP:%.*]] = alloca i32, align 4
-// CHECK6:  [[AGG_CAPTURED1:%.*]] = alloca [[STRUCT_ANON_20:%.*]], align 1
-// CHECK6:  [[TMP2:%.*]] = alloca i32, align 4
-// CHECK6:  [[AGG_CAPTURED3:%.*]] = alloca [[STRUCT_ANON_22:%.*]], align 1
-// CHECK6:  [[TMP4:%.*]] = alloca i32, align 4
-// CHECK6:  [[AGG_CAPTURED5:%.*]] = alloca [[STRUCT_ANON_24:%.*]], align 1
-// CHECK6:  [[TMP6:%.*]] = alloca i32, align 4
-// CHECK6:  [[AGGD_CAPTURED9:%.*]] = alloca [[STRUCT_ANON_28:%.*]], align 1
-// CHECK6:  [[TMP10:%.*]] = alloca i32, align 4
-// CHECK6:  [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
-// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  [[TMP1:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 289, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY1:[0-9]+]])
-// CHECK6:  [[TMP2:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP1]], i32 0, i32 0
-// CHECK6:  [[TMP3:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 4
-// CHECK6:  store i32 10, ptr [[TMP3]], align 8
-// CHECK6:  [[TMP4:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP2]], i32 0, i32 5
-// CHECK6:  store i64 0, ptr [[TMP4]], align 8
-// CHECK6:  [[TMP5:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 6
-// CHECK6:  store i64 9, ptr [[TMP5]], align 8
-// CHECK6:  [[TMP6:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 7
-// CHECK6:  store i64 1, ptr [[TMP6]], align 8
-// CHECK6:  [[TMP7:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 9
-// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP7]], i8 0, i64 8, 
i1 false)
-// CHECK6:  [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
-// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP1]], i32 
1, ptr [[TMP4]], ptr [[TMP5]], i64 [[TMP8]], i32 1, i32 0, i64 0, ptr null)
-// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  [[TMP9:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY2:[0-9]+]])
-// CHECK6:  [[TMP10:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP9]], i32 0, i32 0
-// CHECK6:  [[TMP11:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 5
-// CHECK6:  store i64 0, ptr [[TMP11]], align 8
-// CHECK6:  [[TMP12:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 6
-// CHECK6:  store i64 9, ptr [[TMP12]], align 8
-// CHECK6:  [[TMP13:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 7
-// CHECK6:  store i64 1, ptr [[TMP13]], align 8
-// CHECK6:  [[TMP14:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 9
-// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP14]], i8 0, i64 8, 
i1 false)
-// CHECK6:  [[TMP15:%.*]] = load i64, ptr [[TMP13]], align 8
-// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP9]], i32 
1, ptr [[TMP11]], ptr [[TMP12]], i64 [[TMP15]], i32 1, i32 0, i64 0, ptr null)
-// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  [[TMP16:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..22)
-// CHECK6:  [[TMP17:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP16]], i32 0, i32 0
-// CHECK6:  [[TMP18:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 5
-// CHECK6:  store i64 0, ptr [[TMP18]], align 8
-// CHECK6:  [[TMP19:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 6
-// CHECK6:  store i64 9, ptr [[TMP19]], align 8
-// CHECK6:  [[TMP20:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 7
-// CHECK6:  store i64 1, ptr [[TMP20]], align 8
-// CHECK6:  [[TMP21:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 9
-// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP21]], i8 0, i64 8, 
i1 false)
-// CHECK6:  [[TMP22:%.*]] = load i64, ptr [[TMP20]], align 8
-// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP16]], 
i32 1, ptr [[TMP18]], ptr [[TMP19]], i64 [[TMP22]], i32 1, i32 0, i64 0, ptr 
null)
-// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  [[TMP23:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..24)
-// CHECK6:  [[TMP24:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP23]], i32 0, i32 0
-// CHECK6:  [[TMP25:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 5
-// CHECK6:  store i64 0, ptr [[TMP25]], align 8
-// CHECK6:  [[TMP26:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 6
-// CHECK6:  store i64 9, ptr [[TMP26]], align 8
-// CHECK6:  [[TMP27:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 7
-// CHECK6:  store i64 1, ptr [[TMP27]], align 8
-// CHECK6:  [[TMP28:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 9
-// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, i64 8, 
i1 false)
-// CHECK6:  [[TMP29:%.*]] = load i64, ptr [[TMP27]], align 8
-// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP23]], 
i32 1, ptr [[TMP25]], ptr [[TMP26]], i64 [[TMP29]], i32 1, i32 0, i64 0, ptr 
null)
-// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-LABEL: define void @_Z16test_transparentv
+// CHECK6-NEXT: entry:
+// CHECK6-NEXT:  [[A:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON_18:%.*]], align 1
+// CHECK6-NEXT:  [[TMP:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED1:%.*]] = alloca [[STRUCT_ANON_20:%.*]], align 1
+// CHECK6-NEXT:  [[TMP2:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED3:%.*]] = alloca [[STRUCT_ANON_22:%.*]], align 1
+// CHECK6-NEXT:  [[TMP4:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED5:%.*]] = alloca [[STRUCT_ANON_24:%.*]], align 1
+// CHECK6-NEXT:  [[TMP6:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED7:%.*]] = alloca [[STRUCT_ANON_26:%.*]], align 1
+// CHECK6-NEXT:  [[TMP8:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGGD_CAPTURED9:%.*]] = alloca [[STRUCT_ANON_28:%.*]], align 
1
+// CHECK6-NEXT:  [[TMP10:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED11:%.*]] = alloca [[STRUCT_ANON_30:%.*]], align 
1
+// CHECK6-NEXT:  [[TMP12:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[AGG_CAPTURED13:%.*]] = alloca [[STRUCT_ANON_32:%.*]], align 
1
+// CHECK6-NEXT:  [[TMP14:%.*]] = alloca i32, align 4
+// CHECK6-NEXT:  [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP1:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 289, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY1:[0-9]+]])
+// CHECK6-NEXT:  [[TMP2:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP1]], i32 0, i32 0
+// CHECK6-NEXT:   [[TMP3:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP2]], i32 0, i32 4
+// CHECK6-NEXT:  store i32 10, ptr [[TMP3]], align 8
+// CHECK6-NEXT:  [[TMP4:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP2]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP4]], align 8
+// CHECK6-NEXT:  [[TMP5:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP5]], align 8
+// CHECK6-NEXT:  [[TMP6:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP6]], align 8
+// CHECK6-NEXT:  [[TMP7:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP7]], i8 0, i64 
8, i1 false)
+// CHECK6-NEXT:  [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP1]], i32 1, ptr [[TMP4]], ptr [[TMP5]], i64 [[TMP8]], i32 1, i32 0, i64 0, 
ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP9:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..20)
+// CHECK6-NEXT:  [[TMP10:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP9]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP11:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP11]], align 8
+// CHECK6-NEXT:  [[TMP12:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP12]], align 8
+// CHECK6-NEXT:  [[TMP13:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP13]], align 8
+// CHECK6-NEXT:  [[TMP14:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP10]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP14]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP15:%.*]] = load i64, ptr [[TMP13]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP9]], i32 1, ptr [[TMP11]], ptr [[TMP12]], i64 [[TMP15]], i32 1, i32 0, i64 
0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP16:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY22:[0-9]+]])
+// CHECK6-NEXT:  [[TMP17:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP16]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP18:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP18]], align 8
+// CHECK6-NEXT:  [[TMP19:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP19]], align 8
+// CHECK6-NEXT:  [[TMP20:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP20]], align 8
+// CHECK6-NEXT:  [[TMP21:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP17]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP21]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP22:%.*]] = load i64, ptr [[TMP20]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP16]], i32 1, ptr [[TMP18]], ptr [[TMP19]], i64 [[TMP22]], i32 1, i32 0, 
i64 0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP23:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY24:[0-9]+]])
+// CHECK6-NEXT:  [[TMP24:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP23]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP25:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP25]], align 8
+// CHECK6-NEXT:  [[TMP26:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP26]], align 8
+// CHECK6-NEXT:  [[TMP27:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP27]], align 8
+// CHECK6-NEXT:  [[TMP28:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t{{.*}}, ptr [[TMP24]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP28]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP29:%.*]] = load i64, ptr [[TMP27]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP23]], i32 1, ptr [[TMP25]], ptr [[TMP26]], i64 [[TMP29]], i32 1, i32 0, 
i64 0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
 
-// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  [[TMP30:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY26:[0-9]+]])
-// CHECK6:  [[TMP31:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates.27, ptr [[TMP30]], i32 0, i32 0
-// CHECK6:  [[TMP32:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP31]], i32 0, i32 5
-// CHECK6:  store i64 0, ptr [[TMP32]], align 8
-// CHECK6:  [[TMP33:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP31]], i32 0, i32 6
-// CHECK6:  store i64 9, ptr [[TMP33]], align 8
-// CHECK6:  [[TMP34:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP31]], i32 0, i32 7
-// CHECK6:  store i64 1, ptr [[TMP34]], align 8
-// CHECK6:  [[TMP35:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP31]], i32 0, i32 9
-// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP35]], i8 0, i64 8, 
i1 false)
-// CHECK6:  [[TMP36:%.*]] = load i64, ptr [[TMP34]], align 8
-// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP30]], 
i32 1, ptr [[TMP32]], ptr [[TMP33]], i64 [[TMP36]], i32 1, i32 0, i64 0, ptr 
null)
-// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  [[TMP37:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY28:[0-9]+]])
-// CHECK6:  [[TMP38:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates.29, ptr [[TMP37]], i32 0, i32 0
-// CHECK6:  [[TMP39:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP38]], i32 0, i32 5
-// CHECK6:  store i64 0, ptr [[TMP39]], align 8
-// CHECK6:  [[TMP40:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP38]], i32 0, i32 6
-// CHECK6:  store i64 9, ptr [[TMP40]], align 8
-// CHECK6:  [[TMP41:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP38]], i32 0, i32 7
-// CHECK6:  store i64 1, ptr [[TMP41]], align 8
-// CHECK6:  [[TMP42:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t.2, 
ptr [[TMP38]], i32 0, i32 9
-// CHECK6:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP42]], i8 0, i64 8, 
i1 false)
-// CHECK6:  [[TMP43:%.*]] = load i64, ptr [[TMP41]], align 8
-// CHECK6:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP37]], 
i32 1, ptr [[TMP39]], ptr [[TMP40]], i64 [[TMP43]], i32 1, i32 0, i64 0, ptr 
null)
-// CHECK6:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
-// CHECK6:  ret void
-// CHECK6:}
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP30:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY26:[0-9]+]])
+// CHECK6-NEXT:  [[TMP31:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates.27, ptr [[TMP30]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP32:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP31]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP32]], align 8
+// CHECK6-NEXT:  [[TMP33:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP31]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP33]], align 8
+// CHECK6-NEXT:  [[TMP34:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP31]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP34]], align 8
+// CHECK6-NEXT:  [[TMP35:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP31]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP35]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP36:%.*]] = load i64, ptr [[TMP34]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP30]], i32 1, ptr [[TMP32]], ptr [[TMP33]], i64 [[TMP36]], i32 1, i32 0, 
i64 0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP37:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY28:[0-9]+]])
+// CHECK6-NEXT:  [[TMP38:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates.29, ptr [[TMP37]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP39:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP38]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP39]], align 8
+// CHECK6-NEXT:  [[TMP40:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP38]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP40]], align 8
+// CHECK6-NEXT:  [[TMP41:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP38]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP41]], align 8
+// CHECK6-NEXT:  [[TMP42:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP38]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP42]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP43:%.*]] = load i64, ptr [[TMP41]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP37]], i32 1, ptr [[TMP39]], ptr [[TMP40]], i64 [[TMP43]], i32 1, i32 0, 
i64 0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP44:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY30:[0-9]+]])
+// CHECK6-NEXT:  [[TMP45:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP44]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP46:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP45]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP46]], align 8
+// CHECK6-NEXT:  [[TMP47:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP45]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP47]], align 8
+// CHECK6-NEXT:  [[TMP48:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP45]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP48]], align 8
+// CHECK6-NEXT:  [[TMP49:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP45]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP49]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP50:%.*]] = load i64, ptr [[TMP48]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP44]], i32 1, ptr [[TMP46]], ptr [[TMP47]], i64 [[TMP50]], i32 1, i32 0, 
i64 0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  call void @__kmpc_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  [[TMP51:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 
[[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..32)
+// CHECK6-NEXT:  [[TMP52:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP51]], i32 0, i32 0
+// CHECK6-NEXT:  [[TMP53:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP52]], i32 0, i32 5
+// CHECK6-NEXT:  store i64 0, ptr [[TMP53]], align 8
+// CHECK6-NEXT:  [[TMP54:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP52]], i32 0, i32 6
+// CHECK6-NEXT:  store i64 9, ptr [[TMP54]], align 8
+// CHECK6-NEXT:  [[TMP55:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP52]], i32 0, i32 7
+// CHECK6-NEXT:  store i64 1, ptr [[TMP55]], align 8
+// CHECK6-NEXT:  [[TMP56:%.*]] = getelementptr inbounds nuw 
%struct.kmp_task_t.2, ptr [[TMP52]], i32 0, i32 9
+// CHECK6-NEXT:  call void @llvm.memset.p0.i64(ptr align 8 [[TMP56]], i8 0, 
i64 8, i1 false)
+// CHECK6-NEXT:  [[TMP57:%.*]] = load i64, ptr [[TMP55]], align 8
+// CHECK6-NEXT:  call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr 
[[TMP51]], i32 1, ptr [[TMP53]], ptr [[TMP54]], i64 [[TMP57]], i32 1, i32 0, 
i64 0, ptr null)
+// CHECK6-NEXT:  call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6-NEXT:  ret void
 
 #endif


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to