From 8b5af6812a184d4a680a483ea9e51d7df4ca27ad Mon Sep 17 00:00:00 2001 From: Aleksander Fadeev Date: Fri, 7 Feb 2020 14:07:59 +0300 Subject: [PATCH] Adding the error, that forbid declaration of static variable inside kernel, ifthe variable is not const. Signed-off-by: Aleksander Fadeev --- clang/lib/Sema/SemaDecl.cpp | 7 +++++ .../CodeGenSYCL/address-space-of-returns.cpp | 7 ++--- clang/test/CodeGenSYCL/address-space-swap.cpp | 9 ++++--- clang/test/CodeGenSYCL/intel-fpga-local.cpp | 16 ++++------- .../SemaSYCL/sycl-device-const-static.cpp | 27 +++++++++++++++++++ 5 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 clang/test/SemaSYCL/sycl-device-const-static.cpp diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 45cfc8d137588..d253c5073937b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6945,6 +6945,13 @@ NamedDecl *Sema::ActOnVariableDeclarator( NewVD->setTSCSpec(TSCS); } + // Static variables declared inside SYCL device code must be const or + // constexpr + if (getLangOpts().SYCLIsDevice && SCSpec == DeclSpec::SCS_static && + !R.isConstant(Context)) + SYCLDiagIfDeviceCode(D.getIdentifierLoc(), diag::err_sycl_restrict) + << Sema::KernelNonConstStaticDataVariable; + switch (D.getDeclSpec().getConstexprSpecifier()) { case CSK_unspecified: break; diff --git a/clang/test/CodeGenSYCL/address-space-of-returns.cpp b/clang/test/CodeGenSYCL/address-space-of-returns.cpp index bc65a50b84b7c..7f83376a75bb4 100644 --- a/clang/test/CodeGenSYCL/address-space-of-returns.cpp +++ b/clang/test/CodeGenSYCL/address-space-of-returns.cpp @@ -10,13 +10,14 @@ const char *ret_char() { // CHECK: ret i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0) to i8 addrspace(4)*) const char *ret_arr() { - static char Arr[42]; + const static char Arr[36] = "Carrots, cabbage, radish, potatoes!"; return Arr; } -// CHECK: ret i8 addrspace(4)* getelementptr inbounds ([42 x i8], [42 x i8] addrspace(4)* addrspacecast ([42 x i8] addrspace(1)* @{{.*}}ret_arr{{.*}}Arr to [42 x i8] addrspace(4)*), i64 0, i64 0) + +// CHECK: ret i8 addrspace(4)* getelementptr inbounds ([36 x i8], [36 x i8] addrspace(4)* addrspacecast ([36 x i8] addrspace(1)* @{{.*}}ret_arr{{.*}}Arr to [36 x i8] addrspace(4)*), i64 0, i64 0) const char &ret_ref() { - static char a = 'A'; + const static char a = 'A'; return a; } // CHECK: ret i8 addrspace(4)* addrspacecast (i8 addrspace(1)* @{{.*}}ret_ref{{.*}} to i8 addrspace(4)*) diff --git a/clang/test/CodeGenSYCL/address-space-swap.cpp b/clang/test/CodeGenSYCL/address-space-swap.cpp index 985fbd3f1a958..231d9c7b68789 100644 --- a/clang/test/CodeGenSYCL/address-space-swap.cpp +++ b/clang/test/CodeGenSYCL/address-space-swap.cpp @@ -3,8 +3,8 @@ void test() { - static int foo = 0x42; -// CHECK: @[[FOO:[a-zA-Z0-9_]+]] = internal addrspace(1) global i32 66, align 4 + int foo = 0x42; +// CHECK: %[[FOO:[a-zA-Z0-9_]+]] = alloca i32, align 4 int i = 43; // CHECK: %[[I:[a-zA-Z0-9_]+]] = alloca i32, align 4 @@ -19,8 +19,9 @@ void test() { // CHECK: call spir_func void @_ZSt4swap{{.*}}(i32 addrspace(4)* addrspace(4)* dereferenceable(8) %[[P1GEN]], i32 addrspace(4)* addrspace(4)* dereferenceable(8) %[[P2GEN]]) std::swap(foo, i); -// CHECK: %[[ICAST:[a-zA-Z0-9_]+]] = addrspacecast i32* %[[I]] to i32 addrspace(4)* -// CHECK: call spir_func void @_ZSt4swap{{.*}}(i32 addrspace(4)* dereferenceable(4) addrspacecast (i32 addrspace(1)* @[[FOO]] to i32 addrspace(4)*), i32 addrspace(4)* dereferenceable(4) %[[ICAST]]) +// CHECK: %[[FOOCAST:[a-zA-Z0-9_]+]] = addrspacecast i32* %[[FOO]] to i32 addrspace(4)* +// CHECK: %[[ICAST:[a-zA-Z0-9_]+]] = addrspacecast i32* %[[I]] to i32 addrspace(4)* +// CHECK: call spir_func void @_ZSt4swap{{.*}}(i32 addrspace(4)* dereferenceable(4) %[[FOOCAST]], i32 addrspace(4)* dereferenceable(4) %[[ICAST]]) } diff --git a/clang/test/CodeGenSYCL/intel-fpga-local.cpp b/clang/test/CodeGenSYCL/intel-fpga-local.cpp index 53bbe783489d9..4c7a22eaad91e 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-local.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-local.cpp @@ -25,24 +25,18 @@ // CHECK-BOTH: @llvm.global.annotations // CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_numbanks to i8 addrspace(1)*) to i8*) -// CHECK-DEVICE-SAME: [[ANN_numbanks_4]]{{.*}}i32 38 -// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_annotate to i8 addrspace(1)*) to i8*) +// CHECK-DEVICE-SAME: [[ANN_numbanks_4]], i32 0 +// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_annotate to i8 addrspace(1)*) to i8*) // CHECK-HOST-SAME: { i8* bitcast (i32* @_ZZ15attrs_on_staticvE15static_annotate to i8*) -// CHECK-BOTH-SAME: [[ANN_annotate]]{{.*}}i32 42 +// CHECK-BOTH-SAME: [[ANN_annotate]], i32 0 // CHECK-HOST-NOT: llvm.var.annotation // CHECK-HOST-NOT: llvm.ptr.annotation void attrs_on_static() { int a = 42; - static int static_numbanks [[intelfpga::numbanks(4)]]; - // CHECK-BOTH: load{{.*}}static_numbanks - // CHECK-BOTH: store{{.*}}static_numbanks - static_numbanks = static_numbanks + a; - static int static_annotate [[clang::annotate("foobar")]]; - // CHECK-BOTH: load{{.*}}static_annotate - // CHECK-BOTH: store{{.*}}static_annotate - static_annotate = static_annotate + a; + const static int static_numbanks [[intelfpga::numbanks(4)]] = 20; + const static int static_annotate [[clang::annotate("foobar")]] = 30; } void attrs_on_var() { diff --git a/clang/test/SemaSYCL/sycl-device-const-static.cpp b/clang/test/SemaSYCL/sycl-device-const-static.cpp new file mode 100644 index 0000000000000..aef3b5d139870 --- /dev/null +++ b/clang/test/SemaSYCL/sycl-device-const-static.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -fsycl-is-device %s + +void usage() { + // expected-error@+1{{SYCL kernel cannot use a non-const static data variable}} + static int m; +} + +template +__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { + // expected-error@+1{{SYCL kernel cannot use a non-const static data variable}} + static int z; + // expected-note-re@+2{{called by 'kernel_single_task}} + // expected-note-re@+1{{called by 'kernel_single_task}} + kernelFunc(); +} + +int main() { + static int n; + kernel_single_task([]() { + // expected-note@+1{{called by 'operator()'}} + usage(); + // expected-error@+1{{SYCL kernel cannot use a non-const static data variable}} + static int g; + }); + + return 0; +}