aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-10-08 19:44:16 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-10-08 19:44:16 +0000
commit303657a6c6f440f1855f6680c8bb1c8a7b815535 (patch)
tree96160f0aad0f872949c70622344b899530166d86
parent07c5f2a9b0add36974250cd9ab9152458e8b3361 (diff)
downloadllvm-303657a6c6f440f1855f6680c8bb1c8a7b815535.zip
llvm-303657a6c6f440f1855f6680c8bb1c8a7b815535.tar.gz
llvm-303657a6c6f440f1855f6680c8bb1c8a7b815535.tar.bz2
[OPENMP50]Multiple vendors in vendor context must be treated as logical
and of vendors, not or. If several vendors are provided in the same vendor context trait, the context shall match only if all vendors are matching, not one of them. This is per OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors, all selectors in the construct, device, and implementation sets of the context selector appear in the corresponding trait set of the OpenMP context. llvm-svn: 374107
-rw-r--r--clang/include/clang/Basic/Attr.td8
-rw-r--r--clang/include/clang/Sema/Sema.h10
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp3
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp18
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp4
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp8
-rw-r--r--clang/test/OpenMP/declare_variant_ast_print.c3
-rw-r--r--clang/test/OpenMP/declare_variant_ast_print.cpp6
-rw-r--r--clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp7
9 files changed, 42 insertions, 25 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 283d0f32..279a432 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3309,7 +3309,7 @@ def OMPDeclareVariant : InheritableAttr {
[
"CtxUnknown", "CtxVendor"
]>,
- StringArgument<"ImplVendor", 1>
+ VariadicStringArgument<"ImplVendors">
];
let AdditionalMembers = [{
void printScore(raw_ostream & OS, const PrintingPolicy &Policy) const {
@@ -3337,7 +3337,11 @@ def OMPDeclareVariant : InheritableAttr {
case CtxVendor:
OS << "vendor(";
printScore(OS, Policy);
- OS << getImplVendor();
+ if (implVendors_size() > 0) {
+ OS << *implVendors(). begin();
+ for (StringRef VendorName : llvm::drop_begin(implVendors(), 1))
+ OS << ", " << VendorName;
+ }
OS << ")";
break;
case CtxUnknown:
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index bb05a08..d5d91e3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9110,15 +9110,15 @@ public:
OMPDeclareVariantAttr::CtxSetUnknown;
OMPDeclareVariantAttr::CtxSelectorType Ctx =
OMPDeclareVariantAttr::CtxUnknown;
- StringRef ImplVendor;
+ MutableArrayRef<StringRef> ImplVendors;
ExprResult CtxScore;
explicit OpenMPDeclareVariantCtsSelectorData() = default;
explicit OpenMPDeclareVariantCtsSelectorData(
OMPDeclareVariantAttr::CtxSelectorSetType CtxSet,
- OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor,
- ExprResult CtxScore)
- : CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor), CtxScore(CtxScore) {
- }
+ OMPDeclareVariantAttr::CtxSelectorType Ctx,
+ MutableArrayRef<StringRef> ImplVendors, ExprResult CtxScore)
+ : CtxSet(CtxSet), Ctx(Ctx), ImplVendors(ImplVendors),
+ CtxScore(CtxScore) {}
};
/// Checks if the variant/multiversion functions are compatible.
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index e9cf692..d2f18a5 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11172,7 +11172,8 @@ template <>
bool checkContext<OMPDeclareVariantAttr::CtxSetImplementation,
OMPDeclareVariantAttr::CtxVendor>(
const OMPDeclareVariantAttr *A) {
- return !A->getImplVendor().compare("llvm");
+ return llvm::all_of(A->implVendors(),
+ [](StringRef S) { return !S.compare_lower("llvm"); });
}
static bool greaterCtxScore(ASTContext &Ctx, const Expr *LHS, const Expr *RHS) {
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index f667b83..82a4e70 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -853,6 +853,7 @@ static void parseImplementationSelector(
(void)T.expectAndConsume(diag::err_expected_lparen_after,
CtxSelectorName.data());
const ExprResult Score = parseContextScore(P);
+ SmallVector<llvm::SmallString<16>, 4> Vendors;
do {
// Parse <vendor>.
StringRef VendorName;
@@ -860,18 +861,14 @@ static void parseImplementationSelector(
Buffer.clear();
VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
(void)P.ConsumeToken();
+ if (!VendorName.empty())
+ Vendors.push_back(VendorName);
} else {
P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected)
<< "vendor identifier"
<< "vendor"
<< "implementation";
}
- if (!VendorName.empty()) {
- Sema::OpenMPDeclareVariantCtsSelectorData Data(
- OMPDeclareVariantAttr::CtxSetImplementation, CSKind, VendorName,
- Score);
- Callback(SourceRange(Loc, Tok.getLocation()), Data);
- }
if (!P.TryConsumeToken(tok::comma) && Tok.isNot(tok::r_paren)) {
P.Diag(Tok, diag::err_expected_punc)
<< (VendorName.empty() ? "vendor name" : VendorName);
@@ -879,6 +876,15 @@ static void parseImplementationSelector(
} while (Tok.is(tok::identifier));
// Parse ')'.
(void)T.consumeClose();
+ if (!Vendors.empty()) {
+ SmallVector<StringRef, 4> ImplVendors(Vendors.size());
+ for (int I = 0, E = Vendors.size(); I < E; ++I)
+ ImplVendors[I] = Vendors[I];
+ Sema::OpenMPDeclareVariantCtsSelectorData Data(
+ OMPDeclareVariantAttr::CtxSetImplementation, CSKind, ImplVendors,
+ Score);
+ Callback(SourceRange(Loc, Tok.getLocation()), Data);
+ }
break;
}
case OMPDeclareVariantAttr::CtxUnknown:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ff7e1c0..5ceee81 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5136,8 +5136,8 @@ void Sema::ActOnOpenMPDeclareVariantDirective(
}
}
auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
- Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, Data.ImplVendor,
- SR);
+ Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx,
+ Data.ImplVendors.begin(), Data.ImplVendors.size(), SR);
FD->addAttr(NewAttr);
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 881b4fd..818548c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -399,9 +399,11 @@ static void instantiateOMPDeclareVariantAttr(
if (!DeclVarData)
return;
// Instantiate the attribute.
- Sema::OpenMPDeclareVariantCtsSelectorData Data(Attr.getCtxSelectorSet(),
- Attr.getCtxSelector(),
- Attr.getImplVendor(), Score);
+ Sema::OpenMPDeclareVariantCtsSelectorData Data(
+ Attr.getCtxSelectorSet(), Attr.getCtxSelector(),
+ llvm::makeMutableArrayRef(Attr.implVendors_begin(),
+ Attr.implVendors_size()),
+ Score);
S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
DeclVarData.getValue().second,
Attr.getRange(), Data);
diff --git a/clang/test/OpenMP/declare_variant_ast_print.c b/clang/test/OpenMP/declare_variant_ast_print.c
index 7f359e0..a8a11bc 100644
--- a/clang/test/OpenMP/declare_variant_ast_print.c
+++ b/clang/test/OpenMP/declare_variant_ast_print.c
@@ -15,8 +15,7 @@ int foo(void);
int bar(void);
// CHECK: int foo();
-// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):ibm)})
-// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):xxx)})
+// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):ibm, xxx)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
diff --git a/clang/test/OpenMP/declare_variant_ast_print.cpp b/clang/test/OpenMP/declare_variant_ast_print.cpp
index 7b3b9cc..ce67b81 100644
--- a/clang/test/OpenMP/declare_variant_ast_print.cpp
+++ b/clang/test/OpenMP/declare_variant_ast_print.cpp
@@ -28,8 +28,7 @@ T foofoo() { return T(); }
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)})
int bar();
-// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):ibm)})
-// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):xxx)})
+// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):ibm, xxx)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)})
// CHECK-NEXT: template <typename T, int C> T barbar();
@@ -45,8 +44,7 @@ int bar();
template <typename T, int C>
T barbar();
-// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5):ibm)})
-// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5):xxx)})
+// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5):ibm, xxx)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
// CHECK-NEXT: template<> int barbar<int, 3>();
diff --git a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
index 1c200cc..cf72e4c 100644
--- a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
+++ b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
@@ -13,6 +13,8 @@
// CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv
// CHECK-DAG: @_ZL9stat_usedv = internal alias i32 (), i32 ()* @_ZL10stat_used_v
// CHECK-DAG: @_ZN12SpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev
+// CHECK-DAG: @fn_linkage = {{.*}}alias i32 (), i32 ()* @_Z18fn_linkage_variantv
+// CHECK-DAG: @_Z11fn_linkage1v = {{.*}}alias i32 (), i32 ()* @fn_linkage_variant1
// CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv()
// CHECK-DAG: declare {{.*}}i32 @_Z3bazv()
// CHECK-DAG: ret i32 2
@@ -24,6 +26,7 @@
// CHECK-DAG: ret i32 83
// CHECK-DAG: ret i32 85
// CHECK-DAG: ret i32 86
+// CHECK-DAG: ret i32 87
// CHECK-NOT: ret i32 {{1|4|81|84}}
#ifndef HEADER
@@ -122,4 +125,8 @@ extern "C" int fn_linkage_variant1() { return 86; }
#pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(llvm)})
int fn_linkage1() { return 1; }
+int fn_variant2() { return 1; }
+#pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm, ibm)})
+int fn2() { return 87; }
+
#endif // HEADER