[clang][OpenMP] Add 'allocator' modifier for 'allocate' clause. (#114883)
The 'allocator' modifier is now accepted in the 'allocate' clause. Added LIT tests covering codegen, PCH, template handling, and serialization for 'allocator' modifier. Added support for allocator-modifier to release notes. Testing - New allocate modifier LIT tests. - OpenMP LIT tests. - check-all - relevant sollve_vv test cases tests/5.2/scope/test_scope_allocate_construct.c
This commit is contained in:
parent
d047488d4c
commit
435e58468a
@ -888,6 +888,7 @@ OpenMP Support
|
||||
--------------
|
||||
- Added support for 'omp assume' directive.
|
||||
- Added support for 'omp scope' directive.
|
||||
- Added support for allocator-modifier in 'allocate' clause.
|
||||
|
||||
Improvements
|
||||
^^^^^^^^^^^^
|
||||
|
||||
@ -486,7 +486,8 @@ public:
|
||||
/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp parallel' has clause 'private'
|
||||
/// and clause 'allocate' for the variable 'a'.
|
||||
/// and clause 'allocate' for the variable 'a', which specifies an explicit
|
||||
/// memory allocator.
|
||||
class OMPAllocateClause final
|
||||
: public OMPVarListClause<OMPAllocateClause>,
|
||||
private llvm::TrailingObjects<OMPAllocateClause, Expr *> {
|
||||
@ -499,6 +500,10 @@ class OMPAllocateClause final
|
||||
Expr *Allocator = nullptr;
|
||||
/// Position of the ':' delimiter in the clause;
|
||||
SourceLocation ColonLoc;
|
||||
/// Modifier of 'allocate' clause.
|
||||
OpenMPAllocateClauseModifier AllocatorModifier = OMPC_ALLOCATE_unknown;
|
||||
/// Location of allocator modifier if any.
|
||||
SourceLocation AllocatorModifierLoc;
|
||||
|
||||
/// Build clause with number of variables \a N.
|
||||
///
|
||||
@ -510,10 +515,14 @@ class OMPAllocateClause final
|
||||
/// \param N Number of the variables in the clause.
|
||||
OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
Expr *Allocator, SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc, unsigned N)
|
||||
OpenMPAllocateClauseModifier AllocatorModifier,
|
||||
SourceLocation AllocatorModifierLoc, SourceLocation EndLoc,
|
||||
unsigned N)
|
||||
: OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc,
|
||||
LParenLoc, EndLoc, N),
|
||||
Allocator(Allocator), ColonLoc(ColonLoc) {}
|
||||
Allocator(Allocator), ColonLoc(ColonLoc),
|
||||
AllocatorModifier(AllocatorModifier),
|
||||
AllocatorModifierLoc(AllocatorModifierLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
///
|
||||
@ -527,6 +536,9 @@ class OMPAllocateClause final
|
||||
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
|
||||
|
||||
void setAllocator(Expr *A) { Allocator = A; }
|
||||
void setAllocatorModifier(OpenMPAllocateClauseModifier AM) {
|
||||
AllocatorModifier = AM;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Creates clause with a list of variables \a VL.
|
||||
@ -536,18 +548,31 @@ public:
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param Allocator Allocator expression.
|
||||
/// \param ColonLoc Location of ':' delimiter.
|
||||
/// \param AllocatorModifier Allocator modifier.
|
||||
/// \param SourceLocation Allocator modifier location.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
/// \param VL List of references to the variables.
|
||||
static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, Expr *Allocator,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> VL);
|
||||
static OMPAllocateClause *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
Expr *Allocator, SourceLocation ColonLoc,
|
||||
OpenMPAllocateClauseModifier AllocatorModifier,
|
||||
SourceLocation AllocatorModifierLoc, SourceLocation EndLoc,
|
||||
ArrayRef<Expr *> VL);
|
||||
|
||||
/// Returns the allocator expression or nullptr, if no allocator is specified.
|
||||
Expr *getAllocator() const { return Allocator; }
|
||||
|
||||
/// Return 'allocate' modifier.
|
||||
OpenMPAllocateClauseModifier getAllocatorModifier() const {
|
||||
return AllocatorModifier;
|
||||
}
|
||||
|
||||
/// Returns the location of the ':' delimiter.
|
||||
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||
/// Return the location of the modifier.
|
||||
SourceLocation getAllocatorModifierLoc() const {
|
||||
return AllocatorModifierLoc;
|
||||
}
|
||||
|
||||
/// Creates an empty clause with the place for \a N variables.
|
||||
///
|
||||
|
||||
@ -86,6 +86,9 @@
|
||||
#ifndef OPENMP_DOACROSS_MODIFIER
|
||||
#define OPENMP_DOACROSS_MODIFIER(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_ALLOCATE_MODIFIER
|
||||
#define OPENMP_ALLOCATE_MODIFIER(Name)
|
||||
#endif
|
||||
|
||||
// Static attributes for 'schedule' clause.
|
||||
OPENMP_SCHEDULE_KIND(static)
|
||||
@ -214,6 +217,9 @@ OPENMP_GRAINSIZE_MODIFIER(strict)
|
||||
// Modifiers for the 'num_tasks' clause.
|
||||
OPENMP_NUMTASKS_MODIFIER(strict)
|
||||
|
||||
// Modifiers for 'allocate' clause.
|
||||
OPENMP_ALLOCATE_MODIFIER(allocator)
|
||||
|
||||
// Modifiers for the 'doacross' clause.
|
||||
OPENMP_DOACROSS_MODIFIER(source)
|
||||
OPENMP_DOACROSS_MODIFIER(sink)
|
||||
@ -245,4 +251,5 @@ OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
|
||||
#undef OPENMP_DEFAULTMAP_KIND
|
||||
#undef OPENMP_DEFAULTMAP_MODIFIER
|
||||
#undef OPENMP_DOACROSS_MODIFIER
|
||||
#undef OPENMP_ALLOCATE_MODIFIER
|
||||
|
||||
|
||||
@ -223,6 +223,13 @@ enum OpenMPDoacrossClauseModifier {
|
||||
OMPC_DOACROSS_unknown
|
||||
};
|
||||
|
||||
/// OpenMP modifiers for 'allocate' clause.
|
||||
enum OpenMPAllocateClauseModifier {
|
||||
#define OPENMP_ALLOCATE_MODIFIER(Name) OMPC_ALLOCATE_##Name,
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
OMPC_ALLOCATE_unknown
|
||||
};
|
||||
|
||||
/// Contains 'interop' data for 'append_args' and 'init' clauses.
|
||||
class Expr;
|
||||
struct OMPInteropInfo final {
|
||||
|
||||
@ -1148,6 +1148,7 @@ public:
|
||||
SourceLocation OmpAllMemoryLoc;
|
||||
SourceLocation
|
||||
StepModifierLoc; /// 'step' modifier location for linear clause
|
||||
OpenMPAllocateClauseModifier AllocClauseModifier = OMPC_ALLOCATE_unknown;
|
||||
};
|
||||
|
||||
OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
|
||||
@ -1165,10 +1166,10 @@ public:
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'allocate' clause.
|
||||
OMPClause *
|
||||
ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc, SourceLocation ColonLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc);
|
||||
OMPClause *ActOnOpenMPAllocateClause(
|
||||
Expr *Allocator, OpenMPAllocateClauseModifier ACModifier,
|
||||
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
|
||||
SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
|
||||
/// Called on well-formed 'private' clause.
|
||||
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
|
||||
@ -1023,12 +1023,17 @@ OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
|
||||
OMPAllocateClause *
|
||||
OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, Expr *Allocator,
|
||||
SourceLocation ColonLoc, SourceLocation EndLoc,
|
||||
ArrayRef<Expr *> VL) {
|
||||
SourceLocation ColonLoc,
|
||||
OpenMPAllocateClauseModifier AllocatorModifier,
|
||||
SourceLocation AllocatorModifierLoc,
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> VL) {
|
||||
|
||||
// Allocate space for private variables and initializer expressions.
|
||||
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
|
||||
auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
|
||||
ColonLoc, EndLoc, VL.size());
|
||||
auto *Clause = new (Mem) OMPAllocateClause(
|
||||
StartLoc, LParenLoc, Allocator, ColonLoc, AllocatorModifier,
|
||||
AllocatorModifierLoc, EndLoc, VL.size());
|
||||
|
||||
Clause->setVarRefs(VL);
|
||||
return Clause;
|
||||
}
|
||||
@ -2242,9 +2247,17 @@ void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
|
||||
if (Node->varlist_empty())
|
||||
return;
|
||||
OS << "allocate";
|
||||
OpenMPAllocateClauseModifier Modifier = Node->getAllocatorModifier();
|
||||
if (Expr *Allocator = Node->getAllocator()) {
|
||||
OS << "(";
|
||||
Allocator->printPretty(OS, nullptr, Policy, 0);
|
||||
if (Modifier == OMPC_ALLOCATE_allocator) {
|
||||
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier);
|
||||
OS << "(";
|
||||
Allocator->printPretty(OS, nullptr, Policy, 0);
|
||||
OS << ")";
|
||||
} else {
|
||||
Allocator->printPretty(OS, nullptr, Policy, 0);
|
||||
}
|
||||
OS << ":";
|
||||
VisitOMPClauseList(Node, ' ');
|
||||
} else {
|
||||
|
||||
@ -180,6 +180,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
|
||||
return OMPC_NUMTASKS_unknown;
|
||||
return Type;
|
||||
}
|
||||
case OMPC_allocate:
|
||||
return llvm::StringSwitch<OpenMPAllocateClauseModifier>(Str)
|
||||
#define OPENMP_ALLOCATE_MODIFIER(Name) .Case(#Name, OMPC_ALLOCATE_##Name)
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
.Default(OMPC_ALLOCATE_unknown);
|
||||
case OMPC_unknown:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_if:
|
||||
@ -190,7 +195,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
|
||||
case OMPC_sizes:
|
||||
case OMPC_permutation:
|
||||
case OMPC_allocator:
|
||||
case OMPC_allocate:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_firstprivate:
|
||||
@ -505,6 +509,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
|
||||
case OMPC_allocate:
|
||||
switch (Type) {
|
||||
case OMPC_ALLOCATE_unknown:
|
||||
return "unknown";
|
||||
#define OPENMP_ALLOCATE_MODIFIER(Name) \
|
||||
case OMPC_ALLOCATE_##Name: \
|
||||
return #Name;
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
|
||||
case OMPC_unknown:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_if:
|
||||
@ -515,7 +529,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
||||
case OMPC_sizes:
|
||||
case OMPC_permutation:
|
||||
case OMPC_allocator:
|
||||
case OMPC_allocate:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_firstprivate:
|
||||
|
||||
@ -4800,7 +4800,23 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
||||
// iterator(iterators-definition)
|
||||
ExprResult Tail;
|
||||
if (Kind == OMPC_allocate) {
|
||||
Tail = ParseAssignmentExpression();
|
||||
auto Modifier = static_cast<OpenMPAllocateClauseModifier>(
|
||||
getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
|
||||
if (Modifier == OMPC_ALLOCATE_allocator) {
|
||||
Data.AllocClauseModifier = Modifier;
|
||||
ConsumeToken();
|
||||
BalancedDelimiterTracker AllocateT(*this, tok::l_paren,
|
||||
tok::annot_pragma_openmp_end);
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
AllocateT.consumeOpen();
|
||||
Tail = ParseAssignmentExpression();
|
||||
AllocateT.consumeClose();
|
||||
} else {
|
||||
Diag(Tok, diag::err_expected) << tok::l_paren;
|
||||
}
|
||||
} else {
|
||||
Tail = ParseAssignmentExpression();
|
||||
}
|
||||
} else {
|
||||
HasIterator = true;
|
||||
EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
|
||||
@ -4817,6 +4833,12 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
||||
} else {
|
||||
// Colon not found, parse only list of variables.
|
||||
TPA.Revert();
|
||||
if (Kind == OMPC_allocate &&
|
||||
Data.AllocClauseModifier == OMPC_ALLOCATE_allocator) {
|
||||
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
Diag(Tok, diag::err_modifier_expected_colon) << "allocator";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Parsing was unsuccessfull, revert and skip to the end of clause or
|
||||
@ -4886,7 +4908,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
||||
// Parse ')' for linear clause with modifier.
|
||||
if (NeedRParenForLinear)
|
||||
LinearT.consumeClose();
|
||||
|
||||
// Parse ':' linear modifiers (val, uval, ref or step(step-size))
|
||||
// or parse ':' alignment.
|
||||
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
|
||||
@ -5018,6 +5039,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
||||
/// 'has_device_addr' '(' list ')'
|
||||
/// allocate-clause:
|
||||
/// 'allocate' '(' [ allocator ':' ] list ')'
|
||||
/// As of OpenMP 5.1 there's also
|
||||
/// 'allocate' '(' allocate-modifier: list ')'
|
||||
/// where allocate-modifier is: 'allocator' '(' allocator ')'
|
||||
/// nontemporal-clause:
|
||||
/// 'nontemporal' '(' list ')'
|
||||
/// inclusive-clause:
|
||||
|
||||
@ -17156,7 +17156,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
|
||||
Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
|
||||
break;
|
||||
case OMPC_allocate:
|
||||
Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
|
||||
Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr,
|
||||
Data.AllocClauseModifier, VarList, StartLoc,
|
||||
LParenLoc, ColonLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_nontemporal:
|
||||
@ -23162,9 +23163,17 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
|
||||
}
|
||||
|
||||
OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(
|
||||
Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
|
||||
Expr *Allocator, OpenMPAllocateClauseModifier AllocClauseModifier,
|
||||
ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc, SourceLocation EndLoc) {
|
||||
|
||||
if (Allocator) {
|
||||
// Allocator expression is dependent - skip it for now and build the
|
||||
// allocator when instantiated.
|
||||
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
|
||||
Allocator->isInstantiationDependent() ||
|
||||
Allocator->containsUnexpandedParameterPack())
|
||||
return nullptr;
|
||||
// OpenMP [2.11.4 allocate Clause, Description]
|
||||
// allocator is an expression of omp_allocator_handle_t type.
|
||||
if (!findOMPAllocatorHandleT(SemaRef, Allocator->getExprLoc(), DSAStack))
|
||||
@ -23220,8 +23229,12 @@ OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(
|
||||
|
||||
if (Allocator)
|
||||
DSAStack->addInnerAllocatorExpr(Allocator);
|
||||
|
||||
OpenMPAllocateClauseModifier AllocatorModifier = AllocClauseModifier;
|
||||
SourceLocation AllocatorModifierLoc;
|
||||
return OMPAllocateClause::Create(getASTContext(), StartLoc, LParenLoc,
|
||||
Allocator, ColonLoc, EndLoc, Vars);
|
||||
Allocator, ColonLoc, AllocatorModifier,
|
||||
AllocatorModifierLoc, EndLoc, Vars);
|
||||
}
|
||||
|
||||
OMPClause *SemaOpenMP::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
|
||||
|
||||
@ -2075,13 +2075,15 @@ public:
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new OpenMP clause.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
|
||||
OMPClause *RebuildOMPAllocateClause(Expr *Allocate,
|
||||
OpenMPAllocateClauseModifier ACModifier,
|
||||
ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().OpenMP().ActOnOpenMPAllocateClause(
|
||||
Allocate, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
|
||||
Allocate, ACModifier, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// Build a new OpenMP 'num_teams' clause.
|
||||
@ -11128,8 +11130,8 @@ TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
|
||||
Vars.push_back(EVar.get());
|
||||
}
|
||||
return getDerived().RebuildOMPAllocateClause(
|
||||
Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
|
||||
C->getEndLoc());
|
||||
Allocator, C->getAllocatorModifier(), Vars, C->getBeginLoc(),
|
||||
C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
|
||||
@ -11598,6 +11598,7 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) {
|
||||
C->setAllocatorModifier(Record.readEnum<OpenMPAllocateClauseModifier>());
|
||||
C->setLParenLoc(Record.readSourceLocation());
|
||||
C->setColonLoc(Record.readSourceLocation());
|
||||
C->setAllocator(Record.readSubExpr());
|
||||
|
||||
@ -7619,6 +7619,7 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
|
||||
|
||||
void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Record.writeEnum(C->getAllocatorModifier());
|
||||
Record.AddSourceLocation(C->getLParenLoc());
|
||||
Record.AddSourceLocation(C->getColonLoc());
|
||||
Record.AddStmt(C->getAllocator());
|
||||
|
||||
86
clang/test/OpenMP/allocate_allocator_modifier_ast_print.cpp
Normal file
86
clang/test/OpenMP/allocate_allocator_modifier_ast_print.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++14 \
|
||||
// RUN: -ast-print %s | FileCheck %s --check-prefix=PRINT
|
||||
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++14 \
|
||||
// RUN: -ast-dump %s | FileCheck %s --check-prefix=DUMP
|
||||
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++14 -emit-pch -o %t %s
|
||||
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++14 -include-pch \
|
||||
// RUN: %t -ast-print %s | FileCheck %s --check-prefix=PRINT
|
||||
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++14 -include-pch \
|
||||
// RUN: %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
typedef enum omp_allocator_handle_t {
|
||||
omp_null_allocator = 0,
|
||||
omp_default_mem_alloc = 1,
|
||||
omp_large_cap_mem_alloc = 2,
|
||||
omp_const_mem_alloc = 3,
|
||||
omp_high_bw_mem_alloc = 4,
|
||||
omp_low_lat_mem_alloc = 5,
|
||||
omp_cgroup_mem_alloc = 6,
|
||||
omp_pteam_mem_alloc = 7,
|
||||
omp_thread_mem_alloc = 8,
|
||||
} omp_allocator_handle_t;
|
||||
|
||||
omp_allocator_handle_t myAlloc() {
|
||||
return omp_large_cap_mem_alloc;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int a, b, c, d;
|
||||
#pragma omp scope private(a) allocate(omp_const_mem_alloc:a)
|
||||
a++;
|
||||
#pragma omp scope private(a,b) allocate(allocator(omp_const_mem_alloc):a,b)
|
||||
b++;
|
||||
#pragma omp scope private(c,a,b) allocate(allocator(myAlloc()):a,b,c)
|
||||
c++;
|
||||
#pragma omp scope private(c,a,b,d) allocate(myAlloc():a,b,c,d)
|
||||
// DUMP: FunctionDecl {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'omp_allocator_handle_t' EnumConstant {{.*}}'omp_large_cap_mem_alloc' 'omp_allocator_handle_t'
|
||||
// DUMP: FunctionDecl {{.*}}
|
||||
// DUMP: OMPScopeDirective {{.*}}
|
||||
// DUMP: OMPPrivateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: OMPAllocateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: OMPScopeDirective {{.*}}
|
||||
// DUMP: OMPPrivateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int'
|
||||
// DUMP: OMPAllocateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int'
|
||||
// DUMP: OMPScopeDirective {{.*}}
|
||||
// DUMP: OMPPrivateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int'
|
||||
// DUMP: OMPAllocateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int'
|
||||
// DUMP: OMPScopeDirective {{.*}}
|
||||
// DUMP: OMPPrivateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'d' 'int'
|
||||
// DUMP: OMPAllocateClause {{.*}}
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'a' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'b' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'c' 'int'
|
||||
// DUMP: DeclRefExpr {{.*}}'int' lvalue Var {{.*}}'d' 'int'
|
||||
// PRINT: #pragma omp scope private(a) allocate(omp_const_mem_alloc: a)
|
||||
// PRINT: #pragma omp scope private(a,b) allocate(allocator(omp_const_mem_alloc): a,b)
|
||||
// PRINT: #pragma omp scope private(c,a,b) allocate(allocator(myAlloc()): a,b,c)
|
||||
// PRINT: #pragma omp scope private(c,a,b,d) allocate(myAlloc(): a,b,c,d)
|
||||
d++;
|
||||
return a+b+c+d;
|
||||
}
|
||||
#endif
|
||||
255
clang/test/OpenMP/allocate_allocator_modifier_codegen.cpp
Normal file
255
clang/test/OpenMP/allocate_allocator_modifier_codegen.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 5
|
||||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix CHECK-TLS %s
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
enum omp_allocator_handle_t {
|
||||
omp_null_allocator = 0,
|
||||
omp_default_mem_alloc = 1,
|
||||
omp_large_cap_mem_alloc = 2,
|
||||
omp_const_mem_alloc = 3,
|
||||
omp_high_bw_mem_alloc = 4,
|
||||
omp_low_lat_mem_alloc = 5,
|
||||
omp_cgroup_mem_alloc = 6,
|
||||
omp_pteam_mem_alloc = 7,
|
||||
omp_thread_mem_alloc = 8,
|
||||
KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct ST {
|
||||
static T m;
|
||||
};
|
||||
|
||||
template <class T, omp_allocator_handle_t TY> T foo() {
|
||||
T v;
|
||||
#pragma omp scope private(v) allocate(allocator(TY):v)
|
||||
v = ST<T>::m;
|
||||
return v;
|
||||
}
|
||||
|
||||
namespace ns {
|
||||
int a;
|
||||
}
|
||||
|
||||
int main() {
|
||||
static int a;
|
||||
static int temp;
|
||||
#pragma omp scope private(ns::a) allocate(allocator(omp_pteam_mem_alloc):ns::a)
|
||||
ns::a++;
|
||||
|
||||
#pragma omp scope private(a) allocate(allocator(omp_thread_mem_alloc):a)
|
||||
a = 2;
|
||||
double b = 3;
|
||||
#pragma omp scope private(temp) allocate(temp)
|
||||
temp += foo<int, omp_cgroup_mem_alloc>();
|
||||
return temp+ns::a;
|
||||
}
|
||||
|
||||
extern template int ST<int>::m;
|
||||
|
||||
int b;
|
||||
|
||||
void bar(int a, float &z) {
|
||||
#pragma omp scope private(a,z) allocate(allocator(omp_default_mem_alloc):a,z)
|
||||
a += b;
|
||||
}
|
||||
#endif
|
||||
// CHECK-LABEL: define dso_local noundef i32 @main(
|
||||
// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: [[B:%.*]] = alloca double, align 8
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])
|
||||
// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
||||
// CHECK-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 7 to ptr))
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1
|
||||
// CHECK-NEXT: store i32 [[INC]], ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 7 to ptr))
|
||||
// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP0]])
|
||||
// CHECK-NEXT: [[DOTA__VOID_ADDR1:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 8 to ptr))
|
||||
// CHECK-NEXT: store i32 2, ptr [[DOTA__VOID_ADDR1]], align 4
|
||||
// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR1]], ptr inttoptr (i64 8 to ptr))
|
||||
// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-NEXT: store double 3.000000e+00, ptr [[B]], align 8
|
||||
// CHECK-NEXT: [[DOTTEMP__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr null)
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v()
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTTEMP__VOID_ADDR]], align 4
|
||||
// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[CALL]]
|
||||
// CHECK-NEXT: store i32 [[ADD]], ptr [[DOTTEMP__VOID_ADDR]], align 4
|
||||
// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTTEMP__VOID_ADDR]], ptr null)
|
||||
// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN2ns1aE, align 4
|
||||
// CHECK-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP3]], [[TMP4]]
|
||||
// CHECK-NEXT: ret i32 [[ADD2]]
|
||||
//
|
||||
//
|
||||
// CHECK-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v(
|
||||
// CHECK-SAME: ) #[[ATTR3:[0-9]+]] comdat {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[V:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: [[V1:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4
|
||||
// CHECK-NEXT: store i32 [[TMP1]], ptr [[V1]], align 4
|
||||
// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[V]], align 4
|
||||
// CHECK-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
//
|
||||
// CHECK-LABEL: define dso_local void @_Z3bariRf(
|
||||
// CHECK-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR3]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: [[TMP:%.*]] = alloca ptr, align 8
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
||||
// CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
||||
// CHECK-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8
|
||||
// CHECK-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-NEXT: [[DOTZ__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-NEXT: store ptr [[DOTZ__VOID_ADDR]], ptr [[TMP]], align 8
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @b, align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
|
||||
// CHECK-NEXT: store i32 [[ADD]], ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTZ__VOID_ADDR]], ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
//
|
||||
// CHECK-TLS-LABEL: define dso_local noundef i32 @main(
|
||||
// CHECK-TLS-SAME: ) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-TLS-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-TLS-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
||||
// CHECK-TLS-NEXT: [[B:%.*]] = alloca double, align 8
|
||||
// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])
|
||||
// CHECK-TLS-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
||||
// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 7 to ptr))
|
||||
// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1
|
||||
// CHECK-TLS-NEXT: store i32 [[INC]], ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 7 to ptr))
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP0]])
|
||||
// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR1:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 8 to ptr))
|
||||
// CHECK-TLS-NEXT: store i32 2, ptr [[DOTA__VOID_ADDR1]], align 4
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR1]], ptr inttoptr (i64 8 to ptr))
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-TLS-NEXT: store double 3.000000e+00, ptr [[B]], align 8
|
||||
// CHECK-TLS-NEXT: [[DOTTEMP__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr null)
|
||||
// CHECK-TLS-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v()
|
||||
// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTTEMP__VOID_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[CALL]]
|
||||
// CHECK-TLS-NEXT: store i32 [[ADD]], ptr [[DOTTEMP__VOID_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTTEMP__VOID_ADDR]], ptr null)
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-TLS-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4
|
||||
// CHECK-TLS-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN2ns1aE, align 4
|
||||
// CHECK-TLS-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP3]], [[TMP4]]
|
||||
// CHECK-TLS-NEXT: ret i32 [[ADD2]]
|
||||
//
|
||||
//
|
||||
// CHECK-TLS-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v(
|
||||
// CHECK-TLS-SAME: ) #[[ATTR3:[0-9]+]] comdat {
|
||||
// CHECK-TLS-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-TLS-NEXT: [[V:%.*]] = alloca i32, align 4
|
||||
// CHECK-TLS-NEXT: [[V1:%.*]] = alloca i32, align 4
|
||||
// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
||||
// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4
|
||||
// CHECK-TLS-NEXT: store i32 [[TMP1]], ptr [[V1]], align 4
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[V]], align 4
|
||||
// CHECK-TLS-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
//
|
||||
// CHECK-TLS-LABEL: define dso_local void @_Z3bariRf(
|
||||
// CHECK-TLS-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR3]] {
|
||||
// CHECK-TLS-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-TLS-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
||||
// CHECK-TLS-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8
|
||||
// CHECK-TLS-NEXT: [[TMP:%.*]] = alloca ptr, align 8
|
||||
// CHECK-TLS-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
||||
// CHECK-TLS-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8
|
||||
// CHECK-TLS-NEXT: [[DOTA__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-TLS-NEXT: [[DOTZ__VOID_ADDR:%.*]] = call ptr @__kmpc_alloc(i32 [[TMP0]], i64 4, ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-TLS-NEXT: store ptr [[DOTZ__VOID_ADDR]], ptr [[TMP]], align 8
|
||||
// CHECK-TLS-NEXT: [[TMP1:%.*]] = load i32, ptr @b, align 4
|
||||
// CHECK-TLS-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
|
||||
// CHECK-TLS-NEXT: store i32 [[ADD]], ptr [[DOTA__VOID_ADDR]], align 4
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTZ__VOID_ADDR]], ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_free(i32 [[TMP0]], ptr [[DOTA__VOID_ADDR]], ptr inttoptr (i64 1 to ptr))
|
||||
// CHECK-TLS-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP0]])
|
||||
// CHECK-TLS-NEXT: ret void
|
||||
//
|
||||
//
|
||||
// SIMD-ONLY0-LABEL: define dso_local noundef i32 @main(
|
||||
// SIMD-ONLY0-SAME: ) #[[ATTR0:[0-9]+]] {
|
||||
// SIMD-ONLY0-NEXT: [[ENTRY:.*:]]
|
||||
// SIMD-ONLY0-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[A1:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[B:%.*]] = alloca double, align 8
|
||||
// SIMD-ONLY0-NEXT: [[TEMP:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
||||
// SIMD-ONLY0-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1
|
||||
// SIMD-ONLY0-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
||||
// SIMD-ONLY0-NEXT: store i32 2, ptr [[A1]], align 4
|
||||
// SIMD-ONLY0-NEXT: store double 3.000000e+00, ptr [[B]], align 8
|
||||
// SIMD-ONLY0-NEXT: [[CALL:%.*]] = call noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v()
|
||||
// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[TEMP]], align 4
|
||||
// SIMD-ONLY0-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[CALL]]
|
||||
// SIMD-ONLY0-NEXT: store i32 [[ADD]], ptr [[TEMP]], align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZZ4mainE4temp, align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZN2ns1aE, align 4
|
||||
// SIMD-ONLY0-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP2]], [[TMP3]]
|
||||
// SIMD-ONLY0-NEXT: ret i32 [[ADD2]]
|
||||
//
|
||||
//
|
||||
// SIMD-ONLY0-LABEL: define linkonce_odr noundef i32 @_Z3fooIiL22omp_allocator_handle_t6EET_v(
|
||||
// SIMD-ONLY0-SAME: ) #[[ATTR1:[0-9]+]] comdat {
|
||||
// SIMD-ONLY0-NEXT: [[ENTRY:.*:]]
|
||||
// SIMD-ONLY0-NEXT: [[V:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[V1:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN2STIiE1mE, align 4
|
||||
// SIMD-ONLY0-NEXT: store i32 [[TMP0]], ptr [[V1]], align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[V]], align 4
|
||||
// SIMD-ONLY0-NEXT: ret i32 [[TMP1]]
|
||||
//
|
||||
//
|
||||
// SIMD-ONLY0-LABEL: define dso_local void @_Z3bariRf(
|
||||
// SIMD-ONLY0-SAME: i32 noundef [[A:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[Z:%.*]]) #[[ATTR1]] {
|
||||
// SIMD-ONLY0-NEXT: [[ENTRY:.*:]]
|
||||
// SIMD-ONLY0-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[Z_ADDR:%.*]] = alloca ptr, align 8
|
||||
// SIMD-ONLY0-NEXT: [[A1:%.*]] = alloca i32, align 4
|
||||
// SIMD-ONLY0-NEXT: [[Z2:%.*]] = alloca float, align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP:%.*]] = alloca ptr, align 8
|
||||
// SIMD-ONLY0-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
||||
// SIMD-ONLY0-NEXT: store ptr [[Z]], ptr [[Z_ADDR]], align 8
|
||||
// SIMD-ONLY0-NEXT: store ptr [[Z2]], ptr [[TMP]], align 8
|
||||
// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load i32, ptr @b, align 4
|
||||
// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load i32, ptr [[A1]], align 4
|
||||
// SIMD-ONLY0-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP0]]
|
||||
// SIMD-ONLY0-NEXT: store i32 [[ADD]], ptr [[A1]], align 4
|
||||
// SIMD-ONLY0-NEXT: ret void
|
||||
//
|
||||
97
clang/test/OpenMP/allocate_allocator_modifier_messages.cpp
Normal file
97
clang/test/OpenMP/allocate_allocator_modifier_messages.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 %s
|
||||
|
||||
typedef enum omp_allocator_handle_t {
|
||||
omp_null_allocator = 0,
|
||||
omp_default_mem_alloc = 1,
|
||||
omp_large_cap_mem_alloc = 2,
|
||||
omp_const_mem_alloc = 3,
|
||||
omp_high_bw_mem_alloc = 4,
|
||||
omp_low_lat_mem_alloc = 5,
|
||||
omp_cgroup_mem_alloc = 6,
|
||||
omp_pteam_mem_alloc = 7,
|
||||
omp_thread_mem_alloc = 8,
|
||||
} omp_allocator_handle_t;
|
||||
|
||||
int myAlloc() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int a, b, c;
|
||||
// expected-error@+4 {{expected '('}}
|
||||
// expected-error@+3 {{expected expression}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator
|
||||
// expected-error@+6 {{expected expression}}
|
||||
// expected-error@+5 {{expected ')'}}
|
||||
// expected-note@+4 {{to match this '('}}
|
||||
// expected-error@+3 {{expected expression}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator(
|
||||
// expected-error@+4 {{expected expression}}
|
||||
// expected-error@+3 {{expected expression}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator()
|
||||
// expected-error@+2 {{expected expression}}
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp scope private(c) allocate(allocator())
|
||||
// expected-error@+6 {{expected ')'}}
|
||||
// expected-note@+5 {{to match this '('}}
|
||||
// expected-error@+4 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+3 {{expected expression}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_default_mem_alloc
|
||||
// expected-error@+6 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+5 {{expected expression}}
|
||||
// expected-error@+4 {{expected ')'}}
|
||||
// expected-note@+3 {{to match this '('}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_large_cap_mem_alloc:
|
||||
// expected-error@+4 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+3 {{expected expression}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc)
|
||||
// expected-error@+2 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_high_bw_mem_alloc))
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_low_lat_mem_alloc):)
|
||||
// expected-error@+6 {{expected ')'}}
|
||||
// expected-note@+5 {{to match this '('}}
|
||||
// expected-error@+4 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+3 {{expected expression}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_cgroup_mem_alloc:)
|
||||
// expected-error@+4 {{expected ')'}}
|
||||
// expected-note@+3 {{to match this '('}}
|
||||
// expected-error@+2 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_pteam_mem_alloc:))
|
||||
// expected-error@+4 {{expected ')'}}
|
||||
// expected-note@+3 {{to match this '('}}
|
||||
// expected-error@+2 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_thread_mem_alloc:c))
|
||||
// expected-error@+1 {{expected variable name}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc):1)
|
||||
// expected-error@+1 {{expected variable name}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_const_mem_alloc):-10)
|
||||
// expected-error@+4 {{expected ',' or ')' in 'allocate' clause}}
|
||||
// expected-error@+3 {{expected ')'}}
|
||||
// expected-warning@+2 {{extra tokens at the end of '#pragma omp scope' are ignored}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp scope private(a,b,c) allocate(allocator(omp_const_mem_alloc):c:b;a)
|
||||
// expected-error@+1 {{initializing 'const omp_allocator_handle_t' with an expression of incompatible type 'int'}}
|
||||
#pragma omp scope private(c,a,b) allocate(allocator(myAlloc()):a,b,c)
|
||||
// expected-error@+2 {{missing ':' after allocator modifier}}
|
||||
// expected-error@+1 {{expected expression}}
|
||||
#pragma omp scope private(c) allocate(allocator(omp_default_mem_alloc);c)
|
||||
++a;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user