[clang] [llvm] [OpenMP]Initial parsing/sema support for target_device selector set (PR #118471)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 3 03:27:14 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (Ritanya-B-Bharadwaj)
<details>
<summary>Changes</summary>
This patch adds initial support for target_device selector set - Section 9.2 (Spec 6.0)
---
Patch is 81.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118471.diff
15 Files Affected:
- (modified) clang/include/clang/Sema/SemaOpenMP.h (+3)
- (modified) clang/lib/AST/OpenMPClause.cpp (+4-1)
- (modified) clang/lib/Parse/ParseOpenMP.cpp (+20-7)
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+29)
- (modified) clang/test/OpenMP/begin_declare_variant_messages.c (+11-11)
- (modified) clang/test/OpenMP/declare_variant_ast_print.c (+4)
- (modified) clang/test/OpenMP/declare_variant_bind_to_decl.cpp (+1-1)
- (modified) clang/test/OpenMP/declare_variant_messages.c (+34-23)
- (modified) clang/test/OpenMP/declare_variant_messages.cpp (+14-14)
- (modified) clang/test/OpenMP/metadirective_messages.cpp (+1-1)
- (modified) clang/test/OpenMP/nvptx_declare_variant_name_mangling.cpp (+4-4)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMPContext.h (+7-2)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMPKinds.def (+36)
- (modified) llvm/lib/Frontend/OpenMP/OMPContext.cpp (+137-55)
- (modified) llvm/unittests/Frontend/OpenMPContextTest.cpp (+15-11)
``````````diff
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..4b9c930db26b5d 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -849,6 +849,9 @@ class SemaOpenMP : public SemaBase {
ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
SourceLocation AppendArgsLoc, SourceRange SR);
+ /// Handle device_num selector.
+ void ActOnOpenMPDeviceNum(Expr *DeviceNumExpr);
+
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 4246ba95d827f1..bb3aa9fc959c3a 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -2903,7 +2903,10 @@ TargetOMPContext::TargetOMPContext(
const FunctionDecl *CurrentFunctionDecl,
ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
: OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
- ASTCtx.getTargetInfo().getTriple()),
+ ASTCtx.getTargetInfo().getTriple(),
+ ASTCtx.getLangOpts().OMPTargetTriples.empty()
+ ? llvm::Triple()
+ : ASTCtx.getLangOpts().OMPTargetTriples[0]),
FeatureValidityCheck([&](StringRef FeatureName) {
return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
}),
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index b91928063169ee..84f1fcdb6e83f2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -888,7 +888,18 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
TIProperty.Kind = TraitProperty::invalid;
SourceLocation NameLoc = Tok.getLocation();
- StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
+ StringRef Name;
+ if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
+ Name = "number";
+ TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
+ ExprResult DeviceNumExprResult = ParseExpression();
+ if (!DeviceNumExprResult.isInvalid()) {
+ Expr *DeviceNumExpr = DeviceNumExprResult.get();
+ Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
+ }
+ return;
+ }
+ Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
if (Name.empty()) {
Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
<< CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
@@ -918,7 +929,8 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
<< "(<property-name>)";
return;
}
- TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
+ TraitSelector SelectorForName =
+ getOpenMPContextTraitSelectorKind(Name, SetForName);
if (SelectorForName != TraitSelector::invalid) {
Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
@@ -935,7 +947,7 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
}
for (const auto &PotentialSet :
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
- TraitSet::device}) {
+ TraitSet::device, TraitSet::target_device}) {
TraitProperty PropertyForName =
getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
if (PropertyForName == TraitProperty::invalid)
@@ -1062,7 +1074,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
return;
}
- TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
+ TISelector.Kind = getOpenMPContextTraitSelectorKind(Name, Set);
if (TISelector.Kind != TraitSelector::invalid) {
if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
TISelector.Kind = TraitSelector::invalid;
@@ -1084,7 +1096,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
}
for (const auto &PotentialSet :
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
- TraitSet::device}) {
+ TraitSet::device, TraitSet::target_device}) {
TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
PotentialSet, TraitSelector::invalid, Name);
if (PropertyForName == TraitProperty::invalid)
@@ -1259,7 +1271,8 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
// It follows diagnosis and helping notes.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
- TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
+ TraitSelector SelectorForName =
+ getOpenMPContextTraitSelectorKind(Name, TISet.Kind);
if (SelectorForName != TraitSelector::invalid) {
Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
@@ -1276,7 +1289,7 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
}
for (const auto &PotentialSet :
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
- TraitSet::device}) {
+ TraitSet::device, TraitSet::target_device}) {
TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
PotentialSet, TraitSelector::invalid, Name);
if (PropertyForName == TraitProperty::invalid)
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 976d48e1249136..48f6fa53fc8f29 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -15629,6 +15629,35 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause(
return ICE;
}
+void SemaOpenMP::ActOnOpenMPDeviceNum(Expr *DeviceNumExpr) {
+ llvm::APSInt Result;
+ Expr::EvalResult EvalResult;
+ // Strip implicit casts from the expression
+ DeviceNumExpr = DeviceNumExpr->IgnoreImpCasts();
+
+ // Evaluate the expression to an integer value
+ if (DeviceNumExpr->EvaluateAsInt(EvalResult, SemaRef.Context)) {
+ // The device expression must evaluate to a non-negative integer value.
+ Result = EvalResult.Val.getInt();
+ if (Result.isNonNegative()) {
+ OMPContext::DeviceNum = Result.getSExtValue();
+ } else {
+ Diag(DeviceNumExpr->getExprLoc(),
+ diag::err_omp_negative_expression_in_clause)
+ << "device_num" << 0 << DeviceNumExpr->getSourceRange();
+ }
+ } else if (auto *DeclRef = dyn_cast<DeclRefExpr>(DeviceNumExpr)) {
+ // Check if the expression is an identifier
+ IdentifierInfo *IdInfo = DeclRef->getDecl()->getIdentifier();
+ if (IdInfo) {
+ StringRef Identifier = IdInfo->getName();
+ OMPContext::DeviceNumID = Identifier;
+ }
+ } else {
+ Diag(DeviceNumExpr->getExprLoc(), diag::err_expected_expression);
+ }
+}
+
OMPClause *SemaOpenMP::ActOnOpenMPSafelenClause(Expr *Len,
SourceLocation StartLoc,
SourceLocation LParenLoc,
diff --git a/clang/test/OpenMP/begin_declare_variant_messages.c b/clang/test/OpenMP/begin_declare_variant_messages.c
index ffa56002f19535..f87714a47dce03 100644
--- a/clang/test/OpenMP/begin_declare_variant_messages.c
+++ b/clang/test/OpenMP/begin_declare_variant_messages.c
@@ -32,27 +32,27 @@ const int var;
#pragma omp end declare variant
#pragma omp begin declare variant match // expected-error {{expected '(' after 'match'}}
#pragma omp end declare variant
-#pragma omp begin declare variant match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
+#pragma omp begin declare variant match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
#pragma omp end declare variant
-#pragma omp begin declare variant match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
+#pragma omp begin declare variant match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
+#pragma omp begin declare variant match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
-#pragma omp begin declare variant match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
+#pragma omp begin declare variant match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
#pragma omp end declare variant
#pragma omp begin declare variant match(implementation={xxx}) // expected-warning {{'xxx' is not a valid context selector for the context set 'implementation'; selector ignored}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}}
#pragma omp end declare variant
diff --git a/clang/test/OpenMP/declare_variant_ast_print.c b/clang/test/OpenMP/declare_variant_ast_print.c
index 0df10263cde5ee..9bd0b6d0d61629 100644
--- a/clang/test/OpenMP/declare_variant_ast_print.c
+++ b/clang/test/OpenMP/declare_variant_ast_print.c
@@ -20,6 +20,8 @@ int foo(void);
#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx, ibm)}, device={kind(cpu, nohost)})
#pragma omp declare variant(foo) match(device={kind(host)})
#pragma omp declare variant(foo) match(device={kind(nohost), xxx})
+#pragma omp declare variant(foo) match(target_device={kind(host)})
+#pragma omp declare variant(foo) match(target_device={kind(nohost), xxx})
#pragma omp declare variant(foo) match(implementation={extension(match_all)})
#pragma omp declare variant(foo) match(implementation={extension(match_any)})
#pragma omp declare variant(foo) match(implementation={extension(match_none)})
@@ -29,6 +31,8 @@ int bar(void);
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_none)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_any)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_all)})
+// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(nohost)})
+// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(host)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(nohost)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(host)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}, device={kind(cpu, nohost)})
diff --git a/clang/test/OpenMP/declare_variant_bind_to_decl.cpp b/clang/test/OpenMP/declare_variant_bind_to_decl.cpp
index dca18abb36c896..34191417a39345 100644
--- a/clang/test/OpenMP/declare_variant_bind_to_decl.cpp
+++ b/clang/test/OpenMP/declare_variant_bind_to_decl.cpp
@@ -29,6 +29,6 @@ int main() {
// CHECK-LABEL: define {{[^@]+}}@main
// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @"_Z74foo$ompvariant$S2$s7$Pppc64le$Pppc64$S3$s9$Pmatch_any$Pbind_to_declarationv"()
+// CHECK-NEXT: call void @{{"_Z[0-9]+foo\$ompvariant\$.*"}}()
// CHECK-NEXT: ret i32 0
//
diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c
index 0ae276effd1beb..14637d8200671e 100644
--- a/clang/test/OpenMP/declare_variant_messages.c
+++ b/clang/test/OpenMP/declare_variant_messages.c
@@ -16,17 +16,17 @@ int foo(void);
#pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
#pragma omp declare variant(foo) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}}
#pragma omp declare variant(foo) match // expected-error {{expected '(' after 'match'}}
-#pragma omp declare variant(foo) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
-#pragma omp declare variant(foo) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
-#pragma omp declare variant(foo) match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
-#pragma omp declare variant(foo) match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
-#pragma omp declare variant(foo) match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
-#pragma omp declare variant(foo) match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/118471
More information about the cfe-commits
mailing list