Эх сурвалжийг харах

[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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374107 91177308-0d34-0410-b5e6-96231b3b80d8

Alexey Bataev 5 жил өмнө
parent
commit
1d45d5ea2a

+ 6 - 2
include/clang/Basic/Attr.td

@@ -3309,7 +3309,7 @@ def OMPDeclareVariant : InheritableAttr {
                  [
                  [
                    "CtxUnknown", "CtxVendor"
                    "CtxUnknown", "CtxVendor"
                  ]>,
                  ]>,
-    StringArgument<"ImplVendor", 1>
+    VariadicStringArgument<"ImplVendors">
   ];
   ];
   let AdditionalMembers = [{
   let AdditionalMembers = [{
     void printScore(raw_ostream & OS, const PrintingPolicy &Policy) const {
     void printScore(raw_ostream & OS, const PrintingPolicy &Policy) const {
@@ -3337,7 +3337,11 @@ def OMPDeclareVariant : InheritableAttr {
         case CtxVendor:
         case CtxVendor:
           OS << "vendor(";
           OS << "vendor(";
           printScore(OS, Policy);
           printScore(OS, Policy);
-          OS << getImplVendor();
+          if (implVendors_size() > 0) {
+            OS << *implVendors(). begin();
+            for (StringRef VendorName : llvm::drop_begin(implVendors(), 1))
+              OS << ", " << VendorName;
+          }
           OS << ")";
           OS << ")";
           break;
           break;
         case CtxUnknown:
         case CtxUnknown:

+ 5 - 5
include/clang/Sema/Sema.h

@@ -9110,15 +9110,15 @@ public:
         OMPDeclareVariantAttr::CtxSetUnknown;
         OMPDeclareVariantAttr::CtxSetUnknown;
     OMPDeclareVariantAttr::CtxSelectorType Ctx =
     OMPDeclareVariantAttr::CtxSelectorType Ctx =
         OMPDeclareVariantAttr::CtxUnknown;
         OMPDeclareVariantAttr::CtxUnknown;
-    StringRef ImplVendor;
+    MutableArrayRef<StringRef> ImplVendors;
     ExprResult CtxScore;
     ExprResult CtxScore;
     explicit OpenMPDeclareVariantCtsSelectorData() = default;
     explicit OpenMPDeclareVariantCtsSelectorData() = default;
     explicit OpenMPDeclareVariantCtsSelectorData(
     explicit OpenMPDeclareVariantCtsSelectorData(
         OMPDeclareVariantAttr::CtxSelectorSetType CtxSet,
         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.
   /// Checks if the variant/multiversion functions are compatible.

+ 2 - 1
lib/CodeGen/CGOpenMPRuntime.cpp

@@ -11172,7 +11172,8 @@ template <>
 bool checkContext<OMPDeclareVariantAttr::CtxSetImplementation,
 bool checkContext<OMPDeclareVariantAttr::CtxSetImplementation,
                   OMPDeclareVariantAttr::CtxVendor>(
                   OMPDeclareVariantAttr::CtxVendor>(
     const OMPDeclareVariantAttr *A) {
     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) {
 static bool greaterCtxScore(ASTContext &Ctx, const Expr *LHS, const Expr *RHS) {

+ 12 - 6
lib/Parse/ParseOpenMP.cpp

@@ -853,6 +853,7 @@ static void parseImplementationSelector(
     (void)T.expectAndConsume(diag::err_expected_lparen_after,
     (void)T.expectAndConsume(diag::err_expected_lparen_after,
                              CtxSelectorName.data());
                              CtxSelectorName.data());
     const ExprResult Score = parseContextScore(P);
     const ExprResult Score = parseContextScore(P);
+    SmallVector<llvm::SmallString<16>, 4> Vendors;
     do {
     do {
       // Parse <vendor>.
       // Parse <vendor>.
       StringRef VendorName;
       StringRef VendorName;
@@ -860,18 +861,14 @@ static void parseImplementationSelector(
         Buffer.clear();
         Buffer.clear();
         VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
         VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
         (void)P.ConsumeToken();
         (void)P.ConsumeToken();
+        if (!VendorName.empty())
+          Vendors.push_back(VendorName);
       } else {
       } else {
         P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected)
         P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected)
             << "vendor identifier"
             << "vendor identifier"
             << "vendor"
             << "vendor"
             << "implementation";
             << "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)) {
       if (!P.TryConsumeToken(tok::comma) && Tok.isNot(tok::r_paren)) {
         P.Diag(Tok, diag::err_expected_punc)
         P.Diag(Tok, diag::err_expected_punc)
             << (VendorName.empty() ? "vendor name" : VendorName);
             << (VendorName.empty() ? "vendor name" : VendorName);
@@ -879,6 +876,15 @@ static void parseImplementationSelector(
     } while (Tok.is(tok::identifier));
     } while (Tok.is(tok::identifier));
     // Parse ')'.
     // Parse ')'.
     (void)T.consumeClose();
     (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;
     break;
   }
   }
   case OMPDeclareVariantAttr::CtxUnknown:
   case OMPDeclareVariantAttr::CtxUnknown:

+ 2 - 2
lib/Sema/SemaOpenMP.cpp

@@ -5136,8 +5136,8 @@ void Sema::ActOnOpenMPDeclareVariantDirective(
     }
     }
   }
   }
   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
   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);
   FD->addAttr(NewAttr);
 }
 }
 
 

+ 5 - 3
lib/Sema/SemaTemplateInstantiateDecl.cpp

@@ -399,9 +399,11 @@ static void instantiateOMPDeclareVariantAttr(
   if (!DeclVarData)
   if (!DeclVarData)
     return;
     return;
   // Instantiate the attribute.
   // 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,
   S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
                                        DeclVarData.getValue().second,
                                        DeclVarData.getValue().second,
                                        Attr.getRange(), Data);
                                        Attr.getRange(), Data);

+ 1 - 2
test/OpenMP/declare_variant_ast_print.c

@@ -15,8 +15,7 @@ int foo(void);
 int bar(void);
 int bar(void);
 
 
 // CHECK:      int foo();
 // 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(unknown)})
 // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
 // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
 // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
 // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})

+ 2 - 4
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)})
 #pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)})
 int bar();
 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(unknown)})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)})
 // CHECK-NEXT: template <typename T, int C> T barbar();
 // CHECK-NEXT: template <typename T, int C> T barbar();
@@ -45,8 +44,7 @@ int bar();
 template <typename T, int C>
 template <typename T, int C>
 T barbar();
 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(unknown)})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
 // CHECK-NEXT: template<> int barbar<int, 3>();
 // CHECK-NEXT: template<> int barbar<int, 3>();

+ 7 - 0
test/OpenMP/declare_variant_implementation_vendor_codegen.cpp

@@ -13,6 +13,8 @@
 // CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv
 // CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv
 // CHECK-DAG: @_ZL9stat_usedv = internal alias i32 (), i32 ()* @_ZL10stat_used_v
 // 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: @_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 @_Z5bazzzv()
 // CHECK-DAG: declare {{.*}}i32 @_Z3bazv()
 // CHECK-DAG: declare {{.*}}i32 @_Z3bazv()
 // CHECK-DAG: ret i32 2
 // CHECK-DAG: ret i32 2
@@ -24,6 +26,7 @@
 // CHECK-DAG: ret i32 83
 // CHECK-DAG: ret i32 83
 // CHECK-DAG: ret i32 85
 // CHECK-DAG: ret i32 85
 // CHECK-DAG: ret i32 86
 // CHECK-DAG: ret i32 86
+// CHECK-DAG: ret i32 87
 // CHECK-NOT: ret i32 {{1|4|81|84}}
 // CHECK-NOT: ret i32 {{1|4|81|84}}
 
 
 #ifndef HEADER
 #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)})
 #pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(llvm)})
 int fn_linkage1() { return 1; }
 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
 #endif // HEADER