diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fc8ed4ed3eb33..53a95c1c8c365 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1293,7 +1293,7 @@ def SYCLIntelMaxWorkGroupSize : InheritableAttr { def SYCLIntelMaxGlobalWorkDim : InheritableAttr { let Spellings = [CXX11<"intelfpga","max_global_work_dim">, CXX11<"intel","max_global_work_dim">]; - let Args = [UnsignedArgument<"Number">]; + let Args = [ExprArgument<"Value">]; let LangOpts = [SYCLIsDevice, SYCLIsHost]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [SYCLIntelMaxGlobalWorkDimAttrDocs]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5b23e35f58100..a0eaf8d7bdb3c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11134,8 +11134,6 @@ def err_sycl_function_attribute_mismatch : Error< "SYCL kernel without %0 attribute can't call a function with this attribute">; def err_sycl_x_y_z_arguments_must_be_one : Error< "%0 X-, Y- and Z- sizes must be 1 when %1 attribute is used with value 0">; -def err_intel_attribute_argument_is_not_in_range: Error< - "The value of %0 attribute must be in range from 0 to 3">; def warn_boolean_attribute_argument_is_not_valid: Warning< "The value of %0 attribute should be 0 or 1. Adjusted to 1">, InGroup; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 55b646e370d89..cc49a9994b21b 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12963,10 +12963,25 @@ void Sema::addIntelSYCLSingleArgFunctionAttr(Decl *D, return; } int32_t ArgInt = ArgVal->getSExtValue(); - if (ArgInt <= 0) { - Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) - << CI.getAttrName() << /*positive*/ 0; - return; + if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelNumSimdWorkItems || + CI.getParsedKind() == ParsedAttr::AT_IntelReqdSubGroupSize) { + if (ArgInt <= 0) { + Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) + << CI.getAttrName() << /*positive*/ 0; + return; + } + } + if (CI.getParsedKind() == ParsedAttr::AT_SYCLIntelMaxGlobalWorkDim) { + if (ArgInt < 0) { + Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) + << CI.getAttrName() << /*non-negative*/ 1; + return; + } + if (ArgInt > 3) { + Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range) + << CI.getAttrName() << 0 << 3 << E->getSourceRange(); + return; + } } } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index feb16155b0032..f94a6a6973b6a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -682,8 +682,12 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, if (const SYCLIntelMaxGlobalWorkDimAttr *A = FD->getAttr()) { - llvm::Metadata *AttrMDArgs[] = { - llvm::ConstantAsMetadata::get(Builder.getInt32(A->getNumber()))}; + llvm::LLVMContext &Context = getLLVMContext(); + Optional ArgVal = + A->getValue()->getIntegerConstantExpr(FD->getASTContext()); + assert(ArgVal.hasValue() && "Not an integer constant expression"); + llvm::Metadata *AttrMDArgs[] = {llvm::ConstantAsMetadata::get( + Builder.getInt32(ArgVal->getSExtValue()))}; Fn->setMetadata("max_global_work_dim", llvm::MDNode::get(Context, AttrMDArgs)); } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index a6be20941bb61..d1e5855ff2e0b 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2925,10 +2925,13 @@ static bool checkWorkGroupSizeValues(Sema &S, Decl *D, const ParsedAttr &Attr, return Result; } - if (const auto *A = D->getAttr()) - if (A->getNumber() == 0) + if (const auto *A = D->getAttr()) { + int64_t AttrValue = + A->getValue()->getIntegerConstantExpr(S.Context)->getSExtValue(); + if (AttrValue == 0) Result &= checkZeroDim(A, WGSize[0], WGSize[1], WGSize[2], /*ReverseAttrs=*/true); + } if (const auto *A = D->getAttr()) { if (!(WGSize[0] <= A->getXDim() && WGSize[1] <= A->getYDim() && @@ -3087,25 +3090,14 @@ static void handleMaxGlobalWorkDimAttr(Sema &S, Decl *D, if (D->isInvalidDecl()) return; - uint32_t MaxGlobalWorkDim; - const Expr *E = Attr.getArgAsExpr(0); - if (!checkUInt32Argument(S, Attr, E, MaxGlobalWorkDim, 0, - /*StrictlyUnsigned=*/true)) - return; + Expr *E = Attr.getArgAsExpr(0); - if (MaxGlobalWorkDim > 3) { - S.Diag(Attr.getLoc(), diag::err_intel_attribute_argument_is_not_in_range) - << Attr; + uint32_t WGSize[3] = {1, 1, 1}; + if (!checkWorkGroupSizeValues(S, D, Attr, WGSize)) { + D->setInvalidDecl(); return; } - if (MaxGlobalWorkDim == 0) { - uint32_t WGSize[3] = {1, 1, 1}; - if (!checkWorkGroupSizeValues(S, D, Attr, WGSize)) { - D->setInvalidDecl(); - return; - } - } if (D->getAttr()) S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr; @@ -3113,8 +3105,8 @@ static void handleMaxGlobalWorkDimAttr(Sema &S, Decl *D, S.Diag(Attr.getLoc(), diag::note_spelling_suggestion) << "'intel::max_global_work_dim'"; - D->addAttr(::new (S.Context) SYCLIntelMaxGlobalWorkDimAttr( - S.Context, Attr, MaxGlobalWorkDim)); + S.addIntelSYCLSingleArgFunctionAttr(D, Attr, + E); } static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) { diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 3ce8d68cfad1b..5130bad1f7b5c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -769,6 +769,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, *this, TemplateArgs, SYCLIntelSchedulerTargetFmaxMhz, New); continue; } + if (const auto *SYCLIntelMaxGlobalWorkDim = + dyn_cast(TmplAttr)) { + instantiateIntelSYCLFunctionAttr( + *this, TemplateArgs, SYCLIntelMaxGlobalWorkDim, New); + continue; + } // Existing DLL attribute on the instantiation takes precedence. if (TmplAttr->getKind() == attr::DLLExport || TmplAttr->getKind() == attr::DLLImport) { diff --git a/clang/test/CodeGenSYCL/intel-max-global-work-dim.cpp b/clang/test/CodeGenSYCL/intel-max-global-work-dim.cpp index 673f45d511502..cde0613a8971b 100644 --- a/clang/test/CodeGenSYCL/intel-max-global-work-dim.cpp +++ b/clang/test/CodeGenSYCL/intel-max-global-work-dim.cpp @@ -1,24 +1,37 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; class Foo { public: [[intel::max_global_work_dim(1)]] void operator()() const {} }; -template -__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { - kernelFunc(); -} +template +class Functor { +public: + [[intel::max_global_work_dim(SIZE)]] void operator()() const {} +}; + +int main() { + q.submit([&](handler &h) { + Foo boo; + h.single_task(boo); -void bar() { - Foo boo; - kernel(boo); + h.single_task( + []() [[intel::max_global_work_dim(2)]]{}); - kernel( - []() [[intel::max_global_work_dim(2)]]{}); + Functor<2> f; + h.single_task(f); + }); + return 0; } -// CHECK: define spir_kernel void @{{.*}}kernel_name1() {{.*}} !max_global_work_dim ![[NUM1:[0-9]+]] -// CHECK: define spir_kernel void @{{.*}}kernel_name2() {{.*}} !max_global_work_dim ![[NUM8:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name1"() #0 {{.*}} !max_global_work_dim ![[NUM1:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name2"() #0 {{.*}} !max_global_work_dim ![[NUM2:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name3"() #0 {{.*}} !max_global_work_dim ![[NUM2]] // CHECK: ![[NUM1]] = !{i32 1} -// CHECK: ![[NUM8]] = !{i32 2} +// CHECK: ![[NUM2]] = !{i32 2} diff --git a/clang/test/CodeGenSYCL/num-simd-work-items.cpp b/clang/test/CodeGenSYCL/num-simd-work-items.cpp index 3173971cd0ce6..d83142c29eace 100644 --- a/clang/test/CodeGenSYCL/num-simd-work-items.cpp +++ b/clang/test/CodeGenSYCL/num-simd-work-items.cpp @@ -1,4 +1,9 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; class Foo { public: @@ -11,25 +16,23 @@ class Functor { [[intel::num_simd_work_items(SIZE)]] void operator()() const {} }; -template -__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { - kernelFunc(); -} - -void bar() { - Foo boo; - kernel(boo); +int main() { + q.submit([&](handler &h) { + Foo boo; + h.single_task(boo); - kernel( - []() [[intel::num_simd_work_items(42)]]{}); + h.single_task( + []() [[intel::num_simd_work_items(42)]]{}); - Functor<2> f; - kernel(f); + Functor<2> f; + h.single_task(f); + }); + return 0; } -// CHECK: define spir_kernel void @{{.*}}kernel_name1() {{.*}} !num_simd_work_items ![[NUM1:[0-9]+]] -// CHECK: define spir_kernel void @{{.*}}kernel_name2() {{.*}} !num_simd_work_items ![[NUM42:[0-9]+]] -// CHECK: define spir_kernel void @{{.*}}kernel_name3() {{.*}} !num_simd_work_items ![[NUM2:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name1"() #0 {{.*}} !num_simd_work_items ![[NUM1:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name2"() #0 {{.*}} !num_simd_work_items ![[NUM42:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name3"() #0 {{.*}} !num_simd_work_items ![[NUM2:[0-9]+]] // CHECK: ![[NUM1]] = !{i32 1} // CHECK: ![[NUM42]] = !{i32 42} // CHECK: ![[NUM2]] = !{i32 2} diff --git a/clang/test/CodeGenSYCL/reqd-sub-group-size.cpp b/clang/test/CodeGenSYCL/reqd-sub-group-size.cpp index eb13abbe1948e..27bcfeef79ac2 100644 --- a/clang/test/CodeGenSYCL/reqd-sub-group-size.cpp +++ b/clang/test/CodeGenSYCL/reqd-sub-group-size.cpp @@ -1,4 +1,9 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -disable-llvm-passes -triple spir64-unknown-unknown-sycldevice -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -disable-llvm-passes -triple spir64-unknown-unknown-sycldevice -emit-llvm -o - %s | FileCheck %s + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; class Functor16 { public: @@ -7,7 +12,7 @@ class Functor16 { [[intel::reqd_sub_group_size(8)]] void foo() {} -class Functor { +class Functor8 { public: void operator()() const { foo(); @@ -15,34 +20,32 @@ class Functor { }; template -class Functor5 { +class Functor2 { public: [[intel::reqd_sub_group_size(SIZE)]] void operator()() const {} }; -template -__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { - kernelFunc(); -} - -void bar() { - Functor16 f16; - kernel(f16); +int main() { + q.submit([&](handler &h) { + Functor16 f16; + h.single_task(f16); - Functor f; - kernel(f); + Functor8 f8; + h.single_task(f8); - kernel( - []() [[intel::reqd_sub_group_size(4)]]{}); + h.single_task( + []() [[intel::reqd_sub_group_size(4)]]{}); - Functor5<2> f5; - kernel(f5); + Functor2<2> f2; + h.single_task(f2); + }); + return 0; } -// CHECK: define spir_kernel void @{{.*}}kernel_name1() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE16:[0-9]+]] -// CHECK: define spir_kernel void @{{.*}}kernel_name2() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE8:[0-9]+]] -// CHECK: define spir_kernel void @{{.*}}kernel_name3() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE4:[0-9]+]] -// CHECK: define spir_kernel void @{{.*}}kernel_name4() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE2:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name1"() #0 {{.*}} !intel_reqd_sub_group_size ![[SGSIZE16:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name2"() #0 {{.*}} !intel_reqd_sub_group_size ![[SGSIZE8:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name3"() #0 {{.*}} !intel_reqd_sub_group_size ![[SGSIZE4:[0-9]+]] +// CHECK: define spir_kernel void @{{.*}}kernel_name4"() #0 {{.*}} !intel_reqd_sub_group_size ![[SGSIZE2:[0-9]+]] // CHECK: ![[SGSIZE16]] = !{i32 16} // CHECK: ![[SGSIZE8]] = !{i32 8} // CHECK: ![[SGSIZE4]] = !{i32 4} diff --git a/clang/test/SemaSYCL/intel-max-global-work-dim-device.cpp b/clang/test/SemaSYCL/intel-max-global-work-dim-device.cpp new file mode 100644 index 0000000000000..0f28cbd9911e5 --- /dev/null +++ b/clang/test/SemaSYCL/intel-max-global-work-dim-device.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 %s -fsyntax-only -fsycl -fsycl-is-device -internal-isystem %S/Inputs -Wno-sycl-2017-compat -triple spir64 -DTRIGGER_ERROR -verify +// RUN: %clang_cc1 %s -fsyntax-only -ast-dump -fsycl -fsycl-is-device -internal-isystem %S/Inputs -Wno-sycl-2017-compat -triple spir64 | FileCheck %s + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; + +#ifndef __SYCL_DEVICE_ONLY__ +struct FuncObj { + [[intel::max_global_work_dim(1)]] // expected-no-diagnostics + void + operator()() const {} +}; + +void foo() { + q.submit([&](handler &h) { + h.single_task(FuncObj()); + }); +} + +#else // __SYCL_DEVICE_ONLY__ + +[[intel::max_global_work_dim(2)]] void func_do_not_ignore() {} + +struct FuncObj { + [[intel::max_global_work_dim(1)]] void operator()() const {} +}; + +struct Func { + // expected-warning@+2 {{attribute 'intelfpga::max_global_work_dim' is deprecated}} + // expected-note@+1 {{did you mean to use 'intel::max_global_work_dim' instead?}} + [[intelfpga::max_global_work_dim(2)]] void operator()() const {} +}; + +struct TRIFuncObjGood1 { + [[intel::max_global_work_dim(0)]] + [[intel::max_work_group_size(1, 1, 1)]] + [[cl::reqd_work_group_size(1, 1, 1)]] void + operator()() const {} +}; + +struct TRIFuncObjGood2 { + [[intel::max_global_work_dim(3)]] + [[intel::max_work_group_size(8, 1, 1)]] + [[cl::reqd_work_group_size(4, 1, 1)]] void + operator()() const {} +}; + +#ifdef TRIGGER_ERROR +struct TRIFuncObjBad { + [[intel::max_global_work_dim(0)]] + [[intel::max_work_group_size(8, 8, 8)]] // expected-error{{'max_work_group_size' X-, Y- and Z- sizes must be 1 when 'max_global_work_dim' attribute is used with value 0}} + [[cl::reqd_work_group_size(4, 4, 4)]] // expected-error{{'reqd_work_group_size' X-, Y- and Z- sizes must be 1 when 'max_global_work_dim' attribute is used with value 0}} + void + operator()() const {} +}; +#endif // TRIGGER_ERROR + +int main() { + q.submit([&](handler &h) { + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel1 + // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + h.single_task(FuncObj()); + + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel2 + // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}2{{$}} + // expected-warning@+3 {{attribute 'intelfpga::max_global_work_dim' is deprecated}} + // expected-note@+2 {{did you mean to use 'intel::max_global_work_dim' instead?}} + h.single_task( + []() [[intelfpga::max_global_work_dim(2)]]{}); + + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel3 + // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}2{{$}} + h.single_task( + []() { func_do_not_ignore(); }); + + h.single_task(TRIFuncObjGood1()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel4 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} 1 1 1 + // CHECK: SYCLIntelMaxWorkGroupSizeAttr {{.*}} 1 1 1 + // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}0{{$}} + + h.single_task(TRIFuncObjGood2()); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel5 + // CHECK: ReqdWorkGroupSizeAttr {{.*}} 1 1 4 + // CHECK: SYCLIntelMaxWorkGroupSizeAttr {{.*}} 1 1 8 + // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}3{{$}} +#ifdef TRIGGER_ERROR + [[intel::max_global_work_dim(1)]] int Var = 0; // expected-error{{'max_global_work_dim' attribute only applies to functions}} + + h.single_task( + []() [[intel::max_global_work_dim(-8)]]{}); // expected-error{{'max_global_work_dim' attribute requires a non-negative integral compile time constant expression}} + + h.single_task( + []() [[intel::max_global_work_dim(3), + intel::max_global_work_dim(2)]]{}); // expected-warning{{attribute 'max_global_work_dim' is already applied with different parameters}} + + h.single_task(TRIFuncObjBad()); + + h.single_task( + []() [[intel::max_global_work_dim(4)]]{}); // expected-error{{'max_global_work_dim' attribute requires integer constant between 0 and 3 inclusive}} +#endif // TRIGGER_ERROR + }); + return 0; +} +#endif // __SYCL_DEVICE_ONLY__ diff --git a/clang/test/SemaSYCL/intel-max-global-work-dim-host.cpp b/clang/test/SemaSYCL/intel-max-global-work-dim-host.cpp new file mode 100644 index 0000000000000..433e5afc436e9 --- /dev/null +++ b/clang/test/SemaSYCL/intel-max-global-work-dim-host.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-host -Wno-sycl-2017-compat -fsyntax-only -verify %s +// expected-no-diagnostics + +[[intel::max_global_work_dim(2)]] void func_do_not_ignore() {} + +struct FuncObj { + [[intel::max_global_work_dim(1)]] void operator()() const {} +}; diff --git a/clang/test/SemaSYCL/intel-max-global-work-dim.cpp b/clang/test/SemaSYCL/intel-max-global-work-dim.cpp deleted file mode 100644 index b55994082342f..0000000000000 --- a/clang/test/SemaSYCL/intel-max-global-work-dim.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// RUN: %clang_cc1 %s -fsyntax-only -fsycl -fsycl-is-device -Wno-sycl-2017-compat -triple spir64 -DTRIGGER_ERROR -verify -// RUN: %clang_cc1 %s -fsyntax-only -ast-dump -fsycl -fsycl-is-device -Wno-sycl-2017-compat -triple spir64 | FileCheck %s -// RUN: %clang_cc1 -fsycl -fsycl-is-host -Wno-sycl-2017-compat -fsyntax-only -verify %s - -#ifndef __SYCL_DEVICE_ONLY__ -struct FuncObj { - [[intel::max_global_work_dim(1)]] // expected-no-diagnostics - void - operator()() const {} -}; - -template -void kernel(const Func &kernelFunc) { - kernelFunc(); -} - -void foo() { - kernel( - FuncObj()); -} - -#else // __SYCL_DEVICE_ONLY__ - -[[intel::max_global_work_dim(2)]] void func_do_not_ignore() {} - -struct FuncObj { - [[intel::max_global_work_dim(1)]] void operator()() const {} -}; - -struct Func { - // expected-warning@+2 {{attribute 'intelfpga::max_global_work_dim' is deprecated}} - // expected-note@+1 {{did you mean to use 'intel::max_global_work_dim' instead?}} - [[intelfpga::max_global_work_dim(2)]] void operator()() const {} -}; - -struct TRIFuncObjGood1 { - [[intel::max_global_work_dim(0)]] - [[intel::max_work_group_size(1, 1, 1)]] - [[cl::reqd_work_group_size(1, 1, 1)]] void - operator()() const {} -}; - -struct TRIFuncObjGood2 { - [[intel::max_global_work_dim(3)]] - [[intel::max_work_group_size(8, 1, 1)]] - [[cl::reqd_work_group_size(4, 1, 1)]] void - operator()() const {} -}; - -#ifdef TRIGGER_ERROR -struct TRIFuncObjBad { - [[intel::max_global_work_dim(0)]] - [[intel::max_work_group_size(8, 8, 8)]] // expected-error{{'max_work_group_size' X-, Y- and Z- sizes must be 1 when 'max_global_work_dim' attribute is used with value 0}} - [[cl::reqd_work_group_size(4, 4, 4)]] // expected-error{{'reqd_work_group_size' X-, Y- and Z- sizes must be 1 when 'max_global_work_dim' attribute is used with value 0}} - void - operator()() const {} -}; -#endif // TRIGGER_ERROR - -template -__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { - kernelFunc(); -} - -int main() { - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel1 - // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} 1 - kernel( - FuncObj()); - - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel2 - // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} 2 - // expected-warning@+3 {{attribute 'intelfpga::max_global_work_dim' is deprecated}} - // expected-note@+2 {{did you mean to use 'intel::max_global_work_dim' instead?}} - kernel( - []() [[intelfpga::max_global_work_dim(2)]]{}); - - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel3 - // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} - kernel( - []() { func_do_not_ignore(); }); - - kernel( - TRIFuncObjGood1()); - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel4 - // CHECK: ReqdWorkGroupSizeAttr {{.*}} 1 1 1 - // CHECK: SYCLIntelMaxWorkGroupSizeAttr {{.*}} 1 1 1 - // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} 0 - - kernel( - TRIFuncObjGood2()); - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel5 - // CHECK: ReqdWorkGroupSizeAttr {{.*}} 1 1 4 - // CHECK: SYCLIntelMaxWorkGroupSizeAttr {{.*}} 1 1 8 - // CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} 3 - -#ifdef TRIGGER_ERROR - [[intel::max_global_work_dim(1)]] int Var = 0; // expected-error{{'max_global_work_dim' attribute only applies to functions}} - - kernel( - []() [[intel::max_global_work_dim(-8)]]{}); // expected-error{{'max_global_work_dim' attribute requires a non-negative integral compile time constant expression}} - - kernel( - []() [[intel::max_global_work_dim(3), - intel::max_global_work_dim(2)]]{}); // expected-warning{{attribute 'max_global_work_dim' is already applied with different parameters}} - - kernel( - TRIFuncObjBad()); - - kernel( - []() [[intel::max_global_work_dim(4)]]{}); // expected-error{{The value of 'max_global_work_dim' attribute must be in range from 0 to 3}} - -#endif // TRIGGER_ERROR -} -#endif // __SYCL_DEVICE_ONLY__ diff --git a/clang/test/SemaSYCL/num_simd_work_items_device.cpp b/clang/test/SemaSYCL/num_simd_work_items_device.cpp index b48d6b8d322bc..7531feb7add27 100644 --- a/clang/test/SemaSYCL/num_simd_work_items_device.cpp +++ b/clang/test/SemaSYCL/num_simd_work_items_device.cpp @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -triple spir64 -fsyntax-only -Wno-sycl-2017-compat -DTRIGGER_ERROR -verify -// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -triple spir64 -fsyntax-only -Wno-sycl-2017-compat -ast-dump | FileCheck %s +// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -internal-isystem %S/Inputs -triple spir64 -fsyntax-only -Wno-sycl-2017-compat -DTRIGGER_ERROR -verify +// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -internal-isystem %S/Inputs -triple spir64 -fsyntax-only -Wno-sycl-2017-compat -ast-dump | FileCheck %s + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; #ifndef __SYCL_DEVICE_ONLY__ struct FuncObj { @@ -15,14 +20,10 @@ struct FuncObj { operator()() const {} }; -template -void kernel(const Func &kernelFunc) { - kernelFunc(); -} - void foo() { - kernel( - FuncObj()); + q.submit([&](handler &h) { + h.single_task(FuncObj()); + }); } #else // __SYCL_DEVICE_ONLY__ @@ -32,43 +33,40 @@ struct FuncObj { [[intel::num_simd_work_items(42)]] void operator()() const {} }; -template -__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { - kernelFunc(); -} - int main() { - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel1 - // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} - // CHECK-NEXT: IntegerLiteral{{.*}}42{{$}} - kernel( - FuncObj()); + q.submit([&](handler &h) { + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel1 + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}42{{$}} + h.single_task(FuncObj()); - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel2 - // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} - // CHECK-NEXT: IntegerLiteral{{.*}}8{{$}} - // expected-warning@+3 {{attribute 'intelfpga::num_simd_work_items' is deprecated}} - // expected-note@+2 {{did you mean to use 'intel::num_simd_work_items' instead?}} - kernel( - []() [[intelfpga::num_simd_work_items(8)]]{}); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel2 + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}8{{$}} + // expected-warning@+3 {{attribute 'intelfpga::num_simd_work_items' is deprecated}} + // expected-note@+2 {{did you mean to use 'intel::num_simd_work_items' instead?}} + h.single_task( + []() [[intelfpga::num_simd_work_items(8)]]{}); - // CHECK-LABEL: FunctionDecl {{.*}}test_kernel3 - // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} - // CHECK-NEXT: IntegerLiteral{{.*}}2{{$}} - kernel( - []() { func_do_not_ignore(); }); + // CHECK-LABEL: FunctionDecl {{.*}}test_kernel3 + // CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} + // CHECK-NEXT: IntegerLiteral{{.*}}2{{$}} + h.single_task( + []() { func_do_not_ignore(); }); #ifdef TRIGGER_ERROR - [[intel::num_simd_work_items(0)]] int Var = 0; // expected-error{{'num_simd_work_items' attribute only applies to functions}} + [[intel::num_simd_work_items(0)]] int Var = 0; // expected-error{{'num_simd_work_items' attribute only applies to functions}} - kernel( - []() [[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 requires a positive integral compile time constant expression}} - kernel( - []() [[intel::num_simd_work_items(-42)]]{}); // expected-error{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} + h.single_task( + []() [[intel::num_simd_work_items(-42)]]{}); // expected-error{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}} - kernel( - []() [[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}} + 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 + }); + return 0; } #endif // __SYCL_DEVICE_ONLY__ diff --git a/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp b/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp index d1dd59ea3be34..7fbc7c7333b0e 100644 --- a/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp +++ b/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsyntax-only -Wno-sycl-2017-compat -verify -DTRIGGER_ERROR %s -// RUN: %clang_cc1 -fsycl -fsycl-is-device -Wno-sycl-2017-compat -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -Wno-sycl-2017-compat -verify -DTRIGGER_ERROR %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -Wno-sycl-2017-compat -ast-dump %s | FileCheck %s + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; [[intel::reqd_sub_group_size(4)]] void foo() {} // expected-note {{conflicting attribute is here}} // expected-note@-1 {{conflicting attribute is here}} @@ -29,34 +34,32 @@ class Functor { } }; -template -__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) { - kernelFunc(); -} - -void bar() { - Functor16 f16; - kernel(f16); +int main() { + q.submit([&](handler &h) { + Functor16 f16; + h.single_task(f16); - Functor f; - kernel(f); + Functor f; + h.single_task(f); #ifdef TRIGGER_ERROR - Functor8 f8; - kernel(f8); + Functor8 f8; + h.single_task(f8); - kernel([]() { // expected-error {{conflicting attributes applied to a SYCL kernel}} - foo(); - baz(); - }); + h.single_task([]() { // expected-error {{conflicting attributes applied to a SYCL kernel}} + foo(); + baz(); + }); #endif - kernel([]() [[intel::reqd_sub_group_size(2)]]{}); - kernel([]() [[intel::reqd_sub_group_size(4)]] { foo(); }); - kernel([]() [[intel::reqd_sub_group_size(6)]]{}); + h.single_task([]() [[intel::reqd_sub_group_size(2)]]{}); + h.single_task([]() [[intel::reqd_sub_group_size(4)]] { foo(); }); + h.single_task([]() [[intel::reqd_sub_group_size(6)]]{}); - Functor4 f4; - kernel(f4); + Functor4 f4; + h.single_task(f4); + }); + return 0; } [[intel::reqd_sub_group_size(16)]] SYCL_EXTERNAL void B(); diff --git a/clang/test/SemaSYCL/sycl-device-intel-max-global-work-dim-template.cpp b/clang/test/SemaSYCL/sycl-device-intel-max-global-work-dim-template.cpp new file mode 100644 index 0000000000000..9b8600f99a76d --- /dev/null +++ b/clang/test/SemaSYCL/sycl-device-intel-max-global-work-dim-template.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsyntax-only -ast-dump -verify -pedantic %s | FileCheck %s + +// Test that checkes template parameter support for 'max_global_work_dim' attribute on sycl device. + +template +class KernelFunctor { +public: + // expected-error@+1{{'max_global_work_dim' attribute requires a non-negative integral compile time constant expression}} + [[intel::max_global_work_dim(SIZE)]] void operator()() {} +}; + +int main() { + //expected-note@+1{{in instantiation of template class 'KernelFunctor<-1>' requested here}} + KernelFunctor<-1>(); + // no error expected + KernelFunctor<2>(); +} + +// CHECK: ClassTemplateDecl {{.*}} {{.*}} KernelFunctor +// CHECK: ClassTemplateSpecializationDecl {{.*}} {{.*}} class KernelFunctor definition +// CHECK: CXXRecordDecl {{.*}} {{.*}} implicit class KernelFunctor +// CHECK: SYCLIntelMaxGlobalWorkDimAttr {{.*}} +// CHECK: SubstNonTypeTemplateParmExpr {{.*}} +// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} +// CHECK-NEXT: IntegerLiteral{{.*}}2{{$}}