diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index f816b5f1961da..92c0e195d8ad2 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -2418,6 +2418,26 @@ device kernel, the attribute is not ignored and it is propagated to the kernel. [[intel::num_simd_work_items(N)]] void operator()() const {} }; +If the`` intel::reqd_work_group_size`` or ``cl::reqd_work_group_size`` +attribute is specified on a declaration along with a +intel::num_simd_work_items attribute, the work group size attribute +arguments must all be evenly divisible by the argument specified in +the ``intel::num_simd_work_items`` attribute. + +.. code-block:: c++ + + struct func { + [[intel::num_simd_work_items(4)]] + [[intel::reqd_work_group_size(64, 64, 64)]] + void operator()() const {} + }; + + struct bar { + [[intel::reqd_work_group_size(64, 64, 64)]] + [[intel::num_simd_work_items(4)]] + void operator()() const {} + }; + }]; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d02538ef6f799..39c14167723ae 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11212,6 +11212,9 @@ def err_sycl_invalid_accessor_property_list_template_param : Error< "%select{accessor_property_list|accessor_property_list pack argument|buffer_location}0 " "template parameter must be a " "%select{parameter pack|type|non-negative integer}1">; +def err_sycl_num_kernel_wrong_reqd_wg_size : Error< + "%0 attribute must evenly divide the work-group size for the %1 attribute">; + def warn_sycl_pass_by_value_deprecated : Warning<"Passing kernel functions by value is deprecated in SYCL 2020">, InGroup, ShowInSystemHeader; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8a5f289d43724..51e6ef2dda01a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13068,8 +13068,7 @@ void Sema::addIntelSingleArgAttr(Decl *D, const AttributeCommonInfo &CI, return; E = ICE.get(); int32_t ArgInt = ArgVal.getSExtValue(); - if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelNumSimdWorkItems || - CI.getParsedKind() == ParsedAttr::AT_IntelReqdSubGroupSize || + if (CI.getParsedKind() == ParsedAttr::AT_IntelReqdSubGroupSize || CI.getParsedKind() == ParsedAttr::AT_IntelFPGAMaxReplicates) { if (ArgInt <= 0) { Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) @@ -13077,12 +13076,15 @@ void Sema::addIntelSingleArgAttr(Decl *D, const AttributeCommonInfo &CI, return; } } - if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) { + if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim || + CI.getParsedKind() == ParsedAttr::AT_SYCLIntelNumSimdWorkItems) { if (ArgInt < 0) { Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) << CI << /*non-negative*/ 1; return; } + } + if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) { if (ArgInt > 3) { Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range) << CI << 0 << 3 << E->getSourceRange(); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 7cf0344ba9153..0558baa1e4ece 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3130,26 +3130,53 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - if (WorkGroupAttr *ExistingAttr = D->getAttr()) { - ASTContext &Ctx = S.getASTContext(); - Optional XDimVal = XDimExpr->getIntegerConstantExpr(Ctx); - Optional YDimVal = YDimExpr->getIntegerConstantExpr(Ctx); - Optional ZDimVal = ZDimExpr->getIntegerConstantExpr(Ctx); - Optional ExistingXDimVal = ExistingAttr->getXDimVal(Ctx); - Optional ExistingYDimVal = ExistingAttr->getYDimVal(Ctx); - Optional ExistingZDimVal = ExistingAttr->getZDimVal(Ctx); - - // Compare attribute arguments value and warn for a mismatch. - if (ExistingXDimVal != XDimVal || ExistingYDimVal != YDimVal || - ExistingZDimVal != ZDimVal) { - S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL; - S.Diag(ExistingAttr->getLocation(), diag::note_conflicting_attribute); + ASTContext &Ctx = S.getASTContext(); + + if (!XDimExpr->isValueDependent() && !YDimExpr->isValueDependent() && + !ZDimExpr->isValueDependent()) { + llvm::APSInt XDimVal, YDimVal, ZDimVal; + ExprResult XDim = S.VerifyIntegerConstantExpression(XDimExpr, &XDimVal); + ExprResult YDim = S.VerifyIntegerConstantExpression(YDimExpr, &YDimVal); + ExprResult ZDim = S.VerifyIntegerConstantExpression(ZDimExpr, &ZDimVal); + + if (XDim.isInvalid()) + return; + XDimExpr = XDim.get(); + + if (YDim.isInvalid()) + return; + YDimExpr = YDim.get(); + + if (ZDim.isInvalid()) + return; + ZDimExpr = ZDim.get(); + + if (const auto *A = D->getAttr()) { + int64_t NumSimdWorkItems = + A->getValue()->getIntegerConstantExpr(Ctx)->getSExtValue(); + + if (!(XDimVal.getZExtValue() % NumSimdWorkItems == 0 || + YDimVal.getZExtValue() % NumSimdWorkItems == 0 || + ZDimVal.getZExtValue() % NumSimdWorkItems == 0)) { + S.Diag(A->getLocation(), diag::err_sycl_num_kernel_wrong_reqd_wg_size) + << A << AL; + S.Diag(AL.getLoc(), diag::note_conflicting_attribute); + return; + } + } + if (const auto *ExistingAttr = D->getAttr()) { + // Compare attribute arguments value and warn for a mismatch. + if (ExistingAttr->getXDimVal(Ctx) != XDimVal || + ExistingAttr->getYDimVal(Ctx) != YDimVal || + ExistingAttr->getZDimVal(Ctx) != ZDimVal) { + S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL; + S.Diag(ExistingAttr->getLocation(), diag::note_conflicting_attribute); + } } + if (!checkWorkGroupSizeValues(S, D, AL)) + return; } - if (!checkWorkGroupSizeValues(S, D, AL)) - return; - S.addIntelTripleArgAttr(D, AL, XDimExpr, YDimExpr, ZDimExpr); } @@ -3196,18 +3223,51 @@ static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { } // Handles num_simd_work_items. -static void handleNumSimdWorkItemsAttr(Sema &S, Decl *D, const ParsedAttr &A) { +static void handleNumSimdWorkItemsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (D->isInvalidDecl()) return; - Expr *E = A.getArgAsExpr(0); + Expr *E = AL.getArgAsExpr(0); if (D->getAttr()) - S.Diag(A.getLoc(), diag::warn_duplicate_attribute) << A; + S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL; - S.CheckDeprecatedSYCLAttributeSpelling(A); + S.CheckDeprecatedSYCLAttributeSpelling(AL); + + if (!E->isValueDependent()) { + llvm::APSInt ArgVal; + ExprResult ICE = S.VerifyIntegerConstantExpression(E, &ArgVal); - S.addIntelSingleArgAttr(D, A, E); + if (ICE.isInvalid()) + return; + + E = ICE.get(); + int64_t NumSimdWorkItems = ArgVal.getSExtValue(); + + if (NumSimdWorkItems == 0) { + S.Diag(E->getExprLoc(), diag::err_attribute_argument_is_zero) + << AL << E->getSourceRange(); + return; + } + + if (const auto *A = D->getAttr()) { + ASTContext &Ctx = S.getASTContext(); + Optional XDimVal = A->getXDimVal(Ctx); + Optional YDimVal = A->getYDimVal(Ctx); + Optional ZDimVal = A->getZDimVal(Ctx); + + if (!(XDimVal->getZExtValue() % NumSimdWorkItems == 0 || + YDimVal->getZExtValue() % NumSimdWorkItems == 0 || + ZDimVal->getZExtValue() % NumSimdWorkItems == 0)) { + S.Diag(AL.getLoc(), diag::err_sycl_num_kernel_wrong_reqd_wg_size) + << AL << A; + S.Diag(A->getLocation(), diag::note_conflicting_attribute); + return; + } + } + } + + S.addIntelSingleArgAttr(D, AL, E); } // Handles use_stall_enable_clusters @@ -5967,14 +6027,13 @@ void Sema::addSYCLIntelPipeIOAttr(Decl *D, const AttributeCommonInfo &Attr, Optional ArgVal = E->getIntegerConstantExpr(getASTContext()); if (!ArgVal) { Diag(E->getExprLoc(), diag::err_attribute_argument_type) - << Attr.getAttrName() << AANT_ArgumentIntegerConstant - << E->getSourceRange(); + << Attr << AANT_ArgumentIntegerConstant << E->getSourceRange(); return; } int32_t ArgInt = ArgVal->getSExtValue(); if (ArgInt < 0) { Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) - << Attr.getAttrName() << /*non-negative*/ 1; + << Attr << /*non-negative*/ 1; return; } } diff --git a/clang/test/SemaSYCL/num_simd_work_items_device.cpp b/clang/test/SemaSYCL/num_simd_work_items_device.cpp index 86cd14a140a0b..96c7db29de8ea 100644 --- a/clang/test/SemaSYCL/num_simd_work_items_device.cpp +++ b/clang/test/SemaSYCL/num_simd_work_items_device.cpp @@ -33,6 +33,172 @@ struct FuncObj { [[intel::num_simd_work_items(42)]] void operator()() const {} }; +#ifdef TRIGGER_ERROR +struct TRIFuncObjBad1 { + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + [[intel::reqd_work_group_size(5, 5, 5)]] //expected-note{{conflicting attribute is here}} + void + operator()() const {} +}; + +struct TRIFuncObjBad2 { + [[intel::reqd_work_group_size(5, 5, 5)]] // expected-note{{conflicting attribute is here}} + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + void + operator()() const {} +}; + +struct TRIFuncObjBad3 { + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + [[cl::reqd_work_group_size(5, 5, 5)]] //expected-note{{conflicting attribute is here}} + void + operator()() const {} +}; + +struct TRIFuncObjBad4 { + [[cl::reqd_work_group_size(5, 5, 5)]] // expected-note{{conflicting attribute is here}} + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + void + operator()() const {} +}; + +struct TRIFuncObjBad5 { + [[intel::num_simd_work_items(0)]] // expected-error{{'num_simd_work_items' attribute must be greater than 0}} + [[intel::reqd_work_group_size(5, 5, 5)]] void + operator()() const {} +}; + +struct TRIFuncObjBad6 { + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + [[intel::reqd_work_group_size(5)]] //expected-note{{conflicting attribute is here}} + void + operator()() const {} +}; + +struct TRIFuncObjBad7 { + [[intel::reqd_work_group_size(5)]] // expected-note{{conflicting attribute is here}} + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + void + operator()() const {} +}; + +struct TRIFuncObjBad8 { + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + [[intel::reqd_work_group_size(5, 5)]] // expected-note{{conflicting attribute is here}} + void + operator()() const {} +}; + +struct TRIFuncObjBad9 { + [[intel::reqd_work_group_size(5, 5)]] // expected-note{{conflicting attribute is here}} + [[intel::num_simd_work_items(3)]] // expected-error{{'num_simd_work_items' attribute must evenly divide the work-group size for the 'reqd_work_group_size' attribute}} + void + operator()() const {} +}; + +struct TRIFuncObjBad10 { + [[intel::reqd_work_group_size(5, 5, 5)]] + [[intel::num_simd_work_items(0)]] // expected-error{{'num_simd_work_items' attribute must be greater than 0}} + void operator()() const {} +}; + +struct TRIFuncObjBad11 { + [[intel::num_simd_work_items(3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + [[intel::reqd_work_group_size(64, 64, 64)]] + void operator()() const {} +}; + +struct TRIFuncObjBad12 { + [[intel::reqd_work_group_size(64, 64, 64)]] + [[intel::num_simd_work_items(3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + void operator()() const {} +}; + +struct TRIFuncObjBad13 { + [[intel::reqd_work_group_size(0)]] // expected-error{{'reqd_work_group_size' attribute must be greater than 0}} + [[intel::num_simd_work_items(0)]] // expected-error{{'num_simd_work_items' attribute must be greater than 0}} + void operator()() const {} +}; + +struct TRIFuncObjBad14 { + [[intel::num_simd_work_items(0)]] // expected-error{{'num_simd_work_items' attribute must be greater than 0}} + [[intel::reqd_work_group_size(0)]] // expected-error{{'reqd_work_group_size' attribute must be greater than 0}} + void operator()() const {} +}; + +struct TRIFuncObjBad15 { + [[intel::num_simd_work_items(3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + [[intel::reqd_work_group_size(3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + void operator()() const {} +}; + +struct TRIFuncObjBad16 { + [[intel::reqd_work_group_size(3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + [[intel::num_simd_work_items(3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + void operator()() const {} +}; + +struct TRIFuncObjBad17 { + [[intel::num_simd_work_items(3)]] + [[intel::reqd_work_group_size(3, 3, 3.f)]] // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + void operator()() const {} +}; + +struct TRIFuncObjBad18 { + [[intel::num_simd_work_items(-1)]] // expected-error{{'num_simd_work_items' attribute requires a non-negative integral compile time constant expression}} + [[intel::reqd_work_group_size(-1)]] // expected-warning{{implicit conversion changes signedness: 'int' to 'unsigned long long'}} + void operator()() const {} +}; +#endif // TRIGGER_ERROR + +struct TRIFuncObjGood1 { + [[intel::num_simd_work_items(4)]] + [[intel::reqd_work_group_size(64, 64, 64)]] void + operator()() const {} +}; + +struct TRIFuncObjGood2 { + [[intel::reqd_work_group_size(64, 64, 64)]] + [[intel::num_simd_work_items(4)]] void + operator()() const {} +}; + +struct TRIFuncObjGood3 { + [[intel::num_simd_work_items(4)]] + [[cl::reqd_work_group_size(64, 64, 64)]] void + operator()() const {} +}; + +struct TRIFuncObjGood4 { + [[cl::reqd_work_group_size(64, 64, 64)]] + [[intel::num_simd_work_items(4)]] void + operator()() const {} +}; + +struct TRIFuncObjGood5 { + [[intel::num_simd_work_items(4)]] + [[intel::reqd_work_group_size(64)]] void + operator()() const {} +}; + +struct TRIFuncObjGood6 { + [[intel::reqd_work_group_size(64)]] + [[intel::num_simd_work_items(4)]] void + operator()() const {} +}; + +struct TRIFuncObjGood7 { + [[intel::num_simd_work_items(4)]] + [[intel::reqd_work_group_size(64, 64)]] void + operator()() const {} +}; + +struct TRIFuncObjGood8 { + [[intel::reqd_work_group_size(64, 64)]] + [[intel::num_simd_work_items(4)]] void + operator()() const {} +}; + int main() { q.submit([&](handler &h) { // CHECK-LABEL: FunctionDecl {{.*}}test_kernel1 @@ -60,16 +226,188 @@ int main() { h.single_task( []() { func_do_not_ignore(); }); + h.single_task(TRIFuncObjGood1()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel4 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood2()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel5 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood3()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel6 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood4()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel7 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood5()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel8 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood6()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel9 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood7()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel10 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + + h.single_task(TRIFuncObjGood8()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel11 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 64 + // CHECK-NEXT: IntegerLiteral{{.*}}64{{$}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 4 + // CHECK-NEXT: IntegerLiteral{{.*}}4{{$}} + #ifdef TRIGGER_ERROR [[intel::num_simd_work_items(0)]] int Var = 0; // expected-error{{'num_simd_work_items' attribute only applies to functions}} - h.single_task( - []() [[intel::num_simd_work_items(0)]]{}); // expected-error{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} + h.single_task( + []() [[intel::num_simd_work_items(0)]]{}); // expected-error{{'num_simd_work_items' attribute must be greater than 0}} + + h.single_task( + []() [[intel::num_simd_work_items(-42)]]{}); // expected-error{{'num_simd_work_items' attribute requires a non-negative integral compile time constant expression}} + + h.single_task(TRIFuncObjBad1()); + + h.single_task(TRIFuncObjBad2()); + + h.single_task(TRIFuncObjBad3()); + + h.single_task(TRIFuncObjBad4()); + + h.single_task(TRIFuncObjBad5()); + + h.single_task(TRIFuncObjBad6()); + + h.single_task(TRIFuncObjBad7()); + + h.single_task(TRIFuncObjBad8()); + + h.single_task(TRIFuncObjBad9()); + + h.single_task(TRIFuncObjBad10()); + + h.single_task(TRIFuncObjBad11()); + + h.single_task(TRIFuncObjBad12()); + + h.single_task(TRIFuncObjBad13()); + + h.single_task(TRIFuncObjBad14()); + + h.single_task(TRIFuncObjBad15()); + + h.single_task(TRIFuncObjBad16()); + + h.single_task(TRIFuncObjBad17()); - h.single_task( - []() [[intel::num_simd_work_items(-42)]]{}); // expected-error{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} + h.single_task(TRIFuncObjBad18()); - h.single_task( + h.single_task( []() [[intel::num_simd_work_items(1), intel::num_simd_work_items(2)]]{}); // expected-warning{{attribute 'num_simd_work_items' is already applied with different parameters}} #endif // TRIGGER_ERROR }); diff --git a/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp b/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp index 9d94d3a8e88ba..f308cb4f9e1d9 100644 --- a/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp +++ b/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp @@ -5,7 +5,6 @@ // Test that checks wrong function template instantiation and ensures that the type // is checked properly when instantiating from the template definition. template -// expected-error@+3{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} // expected-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'S'}} // expected-error@+1{{integral constant expression must have integral or unscoped enumeration type, not 'float'}} [[intel::num_simd_work_items(Ty{})]] void func() {} @@ -16,7 +15,6 @@ void test() { func(); //expected-note@+1{{in instantiation of function template specialization 'func' requested here}} func(); - //expected-note@+1{{in instantiation of function template specialization 'func' requested here}} func(); } @@ -35,7 +33,7 @@ constexpr int bar() { return 0; } template class KernelFunctor { public: - // expected-error@+1{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} + // expected-error@+1{{'num_simd_work_items' attribute requires a non-negative integral compile time constant expression}} [[intel::num_simd_work_items(SIZE)]] void operator()() {} }; @@ -57,7 +55,7 @@ int main() { // Test that checks template parameter support on function. template -// expected-error@+1{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} +// expected-error@+1{{'num_simd_work_items' attribute requires a non-negative integral compile time constant expression}} [[intel::num_simd_work_items(N)]] void func3() {} int check() {