[clang] [llvm] [CLANG][OpenMP] Add support for OpenMP6.0 transparent clause (PR #166810)
Zahira Ammarguellat via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 7 11:25:10 PST 2025
https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/166810
>From ec999cb001304680af55b79591c8b998dbcfd925 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 6 Nov 2025 09:17:08 -0800
Subject: [PATCH 1/7] [CLANG][OpenMP] Add support for OpenMP6.0 transparent
clause
---
clang/docs/OpenMPSupport.rst | 2 +-
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/AST/OpenMPClause.h | 86 ++++++++++++++++
clang/include/clang/AST/RecursiveASTVisitor.h | 6 ++
clang/include/clang/Basic/OpenMPKinds.def | 9 ++
clang/include/clang/Basic/OpenMPKinds.h | 7 ++
clang/include/clang/Sema/SemaOpenMP.h | 6 ++
clang/lib/AST/OpenMPClause.cpp | 8 ++
clang/lib/AST/StmtProfile.cpp | 2 +
clang/lib/Basic/OpenMPKinds.cpp | 19 ++++
clang/lib/CodeGen/CGOpenMPRuntime.cpp | 4 +
clang/lib/Parse/ParseOpenMP.cpp | 1 +
clang/lib/Sema/SemaOpenMP.cpp | 22 +++++
clang/lib/Sema/TreeTransform.h | 7 ++
clang/lib/Serialization/ASTReader.cpp | 12 +++
clang/lib/Serialization/ASTWriter.cpp | 6 ++
clang/test/OpenMP/task_ast_print.cpp | 11 +++
clang/test/OpenMP/task_codegen.cpp | 45 +++++++++
.../test/OpenMP/task_transparent_messages.cpp | 98 +++++++++++++++++++
clang/test/OpenMP/taskloop_ast_print.cpp | 22 +++++
clang/test/OpenMP/taskloop_codegen.cpp | 87 ++++++++++++++++
clang/tools/libclang/CIndex.cpp | 2 +
llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 10 +-
llvm/include/llvm/Frontend/OpenMP/OMP.td | 1 +
24 files changed, 472 insertions(+), 2 deletions(-)
create mode 100644 clang/test/OpenMP/task_transparent_messages.cpp
diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index 10a8d095fede3..18b5b60ac6cdf 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -490,7 +490,7 @@ implementation.
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| memscope clause for atomic and flush | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| transparent clause (hull tasks) | :none:`unclaimed` | :none:`unclaimed` | |
+| transparent clause (hull tasks) | :part:`partial` | :none:`unclaimed` | To Add the PR# |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| rule-based compound directives | :part:`In Progress` | :part:`In Progress` | kparzysz |
| | | | Testing for Fortran missing |
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 32f669f8d70d8..1a55b73e1013a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -687,6 +687,7 @@ OpenMP Support
- Allow array length to be omitted in array section subscript expression.
- Fixed non-contiguous strided update in the ``omp target update`` directive with the ``from`` clause.
- Added support for threadset clause in task and taskloop directives.
+- Added support for ``transparent`` clause in task and taskloop directives.
- Properly handle array section/assumed-size array privatization in C/C++.
- Added support to handle new syntax of the ``uses_allocators`` clause.
- Added support for ``variable-category`` modifier in ``default clause``.
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 4f507485968cd..a56b69fa39754 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1504,6 +1504,92 @@ class OMPThreadsetClause final : public OMPClause {
}
};
+/// This class represents the 'transparent' clause in the '#pragma omp task'
+/// directive.
+///
+/// \code
+/// #pragma omp task transparent(omp_not_impex)
+/// \endcode
+///
+/// In this example, the directive '#pragma omp task' has a 'transparent'
+/// 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 {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'transparent' clause.
+ OpenMPTransparentKind Kind = OMPC_TRANSPARENT_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindLoc;
+
+ /// Set kind of the clauses.
+ ///
+ /// \param K Argument of clause.
+ void setTransparentKind(OpenMPTransparentKind K) { Kind = K; }
+
+ /// Set argument location.
+ ///
+ /// \param KLoc Argument location.
+ void setTransparentKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+
+public:
+ /// Build 'transparent' clause with argument \a A ('omp_not_impex',
+ /// 'omp_import', 'omp_export' or 'omp_impex')
+ ///
+ /// \param A Argument of the clause ('omp_not_impex', 'omp_import',
+ /// 'omp_export' or 'omp_impex')
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPTransparentClause(OpenMPTransparentKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_transparent, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPTransparentClause()
+ : OMPClause(llvm::omp::OMPC_transparent, SourceLocation(),
+ SourceLocation()) {}
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPTransparentKind getTransparentKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getTransparentKindLoc() const { return KindLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_transparent;
+ }
+};
+
/// This represents 'proc_bind' clause in the '#pragma omp ...'
/// directive.
///
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 8cb0a657023b4..5650d7411c4d1 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3529,6 +3529,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPThreadsetClause(
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPTransparentClause(
+ OMPTransparentClause *) {
+ return true;
+}
+
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
return true;
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 328a0747a82a8..8bac23dd1a06b 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -101,6 +101,9 @@
#ifndef OPENMP_THREADSET_KIND
#define OPENMP_THREADSET_KIND(Name)
#endif
+#ifndef OPENMP_TRANSPARENT_KIND
+#define OPENMP_TRANSPARENT_KIND(Name)
+#endif
// Static attributes for 'schedule' clause.
OPENMP_SCHEDULE_KIND(static)
@@ -261,6 +264,11 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
OPENMP_THREADSET_KIND(omp_pool)
OPENMP_THREADSET_KIND(omp_team)
+OPENMP_TRANSPARENT_KIND(omp_not_impex)
+OPENMP_TRANSPARENT_KIND(omp_import)
+OPENMP_TRANSPARENT_KIND(omp_export)
+OPENMP_TRANSPARENT_KIND(omp_impex)
+
#undef OPENMP_NUMTASKS_MODIFIER
#undef OPENMP_NUMTHREADS_MODIFIER
#undef OPENMP_GRAINSIZE_MODIFIER
@@ -291,3 +299,4 @@ OPENMP_THREADSET_KIND(omp_team)
#undef OPENMP_DOACROSS_MODIFIER
#undef OPENMP_ALLOCATE_MODIFIER
#undef OPENMP_THREADSET_KIND
+#undef OPENMP_TRANSPARENT_KIND
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index c9ddbcd6d46c1..9bb841396a3b3 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -257,6 +257,13 @@ enum OpenMPThreadsetKind {
OMPC_THREADSET_unknown
};
+/// OpenMP modifiers for 'transparent' clause.
+enum OpenMPTransparentKind {
+#define OPENMP_TRANSPARENT_KIND(Name) OMPC_TRANSPARENT_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_TRANSPARENT_unknown
+};
+
/// Number of allowed allocate-modifiers.
static constexpr unsigned NumberOfOMPAllocateClauseModifiers =
OMPC_ALLOCATE_unknown;
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index ba12b403d9b9a..7bdb2fd94bbd6 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -981,6 +981,12 @@ class SemaOpenMP : public SemaBase {
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'transparent' clause.
+ OMPClause *ActOnOpenMPTransparentClause(OpenMPTransparentKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'proc_bind' clause.
OMPClause *ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind,
SourceLocation KindLoc,
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 59d94590e04d1..ba7e3f82f71e4 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -125,6 +125,7 @@ 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:
@@ -2043,6 +2044,13 @@ void OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {
<< ")";
}
+void OMPClausePrinter::VisitOMPTransparentClause(OMPTransparentClause *Node) {
+ OS << "transparent("
+ << getOpenMPSimpleClauseTypeName(OMPC_transparent,
+ unsigned(Node->getTransparentKind()))
+ << ")";
+}
+
void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
OS << "proc_bind("
<< getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index c909e1bcecd38..e05d3bec98d5c 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -548,6 +548,8 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
void OMPClauseProfiler::VisitOMPThreadsetClause(const OMPThreadsetClause *C) {}
+void OMPClauseProfiler::VisitOMPTransparentClause(const OMPTransparentClause *C) {}
+
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 3d41f2d197b81..ee0d5194d0116 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -219,6 +219,15 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
return OMPC_THREADSET_unknown;
return Type;
}
+ case OMPC_transparent: {
+ unsigned Type = llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_TRANSPARENT_KIND(Name) .Case(#Name, OMPC_TRANSPARENT_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_TRANSPARENT_unknown);
+ if (LangOpts.OpenMP < 60)
+ return OMPC_TRANSPARENT_unknown;
+ return Type;
+ }
case OMPC_num_threads: {
unsigned Type = llvm::StringSwitch<unsigned>(Str)
#define OPENMP_NUMTHREADS_MODIFIER(Name) .Case(#Name, OMPC_NUMTHREADS_##Name)
@@ -584,6 +593,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'threadset' clause modifier");
+ case OMPC_transparent:
+ switch (Type) {
+ case OMPC_TRANSPARENT_unknown:
+ return "unknown";
+#define OPENMP_TRANSPARENT_KIND(Name) \
+ case OMPC_TRANSPARENT_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'transparent' clause modifier");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_groupprivate:
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 121de42248e3b..9e74c1420d228 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -3732,6 +3732,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
PriorityFlag = 0x20,
DetachableFlag = 0x40,
FreeAgentFlag = 0x80,
+ TransparentFlag = 0x100,
};
unsigned Flags = Data.Tied ? TiedFlag : 0;
bool NeedsCleanup = false;
@@ -3746,6 +3747,9 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
if (Kind == OMPC_THREADSET_omp_pool)
Flags = Flags | FreeAgentFlag;
}
+ if (const auto *Clause = D.getSingleClause<OMPTransparentClause>()) {
+ Flags |= TransparentFlag;
+ }
if (Data.Priority.getInt())
Flags = Flags | PriorityFlag;
if (D.hasClausesOfKind<OMPDetachClause>())
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 31bc941e6a015..60e463ba3f8a2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3222,6 +3222,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
break;
case OMPC_threadset:
+ case OMPC_transparent:
case OMPC_fail:
case OMPC_proc_bind:
case OMPC_atomic_default_mem_order:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 256f9521b3a7e..fca76bfb232a0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17220,6 +17220,11 @@ OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
Res = ActOnOpenMPThreadsetClause(static_cast<OpenMPThreadsetKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_transparent:
+ Res = ActOnOpenMPTransparentClause(
+ static_cast<OpenMPTransparentKind>(Argument), ArgumentLoc, StartLoc,
+ LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -17376,6 +17381,23 @@ OMPClause *SemaOpenMP::ActOnOpenMPThreadsetClause(OpenMPThreadsetKind Kind,
OMPThreadsetClause(Kind, KindLoc, StartLoc, LParenLoc, EndLoc);
}
+OMPClause *SemaOpenMP::ActOnOpenMPTransparentClause(OpenMPTransparentKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_TRANSPARENT_unknown) {
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_transparent, /*First=*/0,
+ /*Last=*/unsigned(OMPC_TRANSPARENT_unknown))
+ << getOpenMPClauseName(OMPC_transparent);
+ return nullptr;
+ }
+
+ return new (getASTContext())
+ OMPTransparentClause(Kind, KindLoc, StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *SemaOpenMP::ActOnOpenMPProcBindClause(ProcBindKind Kind,
SourceLocation KindKwLoc,
SourceLocation StartLoc,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dffd7c1def8e2..352079e13071b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10625,6 +10625,13 @@ TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
return C;
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
+ // No need to rebuild this clause, no template-dependent parameters.
+ return C;
+}
+
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index d5528219bb7d5..9a415aab71be6 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11258,6 +11258,9 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_threadset:
C = new (Context) OMPThreadsetClause();
break;
+ case llvm::omp::OMPC_transparent:
+ C = new (Context) OMPTransparentClause();
+ break;
case llvm::omp::OMPC_read:
C = new (Context) OMPReadClause();
break;
@@ -11672,6 +11675,15 @@ void OMPClauseReader::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
C->setThreadsetKind(TKind);
}
+void OMPClauseReader::VisitOMPTransparentClause(OMPTransparentClause *C) {
+ C->setLParenLoc(Record.readSourceLocation());
+ SourceLocation TransparentKindLoc = Record.readSourceLocation();
+ C->setTransparentKindLoc(TransparentKindLoc);
+ OpenMPTransparentKind TKind =
+ static_cast<OpenMPTransparentKind>(Record.readInt());
+ C->setTransparentKind(TKind);
+}
+
void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
C->setProcBindKind(static_cast<llvm::omp::ProcBindKind>(Record.readInt()));
C->setLParenLoc(Record.readSourceLocation());
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index b1fd151790d96..34ee0599c33c5 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7918,6 +7918,12 @@ void OMPClauseWriter::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
Record.writeEnum(C->getThreadsetKind());
}
+void OMPClauseWriter::VisitOMPTransparentClause(OMPTransparentClause *C) {
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getTransparentKindLoc());
+ Record.writeEnum(C->getTransparentKind());
+}
+
void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
Record.push_back(unsigned(C->getProcBindKind()));
Record.AddSourceLocation(C->getLParenLoc());
diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp
index b059f187156ee..d3108236b40df 100644
--- a/clang/test/OpenMP/task_ast_print.cpp
+++ b/clang/test/OpenMP/task_ast_print.cpp
@@ -205,10 +205,21 @@ int main(int argc, char **argv) {
#pragma omp task threadset(omp_pool)
#pragma omp task threadset(omp_team)
foo();
+
+#pragma omp task transparent(omp_not_impex)
+#pragma omp task transparent(omp_import)
+#pragma omp task transparent(omp_export)
+#pragma omp task transparent(omp_impex)
+ foo();
#endif
// CHECK60: #pragma omp task threadset(omp_pool)
// CHECK60: #pragma omp task threadset(omp_team)
// CHECK60-NEXT: foo();
+ // CHECK60: #pragma omp task transparent(omp_not_impex)
+ // CHECK60: #pragma omp task transparent(omp_import)
+ // CHECK60: #pragma omp task transparent(omp_export)
+ // CHECK60: #pragma omp task transparent(omp_impex)
+ // CHECK60-NEXT: foo();
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
}
diff --git a/clang/test/OpenMP/task_codegen.cpp b/clang/test/OpenMP/task_codegen.cpp
index ba8e6945de9d0..6c3bad672e4ba 100644
--- a/clang/test/OpenMP/task_codegen.cpp
+++ b/clang/test/OpenMP/task_codegen.cpp
@@ -231,6 +231,22 @@ void test_threadset()
{
}
}
+
+void test_transparent()
+{
+#pragma omp task transparent(omp_not_impex)
+ {
+ }
+#pragma omp task transparent(omp_import)
+ {
+ }
+#pragma omp task transparent(omp_export)
+ {
+ }
+#pragma omp task transparent(omp_impex)
+ {
+ }
+}
#endif // OMP60
#endif
@@ -10276,3 +10292,32 @@ void test_threadset()
// CHECK6-NEXT: call i32 @__kmpc_global_thread_num(ptr @[[GLOB_PTR2:[0-9]+]])
// CHECK6-NEXT: call i32 @__kmpc_omp_task(ptr @1, i32 %omp_global_thread_num4, ptr %3)
// CHECK6-NEXT: ret void
+
+// CHECK6-LABEL: define void @_Z16test_transparentv() #1 {
+// CHECK6-NEXT: entry:
+// CHECK6-NEXT: [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON_27:%.*]], align 1
+// CHECK6-NEXT: [[AGG_CAPTURED2:%.*]] = alloca [[STRUCT_ANON_29:%.*]], align 1
+// CHECK6-NEXT: [[AGG_CAPTURED5:%.*]] = alloca [[STRUCT_ANON_31:%.*]], align 1
+// CHECK6-NEXT: [[AGG_CAPTURED8:%.*]] = alloca [[STRUCT_ANON_33:%.*]], align 1
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @31)
+// CHECK6-NEXT: [[TMP0:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM]], i32 257, i64 40, i64 1, ptr @.omp_task_entry..[[ENTRY1:[0-9]+]])
+// CHECK6-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP0]], i32 0, i32 0
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @31)
+// CHECK6-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM1]], ptr [[TMP0]])
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @33)
+// CHECK6-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM3]], i32 257, i64 40, i64 1, ptr @.omp_task_entry..[[ENTRY2:[0-9]+]])
+// CHECK6-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP3]], i32 0, i32 0
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 @__kmpc_global_thread_num(ptr @33)
+// CHECK6-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM4]], ptr [[TMP3]])
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 @__kmpc_global_thread_num(ptr @35)
+// CHECK6-NEXT: [[TMP6:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM6]], i32 257, i64 40, i64 1, ptr @.omp_task_entry..[[ENTRY3:[0-9]+]])
+// CHECK6-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP6]], i32 0, i32 0
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @35)
+// CHECK6-NEXT: [[TMP8:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM7]], ptr [[TMP6]])
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM9:%.*]] = call i32 @__kmpc_global_thread_num(ptr @37)
+// CHECK6-NEXT: [[TMP9:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM9]], i32 257, i64 40, i64 1, ptr @.omp_task_entry..[[ENTRY4:[0-9]+]])
+// CHECK6-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP9]], i32 0, i32 0
+// CHECK6-NEXT: [[OMP_GLOBAL_THREAD_NUM10:%.*]] = call i32 @__kmpc_global_thread_num(ptr @37)
+// CHECK6-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_omp_task(ptr @1, i32 [[OMP_GLOBAL_THREAD_NUM10]], ptr [[TMP9]])
+// CHECK6-NEXT: ret void
+// CHECK6-NEXT:}
diff --git a/clang/test/OpenMP/task_transparent_messages.cpp b/clang/test/OpenMP/task_transparent_messages.cpp
new file mode 100644
index 0000000000000..465b8008701f5
--- /dev/null
+++ b/clang/test/OpenMP/task_transparent_messages.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected -DOMP60 -fopenmp -fopenmp-version=60 -std=c++11 -ferror-limit 200 -o - %s
+
+// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp-simd -fopenmp-version=51 -std=c++11 -ferror-limit 200 -o - %s
+// RUN: %clang_cc1 -verify=expected -DOMP60 -fopenmp-simd -fopenmp-version=60 -std=c++11 -ferror-limit 200 -o - %s
+
+#ifdef OMP60
+struct ComplexStruct {
+ int data[10];
+ struct InnerStruct {
+ float value;
+ } inner;
+};
+
+template <typename T>
+class TransparentTemplate {
+public:
+ void TestTaskImport() {
+ #pragma omp task transparent(omp_import)
+ {
+ T temp;
+ }
+ }
+ void TestTaskLoopImpex() {
+ #pragma omp taskloop transparent(omp_impex)
+ for (int i = 0; i < 10; ++i) {}
+ }
+};
+
+void TestTaskTransparent() {
+ int a;
+#pragma omp task transparent(omp_not_impex)
+#pragma omp task transparent(omp_import)
+#pragma omp task transparent(omp_export)
+#pragma omp task transparent(omp_impex)
+
+#pragma omp task transparent(omp_import) if(1)
+#pragma omp task transparent(omp_impex) priority(5)
+#pragma omp task transparent(omp_not_impex) depend(out: a)
+#pragma omp parallel
+ {
+#pragma omp task transparent(omp_export)
+ {
+#pragma omp taskloop transparent(omp_not_impex)
+ for (int i = 0; i < 5; ++i) {}
+ }
+ }
+
+ TransparentTemplate<int> obj;
+ obj.TestTaskImport();
+ obj.TestTaskLoopImpex();
+}
+
+void TestTaskTransparentInvalidArgs() {
+ #pragma omp task transparent(invalid_arg) // expected-error {{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+ #pragma omp task transparent(123) // expected-error {{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+#pragma omp task transparent(omp_import, omp_not_import) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp task transparent() // expected-error {{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+ {}
+}
+
+void TestTaskloopTransparent() {
+ #pragma omp taskloop transparent(omp_import)
+ for (int i = 0; i < 10; ++i) {}
+ #pragma omp taskloop transparent(omp_export)
+ for (int i = 0; i < 10; ++i) {}
+ #pragma omp taskloop transparent(omp_not_impex) grainsize(5)
+ for (int i = 0; i < 10; ++i) {}
+ #pragma omp taskloop transparent(omp_impex) num_tasks(2)
+ for (int i = 0; i < 10; ++i) {}
+}
+
+
+void TestTaskLoopTransparentInvalidArgs() {
+ #pragma omp taskloop transparent(invalid_arg) // expected-error {{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+ for (int i = 0; i < 10; ++i) {}
+ #pragma omp taskloop transparent(123) // expected-error {{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+ for (int i = 0; i < 10; ++i) {}
+#pragma omp taskloop transparent(omp_not_import, omp_import) // expected-error{{expected ')'}} // expected-note{{to match this '('}} // expected-error{{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+ for (int i = 0; i < 10; ++i) {}
+ #pragma omp taskloop transparent() // expected-error {{expected 'omp_not_impex', 'omp_import', 'omp_export' or 'omp_impex' in OpenMP clause 'transparent'}}
+ for (int i = 0; i < 10; ++i) {}
+}
+
+#else
+void TransparentClauseNotSupported() {
+ #pragma omp task transparent(omp_pool) // omp45-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}} omp50-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}} omp51-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}}
+ #pragma omp task transparent(omp_team) // omp45-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}} omp50-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}} omp51-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp task'}}
+ #pragma omp taskloop transparent(omp_team) // omp45-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} omp50-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} omp51-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}}
+ for (int i = 0; i < 10; ++i) {}
+ #pragma omp taskloop transparent(omp_pool) // omp45-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} omp50-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}} omp51-error {{unexpected OpenMP clause 'transparent' in directive '#pragma omp taskloop'}}
+ for (int i = 0; i < 10; ++i) {}
+}
+#endif
diff --git a/clang/test/OpenMP/taskloop_ast_print.cpp b/clang/test/OpenMP/taskloop_ast_print.cpp
index e4bf20af5d78e..dedbcf4c66bec 100644
--- a/clang/test/OpenMP/taskloop_ast_print.cpp
+++ b/clang/test/OpenMP/taskloop_ast_print.cpp
@@ -97,12 +97,34 @@ int main(int argc, char **argv) {
foo();
}
}
+
+#pragma omp taskloop transparent(omp_not_impex)
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task transparent(omp_import)
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task transparent(omp_export)
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task transparent(omp_impex)
+ foo();
+ }
+ }
+ }
#endif
// CHECK60: #pragma omp taskloop threadset(omp_team)
// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
// CHECK60: #pragma omp taskloop threadset(omp_pool)
// CHECK60-NEXT: for (int j = 0; j < 10; ++j) {
// CHECK60-NEXT: foo();
+
+// CHECK60: #pragma omp taskloop transparent(omp_not_impex)
+// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK60-NEXT: #pragma omp task transparent(omp_import)
+// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK60-NEXT: #pragma omp task transparent(omp_export)
+// CHECK60-NEXT: for (int i = 0; i < 10; ++i) {
+// CHECK60-NEXT: #pragma omp task transparent(omp_impex)
+// CHECK60-NEXT: foo();
+
return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
}
diff --git a/clang/test/OpenMP/taskloop_codegen.cpp b/clang/test/OpenMP/taskloop_codegen.cpp
index d1197607a2684..2a1af769fb8b2 100644
--- a/clang/test/OpenMP/taskloop_codegen.cpp
+++ b/clang/test/OpenMP/taskloop_codegen.cpp
@@ -256,6 +256,23 @@ void test_threadset()
for (int i = 0; i < 10; ++i) {
}
}
+
+void test_transparent()
+{
+#pragma omp taskloop transparent(omp_not_impex)
+ for (int i = 0; i < 10; ++i) {
+ }
+#pragma omp taskloop transparent(omp_import)
+ for (int i = 0; i < 10; ++i) {
+ }
+#pragma omp taskloop transparent(omp_export)
+ for (int i = 0; i < 10; ++i) {
+ }
+#pragma omp taskloop transparent(omp_impex)
+ for (int i = 0; i < 10; ++i) {
+ }
+}
+
#endif // OMP60
// CHECK6-LABEL: define void @_Z14test_threadsetv()
// CHECK6-NEXT: entry:
@@ -294,4 +311,74 @@ void test_threadset()
// 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: [[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 257, 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 5
+// CHECK6: store i64 0, ptr [[TMP3]], align 8
+// CHECK6: [[TMP4:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 6
+// CHECK6: store i64 9, ptr [[TMP4]], align 8
+// CHECK6: [[TMP5:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 7
+// CHECK6: store i64 1, ptr [[TMP5]], align 8
+// CHECK6: [[TMP6:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP2]], i32 0, i32 9
+// CHECK6: call void @llvm.memset.p0.i64(ptr align 8 [[TMP6]], i8 0, i64 8, i1 false)
+// CHECK6: [[TMP7:%.*]] = load i64, ptr [[TMP5]], align 8
+// CHECK6: call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP1]], i32 1, ptr [[TMP3]], ptr [[TMP4]], i64 [[TMP7]], 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: [[TMP8:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..[[ENTRY2:[0-9]+]])
+// CHECK6: [[TMP9:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP8]], i32 0, i32 0
+// CHECK6: [[TMP10:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 5
+// CHECK6: store i64 0, ptr [[TMP10]], align 8
+// CHECK6: [[TMP11:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 6
+// CHECK6: store i64 9, ptr [[TMP11]], align 8
+// CHECK6: [[TMP12:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 7
+// CHECK6: store i64 1, ptr [[TMP12]], align 8
+// CHECK6: [[TMP13:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP9]], i32 0, i32 9
+// CHECK6: call void @llvm.memset.p0.i64(ptr align 8 [[TMP13]], i8 0, i64 8, i1 false)
+// CHECK6: [[TMP14:%.*]] = load i64, ptr [[TMP12]], align 8
+// CHECK6: call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP8]], i32 1, ptr [[TMP10]], ptr [[TMP11]], i64 [[TMP14]], 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: [[TMP15:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..22)
+// CHECK6: [[TMP16:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP15]], i32 0, i32 0
+// CHECK6: [[TMP17:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 5
+// CHECK6: store i64 0, ptr [[TMP17]], align 8
+// CHECK6: [[TMP18:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 6
+// CHECK6: store i64 9, ptr [[TMP18]], align 8
+// CHECK6: [[TMP19:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 7
+// CHECK6: store i64 1, ptr [[TMP19]], align 8
+// CHECK6: [[TMP20:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP16]], i32 0, i32 9
+// CHECK6: call void @llvm.memset.p0.i64(ptr align 8 [[TMP20]], i8 0, i64 8, i1 false)
+// CHECK6: [[TMP21:%.*]] = load i64, ptr [[TMP19]], align 8
+// CHECK6: call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP15]], i32 1, ptr [[TMP17]], ptr [[TMP18]], i64 [[TMP21]], 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: [[TMP22:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[TMP0]], i32 257, i64 80, i64 1, ptr @.omp_task_entry..24)
+// CHECK6: [[TMP23:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t_with_privates{{.*}}, ptr [[TMP22]], i32 0, i32 0
+// CHECK6: [[TMP24:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 5
+// CHECK6: store i64 0, ptr [[TMP24]], align 8
+// CHECK6: [[TMP25:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 6
+// CHECK6: store i64 9, ptr [[TMP25]], align 8
+// CHECK6: [[TMP26:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 7
+// CHECK6: store i64 1, ptr [[TMP26]], align 8
+// CHECK6: [[TMP27:%.*]] = getelementptr inbounds nuw %struct.kmp_task_t{{.*}}, ptr [[TMP23]], i32 0, i32 9
+// CHECK6: call void @llvm.memset.p0.i64(ptr align 8 [[TMP27]], i8 0, i64 8, i1 false)
+// CHECK6: [[TMP28:%.*]] = load i64, ptr [[TMP26]], align 8
+// CHECK6: call void @__kmpc_taskloop(ptr @1, i32 [[TMP0]], ptr [[TMP22]], i32 1, ptr [[TMP24]], ptr [[TMP25]], i64 [[TMP28]], i32 1, i32 0, i64 0, ptr null)
+// CHECK6: call void @__kmpc_end_taskgroup(ptr @1, i32 [[TMP0]])
+// CHECK6: ret void
+// CHECK6:}
+
#endif
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 08776d9bcabfc..6230bab9ff5d8 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2408,6 +2408,8 @@ void OMPClauseEnqueue::VisitOMPFailClause(const OMPFailClause *) {}
void OMPClauseEnqueue::VisitOMPThreadsetClause(const OMPThreadsetClause *) {}
+void OMPClauseEnqueue::VisitOMPTransparentClause(const OMPTransparentClause *) {}
+
void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause *) {}
void OMPClauseEnqueue::VisitOMPHoldsClause(const OMPHoldsClause *) {}
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index d7f0e3a3d49da..ccdc8e1f744c0 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -1175,6 +1175,14 @@ struct ThreadsetT {
ThreadsetPolicy v;
};
+// V6.0: [17.9.6] `transparent` clause
+template <typename T, typename I, typename E> //
+struct TransparentT {
+ ENUM(TransparentPolicy, Omp_not_impex, Omp_import, Omp_export, Omp_impex);
+ using WrapperTrait = std::true_type;
+ TransparentPolicy v;
+};
+
// V5.2: [5.9.1] `to` clause
template <typename T, typename I, typename E> //
struct ToT {
@@ -1360,7 +1368,7 @@ using WrapperClausesT = std::variant<
ProcBindT<T, I, E>, ReverseOffloadT<T, I, E>, SafelenT<T, I, E>,
SelfMapsT<T, I, E>, SeverityT<T, I, E>, SharedT<T, I, E>, SimdlenT<T, I, E>,
SizesT<T, I, E>, PermutationT<T, I, E>, ThreadLimitT<T, I, E>,
- ThreadsetT<T, I, E>, UnifiedAddressT<T, I, E>,
+ ThreadsetT<T, I, E>, TransparentT<T, I, E>, UnifiedAddressT<T, I, E>,
UnifiedSharedMemoryT<T, I, E>, UniformT<T, I, E>, UpdateT<T, I, E>,
UseDeviceAddrT<T, I, E>, UseDevicePtrT<T, I, E>, UsesAllocatorsT<T, I, E>>;
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 208609f64f418..26254bc9f3cfa 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -548,6 +548,7 @@ def OMPC_To : Clause<[Spelling<"to">]> {
let flangClass = "OmpToClause";
}
def OMPC_Transparent : Clause<[Spelling<"transparent">]> {
+ let clangClass = "OMPTransparentClause";
let flangClass = "OmpTransparentClause";
let isValueOptional = true;
}
>From a2413000f3782636ff366df178ee3366d9eabc7b Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 6 Nov 2025 09:25:45 -0800
Subject: [PATCH 2/7] Fix format
---
clang/include/clang/AST/OpenMPClause.h | 4 ++--
clang/lib/AST/StmtProfile.cpp | 3 ++-
clang/lib/Basic/OpenMPKinds.cpp | 4 ++--
clang/tools/libclang/CIndex.cpp | 3 ++-
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index a56b69fa39754..ddfde86e18789 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1548,8 +1548,8 @@ class OMPTransparentClause final : public OMPClause {
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
OMPTransparentClause(OpenMPTransparentKind A, SourceLocation ALoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_transparent, StartLoc, EndLoc),
LParenLoc(LParenLoc), Kind(A), KindLoc(ALoc) {}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index e05d3bec98d5c..cd1657525cceb 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -548,7 +548,8 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
void OMPClauseProfiler::VisitOMPThreadsetClause(const OMPThreadsetClause *C) {}
-void OMPClauseProfiler::VisitOMPTransparentClause(const OMPTransparentClause *C) {}
+void OMPClauseProfiler::VisitOMPTransparentClause(
+ const OMPTransparentClause *C) {}
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index ee0d5194d0116..e19f0c27c8ab3 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -597,8 +597,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
switch (Type) {
case OMPC_TRANSPARENT_unknown:
return "unknown";
-#define OPENMP_TRANSPARENT_KIND(Name) \
- case OMPC_TRANSPARENT_##Name: \
+#define OPENMP_TRANSPARENT_KIND(Name) \
+ case OMPC_TRANSPARENT_##Name: \
return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 6230bab9ff5d8..faebf50488f8c 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2408,7 +2408,8 @@ void OMPClauseEnqueue::VisitOMPFailClause(const OMPFailClause *) {}
void OMPClauseEnqueue::VisitOMPThreadsetClause(const OMPThreadsetClause *) {}
-void OMPClauseEnqueue::VisitOMPTransparentClause(const OMPTransparentClause *) {}
+void OMPClauseEnqueue::VisitOMPTransparentClause(const OMPTransparentClause *) {
+}
void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause *) {}
>From c8fe05b0781b61cdd43ffff3390aea1e4c083fd7 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 6 Nov 2025 09:33:00 -0800
Subject: [PATCH 3/7] Fix format and add PR # to doc
---
clang/docs/OpenMPSupport.rst | 2 +-
clang/lib/Basic/OpenMPKinds.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index 18b5b60ac6cdf..01c834d9ca7b3 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -490,7 +490,7 @@ implementation.
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| memscope clause for atomic and flush | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| transparent clause (hull tasks) | :part:`partial` | :none:`unclaimed` | To Add the PR# |
+| transparent clause (hull tasks) | :part:`partial` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/166810 |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| rule-based compound directives | :part:`In Progress` | :part:`In Progress` | kparzysz |
| | | | Testing for Fortran missing |
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index e19f0c27c8ab3..e7d8f646009da 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -597,8 +597,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
switch (Type) {
case OMPC_TRANSPARENT_unknown:
return "unknown";
-#define OPENMP_TRANSPARENT_KIND(Name) \
- case OMPC_TRANSPARENT_##Name: \
+#define OPENMP_TRANSPARENT_KIND(Name) \
+ case OMPC_TRANSPARENT_##Name: \
return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
>From cc36c518437487cd202ea37d2830b9cfbd1e4246 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 6 Nov 2025 09:40:18 -0800
Subject: [PATCH 4/7] Remove redundant comment
---
clang/lib/Sema/TreeTransform.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 352079e13071b..33df9e934ecb3 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10628,7 +10628,6 @@ TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
- // No need to rebuild this clause, no template-dependent parameters.
return C;
}
>From bdb4b913240639137331f08fee550f48330b1ba5 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 6 Nov 2025 09:52:17 -0800
Subject: [PATCH 5/7] Fix doc
---
clang/docs/OpenMPSupport.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index 01c834d9ca7b3..32aac6fbeb9c4 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -490,7 +490,7 @@ implementation.
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| memscope clause for atomic and flush | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
-| transparent clause (hull tasks) | :part:`partial` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/166810 |
+| transparent clause (hull tasks) | :part:`partial` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/166810 |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| rule-based compound directives | :part:`In Progress` | :part:`In Progress` | kparzysz |
| | | | Testing for Fortran missing |
>From 788f0fd82bcdef624ee1f35f984e80bf15ee1b40 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 6 Nov 2025 12:19:25 -0800
Subject: [PATCH 6/7] Removed redefinition of TransparentT
---
llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index ccdc8e1f744c0..70f820d5196bc 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -1175,14 +1175,6 @@ struct ThreadsetT {
ThreadsetPolicy v;
};
-// V6.0: [17.9.6] `transparent` clause
-template <typename T, typename I, typename E> //
-struct TransparentT {
- ENUM(TransparentPolicy, Omp_not_impex, Omp_import, Omp_export, Omp_impex);
- using WrapperTrait = std::true_type;
- TransparentPolicy v;
-};
-
// V5.2: [5.9.1] `to` clause
template <typename T, typename I, typename E> //
struct ToT {
@@ -1196,10 +1188,12 @@ struct ToT {
std::tuple<OPT(Expectation), OPT(Mappers), OPT(Iterator), LocatorList> t;
};
-// [6.0:440-441] `transparent` clause
+// V6.0: [17.9.6] `transparent` clause
template <typename T, typename I, typename E> //
struct TransparentT {
- using IncompleteTrait = std::true_type;
+ ENUM(TransparentPolicy, Omp_not_impex, Omp_import, Omp_export, Omp_impex);
+ using WrapperTrait = std::true_type;
+ TransparentPolicy v;
};
// V5.2: [8.2.1] `requirement` clauses
>From 513738a1c758f7c311080efaecb10b5ae1c29d42 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 7 Nov 2025 11:24:49 -0800
Subject: [PATCH 7/7] Addressed review comments
---
clang/include/clang/AST/OpenMPClause.h | 6 +++---
clang/include/clang/Basic/OpenMPKinds.def | 2 +-
clang/lib/CodeGen/CGOpenMPRuntime.cpp | 4 ++--
llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index ddfde86e18789..795297990ec97 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1537,6 +1537,9 @@ class OMPTransparentClause final : public OMPClause {
/// \param KLoc Argument location.
void setTransparentKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
public:
/// Build 'transparent' clause with argument \a A ('omp_not_impex',
/// 'omp_import', 'omp_export' or 'omp_impex')
@@ -1558,9 +1561,6 @@ class OMPTransparentClause final : public OMPClause {
: OMPClause(llvm::omp::OMPC_transparent, SourceLocation(),
SourceLocation()) {}
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
/// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 8bac23dd1a06b..2efca6adaf8fa 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -264,7 +264,7 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
OPENMP_THREADSET_KIND(omp_pool)
OPENMP_THREADSET_KIND(omp_team)
-OPENMP_TRANSPARENT_KIND(omp_not_impex)
+OPENMP_TRANSPARENT_KIND(omp_notimpex)
OPENMP_TRANSPARENT_KIND(omp_import)
OPENMP_TRANSPARENT_KIND(omp_export)
OPENMP_TRANSPARENT_KIND(omp_impex)
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 9e74c1420d228..1fdd5e63103f0 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -3747,9 +3747,9 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
if (Kind == OMPC_THREADSET_omp_pool)
Flags = Flags | FreeAgentFlag;
}
- if (const auto *Clause = D.getSingleClause<OMPTransparentClause>()) {
+ if (D.getSingleClause<OMPTransparentClause>())
Flags |= TransparentFlag;
- }
+
if (Data.Priority.getInt())
Flags = Flags | PriorityFlag;
if (D.hasClausesOfKind<OMPDetachClause>())
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 70f820d5196bc..19daa6569632e 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -1191,7 +1191,7 @@ struct ToT {
// V6.0: [17.9.6] `transparent` clause
template <typename T, typename I, typename E> //
struct TransparentT {
- ENUM(TransparentPolicy, Omp_not_impex, Omp_import, Omp_export, Omp_impex);
+ ENUM(TransparentPolicy, Omp_NotImpex, Omp_Import, Omp_Export, Omp_Impex);
using WrapperTrait = std::true_type;
TransparentPolicy v;
};
More information about the llvm-commits
mailing list