Skip to content

Commit 5deccd2

Browse files
authored
[SYCL][FPGA] Refactor [[intel::max_work_group_size()]] attribute implementation (#5392)
This patch 1. refactors FPGA function attribute [[intel::max_work_group_size()]] to better fit for community standards and separates the attribute from [[sycl::reqd_work_group_size()]] attribute implementation. 2. refactors the way we handled duplicate attributes and mutually exclusive attributes logic with when present on a given declaration. 3. handles redeclarations or template instantiations properly. 4. adds tests 5. Before the refactoring patch, we silently accepted this test case below: struct TRIFuncObjBad { [[intel::max_work_group_size(4, 4, 4)]] void operator()() const; }; [[intel::max_global_work_dim(0)]] void TRIFuncObjBad::operator()() const {} This PR fixes the bug and closes #5449 Signed-off-by: Soumi Manna <soumi.manna@intel.com>
1 parent 99177f0 commit 5deccd2

13 files changed

+340
-108
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,17 +1406,20 @@ def SYCLIntelMaxWorkGroupSize : InheritableAttr {
14061406
let LangOpts = [SYCLIsDevice, SYCLIsHost];
14071407
let Subjects = SubjectList<[Function], ErrorDiag>;
14081408
let AdditionalMembers = [{
1409-
ArrayRef<const Expr *> dimensions() const {
1410-
return {getXDim(), getYDim(), getZDim()};
1411-
}
1412-
Optional<llvm::APSInt> getXDimVal(ASTContext &Ctx) const {
1413-
return getXDim()->getIntegerConstantExpr(Ctx);
1409+
Optional<llvm::APSInt> getXDimVal() const {
1410+
if (const auto *CE = dyn_cast<ConstantExpr>(getXDim()))
1411+
return CE->getResultAsAPSInt();
1412+
return None;
14141413
}
1415-
Optional<llvm::APSInt> getYDimVal(ASTContext &Ctx) const {
1416-
return getYDim()->getIntegerConstantExpr(Ctx);
1414+
Optional<llvm::APSInt> getYDimVal() const {
1415+
if (const auto *CE = dyn_cast<ConstantExpr>(getYDim()))
1416+
return CE->getResultAsAPSInt();
1417+
return None;
14171418
}
1418-
Optional<llvm::APSInt> getZDimVal(ASTContext &Ctx) const {
1419-
return getZDim()->getIntegerConstantExpr(Ctx);
1419+
Optional<llvm::APSInt> getZDimVal() const {
1420+
if (const auto *CE = dyn_cast<ConstantExpr>(getZDim()))
1421+
return CE->getResultAsAPSInt();
1422+
return None;
14201423
}
14211424
}];
14221425
let Documentation = [SYCLIntelMaxWorkGroupSizeAttrDocs];

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10567,6 +10567,11 @@ class Sema final {
1056710567
const SYCLUsesAspectsAttr &A);
1056810568
void AddSYCLUsesAspectsAttr(Decl *D, const AttributeCommonInfo &CI,
1056910569
Expr **Exprs, unsigned Size);
10570+
void AddSYCLIntelMaxWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI,
10571+
Expr *XDim, Expr *YDim, Expr *ZDim);
10572+
SYCLIntelMaxWorkGroupSizeAttr *
10573+
MergeSYCLIntelMaxWorkGroupSizeAttr(Decl *D,
10574+
const SYCLIntelMaxWorkGroupSizeAttr &A);
1057010575
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
1057110576
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1057210577
bool IsPackExpansion);

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -743,24 +743,16 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
743743

744744
if (const SYCLIntelMaxWorkGroupSizeAttr *A =
745745
FD->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
746-
ASTContext &ClangCtx = FD->getASTContext();
747-
Optional<llvm::APSInt> XDimVal = A->getXDimVal(ClangCtx);
748-
Optional<llvm::APSInt> YDimVal = A->getYDimVal(ClangCtx);
749-
Optional<llvm::APSInt> ZDimVal = A->getZDimVal(ClangCtx);
750746

751-
// For a SYCLDevice SYCLIntelMaxWorkGroupSizeAttr arguments are reversed.
752-
if (getLangOpts().SYCLIsDevice)
753-
std::swap(XDimVal, ZDimVal);
754-
755-
llvm::Metadata *AttrMDArgs[] = {
756-
llvm::ConstantAsMetadata::get(
757-
Builder.getInt32(XDimVal->getZExtValue())),
758-
llvm::ConstantAsMetadata::get(
759-
Builder.getInt32(YDimVal->getZExtValue())),
760-
llvm::ConstantAsMetadata::get(
761-
Builder.getInt32(ZDimVal->getZExtValue()))};
762-
Fn->setMetadata("max_work_group_size",
763-
llvm::MDNode::get(Context, AttrMDArgs));
747+
// Attributes arguments (first and third) are reversed on SYCLDevice.
748+
if (getLangOpts().SYCLIsDevice) {
749+
llvm::Metadata *AttrMDArgs[] = {
750+
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getZDimVal())),
751+
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getYDimVal())),
752+
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getXDimVal()))};
753+
Fn->setMetadata("max_work_group_size",
754+
llvm::MDNode::get(Context, AttrMDArgs));
755+
}
764756
}
765757

766758
if (const auto *A = FD->getAttr<SYCLIntelNoGlobalWorkOffsetAttr>()) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2781,6 +2781,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
27812781
NewAttr = S.MergeSYCLUsesAspectsAttr(D, *A);
27822782
else if (const auto *A = dyn_cast<SYCLIntelPipeIOAttr>(Attr))
27832783
NewAttr = S.MergeSYCLIntelPipeIOAttr(D, *A);
2784+
else if (const auto *A = dyn_cast<SYCLIntelMaxWorkGroupSizeAttr>(Attr))
2785+
NewAttr = S.MergeSYCLIntelMaxWorkGroupSizeAttr(D, *A);
27842786
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
27852787
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
27862788

@@ -3482,8 +3484,6 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
34823484

34833485
checkDimensionsAndSetDiagnostics<ReqdWorkGroupSizeAttr>(*this, New, Old);
34843486

3485-
checkDimensionsAndSetDiagnostics<SYCLIntelMaxWorkGroupSizeAttr>(*this, New,
3486-
Old);
34873487
if (const auto *ILA = New->getAttr<InternalLinkageAttr>())
34883488
if (!Old->hasAttr<InternalLinkageAttr>()) {
34893489
Diag(New->getLocation(), diag::err_attribute_missing_on_first_decl)

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 149 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3245,12 +3245,9 @@ static bool checkWorkGroupSizeValues(Sema &S, Decl *D, const ParsedAttr &AL) {
32453245
ASTContext &Ctx = S.getASTContext();
32463246

32473247
if (const auto *A = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
3248-
if (!((getExprValue(AL.getArgAsExpr(0), Ctx) <=
3249-
getExprValue(A->getXDim(), Ctx)) &&
3250-
(getExprValue(AL.getArgAsExpr(1), Ctx) <=
3251-
getExprValue(A->getYDim(), Ctx)) &&
3252-
(getExprValue(AL.getArgAsExpr(2), Ctx) <=
3253-
getExprValue(A->getZDim(), Ctx)))) {
3248+
if (!((getExprValue(AL.getArgAsExpr(0), Ctx) <= *A->getXDimVal()) &&
3249+
(getExprValue(AL.getArgAsExpr(1), Ctx) <= *A->getYDimVal()) &&
3250+
(getExprValue(AL.getArgAsExpr(2), Ctx) <= *A->getZDimVal()))) {
32543251
S.Diag(AL.getLoc(), diag::err_conflicting_sycl_function_attributes)
32553252
<< AL << A->getSpelling();
32563253
Result &= false;
@@ -3272,19 +3269,18 @@ static bool checkWorkGroupSizeValues(Sema &S, Decl *D, const ParsedAttr &AL) {
32723269
return Result;
32733270
}
32743271

3275-
// Handles reqd_work_group_size and max_work_group_size.
3272+
// Handles reqd_work_group_size.
32763273
template <typename WorkGroupAttr>
32773274
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
32783275
if (D->isInvalidDecl())
32793276
return;
32803277

32813278
S.CheckDeprecatedSYCLAttributeSpelling(AL);
3282-
// __attribute__((reqd_work_group_size)), [[cl::reqd_work_group_size]], and
3283-
// [[intel::max_work_group_size]] all require exactly three arguments.
3279+
// __attribute__((reqd_work_group_size)) and [[cl::reqd_work_group_size]]
3280+
// all require exactly three arguments.
32843281
if ((AL.getKind() == ParsedAttr::AT_ReqdWorkGroupSize &&
32853282
AL.getAttributeSpellingListIndex() ==
32863283
ReqdWorkGroupSizeAttr::CXX11_cl_reqd_work_group_size) ||
3287-
AL.getKind() == ParsedAttr::AT_SYCLIntelMaxWorkGroupSize ||
32883284
AL.getSyntax() == ParsedAttr::AS_GNU) {
32893285
if (!AL.checkExactlyNumArgs(S, 3))
32903286
return;
@@ -3348,8 +3344,8 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
33483344
}
33493345
}
33503346

3351-
// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr or
3352-
// ReqdWorkGroupSizeAttr, check to see if they hold equal values
3347+
// If the declaration has a ReqdWorkGroupSizeAttr,
3348+
// check to see if they hold equal values
33533349
// (1, 1, 1) in case the value of SYCLIntelMaxGlobalWorkDimAttr
33543350
// equals to 0.
33553351
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
@@ -3494,6 +3490,146 @@ static void handleWorkGroupSizeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
34943490
AL.getArgAsExpr(2));
34953491
}
34963492

3493+
// Handles max_work_group_size attribute.
3494+
// If the [[intel::max_work_group_size(X, Y, Z)]] attribute is specified on a
3495+
// declaration along with [[intel::max_global_work_dim()]] attribute,
3496+
// check to see if all arguments of [[intel::max_work_group_size(X, Y, Z)]]
3497+
// attribute hold value 1 in case the argument of
3498+
// [[intel::max_global_work_dim()]] attribute equals to 0.
3499+
static bool InvalidWorkGroupSizeAttrs(const Expr *MGValue, const Expr *XDim,
3500+
const Expr *YDim, const Expr *ZDim) {
3501+
// If any of the operand is still value dependent, we can't test anything.
3502+
const auto *MGValueExpr = dyn_cast<ConstantExpr>(MGValue);
3503+
const auto *XDimExpr = dyn_cast<ConstantExpr>(XDim);
3504+
const auto *YDimExpr = dyn_cast<ConstantExpr>(YDim);
3505+
const auto *ZDimExpr = dyn_cast<ConstantExpr>(ZDim);
3506+
3507+
if (!MGValueExpr || !XDimExpr || !YDimExpr || !ZDimExpr)
3508+
return false;
3509+
3510+
// Otherwise, check if the attribute values are equal to one.
3511+
return (MGValueExpr->getResultAsAPSInt() == 0 &&
3512+
(XDimExpr->getResultAsAPSInt() != 1 ||
3513+
YDimExpr->getResultAsAPSInt() != 1 ||
3514+
ZDimExpr->getResultAsAPSInt() != 1));
3515+
}
3516+
3517+
void Sema::AddSYCLIntelMaxWorkGroupSizeAttr(Decl *D,
3518+
const AttributeCommonInfo &CI,
3519+
Expr *XDim, Expr *YDim,
3520+
Expr *ZDim) {
3521+
// Returns nullptr if diagnosing, otherwise returns the original expression
3522+
// or the original expression converted to a constant expression.
3523+
auto CheckAndConvertArg = [&](Expr *E) -> Expr * {
3524+
// Check if the expression is not value dependent.
3525+
if (!E->isValueDependent()) {
3526+
llvm::APSInt ArgVal;
3527+
ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal);
3528+
if (Res.isInvalid())
3529+
return nullptr;
3530+
E = Res.get();
3531+
3532+
// This attribute requires a strictly positive value.
3533+
if (ArgVal <= 0) {
3534+
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
3535+
<< CI << /*positive*/ 0;
3536+
return nullptr;
3537+
}
3538+
}
3539+
return E;
3540+
};
3541+
3542+
// Check all three argument values, and if any are bad, bail out. This will
3543+
// convert the given expressions into constant expressions when possible.
3544+
XDim = CheckAndConvertArg(XDim);
3545+
YDim = CheckAndConvertArg(YDim);
3546+
ZDim = CheckAndConvertArg(ZDim);
3547+
if (!XDim || !YDim || !ZDim)
3548+
return;
3549+
3550+
// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr, check to see if
3551+
// the attribute holds equal values to (1, 1, 1) in case the value of
3552+
// SYCLIntelMaxGlobalWorkDimAttr equals to 0.
3553+
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
3554+
if (InvalidWorkGroupSizeAttrs(DeclAttr->getValue(), XDim, YDim, ZDim)) {
3555+
Diag(CI.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
3556+
<< CI << DeclAttr;
3557+
return;
3558+
}
3559+
}
3560+
3561+
// If the attribute was already applied with different arguments, then
3562+
// diagnose the second attribute as a duplicate and don't add it.
3563+
if (const auto *Existing = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
3564+
DupArgResult Results[] = {AreArgValuesIdentical(XDim, Existing->getXDim()),
3565+
AreArgValuesIdentical(YDim, Existing->getYDim()),
3566+
AreArgValuesIdentical(ZDim, Existing->getZDim())};
3567+
// If any of the results are known to be different, we can diagnose at this
3568+
// point and drop the attribute.
3569+
if (llvm::is_contained(Results, DupArgResult::Different)) {
3570+
Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI;
3571+
Diag(Existing->getLoc(), diag::note_previous_attribute);
3572+
return;
3573+
}
3574+
// If all of the results are known to be the same, we can silently drop the
3575+
// attribute. Otherwise, we have to add the attribute and resolve its
3576+
// differences later.
3577+
if (llvm::all_of(Results,
3578+
[](DupArgResult V) { return V == DupArgResult::Same; }))
3579+
return;
3580+
}
3581+
3582+
D->addAttr(::new (Context)
3583+
SYCLIntelMaxWorkGroupSizeAttr(Context, CI, XDim, YDim, ZDim));
3584+
}
3585+
3586+
SYCLIntelMaxWorkGroupSizeAttr *Sema::MergeSYCLIntelMaxWorkGroupSizeAttr(
3587+
Decl *D, const SYCLIntelMaxWorkGroupSizeAttr &A) {
3588+
// Check to see if there's a duplicate attribute already applied.
3589+
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
3590+
DupArgResult Results[] = {
3591+
AreArgValuesIdentical(DeclAttr->getXDim(), A.getXDim()),
3592+
AreArgValuesIdentical(DeclAttr->getYDim(), A.getYDim()),
3593+
AreArgValuesIdentical(DeclAttr->getZDim(), A.getZDim())};
3594+
3595+
// If any of the results are known to be different, we can diagnose at this
3596+
// point and drop the attribute.
3597+
if (llvm::is_contained(Results, DupArgResult::Different)) {
3598+
Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A;
3599+
Diag(A.getLoc(), diag::note_previous_attribute);
3600+
return nullptr;
3601+
}
3602+
// If all of the results are known to be the same, we can silently drop the
3603+
// attribute. Otherwise, we have to add the attribute and resolve its
3604+
// differences later.
3605+
if (llvm::all_of(Results,
3606+
[](DupArgResult V) { return V == DupArgResult::Same; }))
3607+
return nullptr;
3608+
}
3609+
3610+
// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr,
3611+
// check to see if the attribute holds equal values to
3612+
// (1, 1, 1) in case the value of SYCLIntelMaxGlobalWorkDimAttr
3613+
// equals to 0.
3614+
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
3615+
if (InvalidWorkGroupSizeAttrs(DeclAttr->getValue(), A.getXDim(),
3616+
A.getYDim(), A.getZDim())) {
3617+
Diag(A.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
3618+
<< &A << DeclAttr;
3619+
return nullptr;
3620+
}
3621+
}
3622+
3623+
return ::new (Context) SYCLIntelMaxWorkGroupSizeAttr(
3624+
Context, A, A.getXDim(), A.getYDim(), A.getZDim());
3625+
}
3626+
3627+
static void handleSYCLIntelMaxWorkGroupSize(Sema &S, Decl *D,
3628+
const ParsedAttr &AL) {
3629+
S.AddSYCLIntelMaxWorkGroupSizeAttr(D, AL, AL.getArgAsExpr(0),
3630+
AL.getArgAsExpr(1), AL.getArgAsExpr(2));
3631+
}
3632+
34973633
void Sema::AddIntelReqdSubGroupSize(Decl *D, const AttributeCommonInfo &CI,
34983634
Expr *E) {
34993635
if (!E->isValueDependent()) {
@@ -10371,7 +10507,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
1037110507
handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);
1037210508
break;
1037310509
case ParsedAttr::AT_SYCLIntelMaxWorkGroupSize:
10374-
handleWorkGroupSize<SYCLIntelMaxWorkGroupSizeAttr>(S, D, AL);
10510+
handleSYCLIntelMaxWorkGroupSize(S, D, AL);
1037510511
break;
1037610512
case ParsedAttr::AT_IntelReqdSubGroupSize:
1037710513
handleIntelReqdSubGroupSize(S, D, AL);

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3910,9 +3910,9 @@ static void PropagateAndDiagnoseDeviceAttr(
39103910
} else if (auto *Existing =
39113911
SYCLKernel->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
39123912
ASTContext &Ctx = S.getASTContext();
3913-
if (Existing->getXDimVal(Ctx) < RWGSA->getXDimVal(Ctx) ||
3914-
Existing->getYDimVal(Ctx) < RWGSA->getYDimVal(Ctx) ||
3915-
Existing->getZDimVal(Ctx) < RWGSA->getZDimVal(Ctx)) {
3913+
if (*Existing->getXDimVal() < RWGSA->getXDimVal(Ctx) ||
3914+
*Existing->getYDimVal() < RWGSA->getYDimVal(Ctx) ||
3915+
*Existing->getZDimVal() < RWGSA->getZDimVal(Ctx)) {
39163916
S.Diag(SYCLKernel->getLocation(),
39173917
diag::err_conflicting_sycl_kernel_attributes);
39183918
S.Diag(Existing->getLocation(), diag::note_conflicting_attribute);
@@ -3930,9 +3930,9 @@ static void PropagateAndDiagnoseDeviceAttr(
39303930
auto *SIMWGSA = cast<SYCLIntelMaxWorkGroupSizeAttr>(A);
39313931
if (auto *Existing = SYCLKernel->getAttr<ReqdWorkGroupSizeAttr>()) {
39323932
ASTContext &Ctx = S.getASTContext();
3933-
if (Existing->getXDimVal(Ctx) > SIMWGSA->getXDimVal(Ctx) ||
3934-
Existing->getYDimVal(Ctx) > SIMWGSA->getYDimVal(Ctx) ||
3935-
Existing->getZDimVal(Ctx) > SIMWGSA->getZDimVal(Ctx)) {
3933+
if (Existing->getXDimVal(Ctx) > *SIMWGSA->getXDimVal() ||
3934+
Existing->getYDimVal(Ctx) > *SIMWGSA->getYDimVal() ||
3935+
Existing->getZDimVal(Ctx) > *SIMWGSA->getZDimVal()) {
39363936
S.Diag(SYCLKernel->getLocation(),
39373937
diag::err_conflicting_sycl_kernel_attributes);
39383938
S.Diag(Existing->getLocation(), diag::note_conflicting_attribute);

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,25 @@ static void instantiateWorkGroupSizeHintAttr(
814814
ZResult.get());
815815
}
816816

817+
static void instantiateSYCLIntelMaxWorkGroupSizeAttr(
818+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
819+
const SYCLIntelMaxWorkGroupSizeAttr *A, Decl *New) {
820+
EnterExpressionEvaluationContext Unevaluated(
821+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
822+
ExprResult XResult = S.SubstExpr(A->getXDim(), TemplateArgs);
823+
if (XResult.isInvalid())
824+
return;
825+
ExprResult YResult = S.SubstExpr(A->getYDim(), TemplateArgs);
826+
if (YResult.isInvalid())
827+
return;
828+
ExprResult ZResult = S.SubstExpr(A->getZDim(), TemplateArgs);
829+
if (ZResult.isInvalid())
830+
return;
831+
832+
S.AddSYCLIntelMaxWorkGroupSizeAttr(New, *A, XResult.get(), YResult.get(),
833+
ZResult.get());
834+
}
835+
817836
// This doesn't take any template parameters, but we have a custom action that
818837
// needs to happen when the kernel itself is instantiated. We need to run the
819838
// ItaniumMangler to mark the names required to name this kernel.
@@ -1045,8 +1064,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
10451064
}
10461065
if (const auto *SYCLIntelMaxWorkGroupSize =
10471066
dyn_cast<SYCLIntelMaxWorkGroupSizeAttr>(TmplAttr)) {
1048-
instantiateIntelSYCTripleLFunctionAttr<SYCLIntelMaxWorkGroupSizeAttr>(
1049-
*this, TemplateArgs, SYCLIntelMaxWorkGroupSize, New);
1067+
instantiateSYCLIntelMaxWorkGroupSizeAttr(*this, TemplateArgs,
1068+
SYCLIntelMaxWorkGroupSize, New);
10501069
continue;
10511070
}
10521071
if (const auto *SYCLIntelMaxConcurrency =

0 commit comments

Comments
 (0)