Skip to content

Commit cde3fb4

Browse files
committed
[OpenMP] implementation set triggers elision for begin declare variant
The device and implementation set should trigger elision of tokens if they do not match statically in a begin/end declare variant. This simply extends the logic from the device set only and includes the implementation set. Reported by @kkwli.
1 parent ad5b3e0 commit cde3fb4

File tree

4 files changed

+37
-17
lines changed

4 files changed

+37
-17
lines changed

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2270,7 +2270,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
22702270
/* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>(),
22712271
Actions.OpenMP().getOpenMPDeviceNum());
22722272

2273-
if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
2273+
if (isVariantApplicableInContext(VMI, OMPCtx, /*DeviceOrImplementationSetOnly=*/ true)) {
22742274
Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
22752275
break;
22762276
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c -std=c99 -fms-extensions -Wno-pragma-pack %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -x c -std=c99 -fms-extensions -Wno-pragma-pack %s
3+
4+
// expected-no-diagnostics
5+
6+
#pragma omp begin declare variant match(implementation={vendor(llvm)})
7+
typedef int bar;
8+
void f() {}
9+
#pragma omp end declare variant
10+
11+
#pragma omp begin declare variant match(implementation={vendor(ibm)})
12+
typedef float bar;
13+
void f() {}
14+
#pragma omp end declare variant

llvm/include/llvm/Frontend/OpenMP/OMPContext.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,13 @@ struct OMPContext {
180180
};
181181

182182
/// Return true if \p VMI is applicable in \p Ctx, that is, all traits required
183-
/// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is
184-
/// true, only the device selector set, if present, are checked. Note that we
185-
/// still honor extension traits provided by the user.
183+
/// by \p VMI are available in the OpenMP context \p Ctx. If
184+
/// \p DeviceOrImplementationSetOnly is true, only the device and implementation
185+
/// selector set, if present, are checked. Note that we still honor extension
186+
/// traits provided by the user.
186187
bool isVariantApplicableInContext(const VariantMatchInfo &VMI,
187188
const OMPContext &Ctx,
188-
bool DeviceSetOnly = false);
189+
bool DeviceOrImplementationSetOnly = false);
189190

190191
/// Return the index (into \p VMIs) of the variant with the highest score
191192
/// from the ones applicable in \p Ctx. See llvm::isVariantApplicableInContext.

llvm/lib/Frontend/OpenMP/OMPContext.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,11 @@ static bool isStrictSubset(const VariantMatchInfo &VMI0,
193193
return true;
194194
}
195195

196-
static int isVariantApplicableInContextHelper(
197-
const VariantMatchInfo &VMI, const OMPContext &Ctx,
198-
SmallVectorImpl<unsigned> *ConstructMatches, bool DeviceSetOnly) {
196+
static int
197+
isVariantApplicableInContextHelper(const VariantMatchInfo &VMI,
198+
const OMPContext &Ctx,
199+
SmallVectorImpl<unsigned> *ConstructMatches,
200+
bool DeviceOrImplementationSetOnly) {
199201

200202
// The match kind determines if we need to match all traits, any of the
201203
// traits, or none of the traits for it to be an applicable context.
@@ -245,8 +247,10 @@ static int isVariantApplicableInContextHelper(
245247

246248
for (unsigned Bit : VMI.RequiredTraits.set_bits()) {
247249
TraitProperty Property = TraitProperty(Bit);
248-
if (DeviceSetOnly &&
249-
getOpenMPContextTraitSetForProperty(Property) != TraitSet::device)
250+
if (DeviceOrImplementationSetOnly &&
251+
getOpenMPContextTraitSetForProperty(Property) != TraitSet::device &&
252+
getOpenMPContextTraitSetForProperty(Property) !=
253+
TraitSet::implementation)
250254
continue;
251255

252256
// So far all extensions are handled elsewhere, we skip them here as they
@@ -272,7 +276,7 @@ static int isVariantApplicableInContextHelper(
272276
return *Result;
273277
}
274278

275-
if (!DeviceSetOnly) {
279+
if (!DeviceOrImplementationSetOnly) {
276280
// We could use isSubset here but we also want to record the match
277281
// locations.
278282
unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();
@@ -315,11 +319,11 @@ static int isVariantApplicableInContextHelper(
315319
return true;
316320
}
317321

318-
bool llvm::omp::isVariantApplicableInContext(const VariantMatchInfo &VMI,
319-
const OMPContext &Ctx,
320-
bool DeviceSetOnly) {
322+
bool llvm::omp::isVariantApplicableInContext(
323+
const VariantMatchInfo &VMI, const OMPContext &Ctx,
324+
bool DeviceOrImplementationSetOnly) {
321325
return isVariantApplicableInContextHelper(
322-
VMI, Ctx, /* ConstructMatches */ nullptr, DeviceSetOnly);
326+
VMI, Ctx, /* ConstructMatches */ nullptr, DeviceOrImplementationSetOnly);
323327
}
324328

325329
static APInt getVariantMatchScore(const VariantMatchInfo &VMI,
@@ -418,8 +422,9 @@ int llvm::omp::getBestVariantMatchForContext(
418422

419423
SmallVector<unsigned, 8> ConstructMatches;
420424
// If the variant is not applicable its not the best.
421-
if (!isVariantApplicableInContextHelper(VMI, Ctx, &ConstructMatches,
422-
/* DeviceSetOnly */ false))
425+
if (!isVariantApplicableInContextHelper(
426+
VMI, Ctx, &ConstructMatches,
427+
/* DeviceOrImplementationSetOnly */ false))
423428
continue;
424429
// Check if its clearly not the best.
425430
APInt Score = getVariantMatchScore(VMI, Ctx, ConstructMatches);

0 commit comments

Comments
 (0)