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..45ca6bb59d509 100644 --- a/clang/test/CodeGenSYCL/address-space-swap.cpp +++ b/clang/test/CodeGenSYCL/address-space-swap.cpp @@ -1,35 +1,33 @@ // RUN: %clang -fsycl-device-only -S -emit-llvm %s -o - | FileCheck %s #include - 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 + // CHECK: %[[I:[a-zA-Z0-9_]+]] = alloca i32, align 4 - int* p1 = &foo; - int* p2 = &i; -// CHECK: %[[P1:[a-zA-Z0-9_]+]] = alloca i32 addrspace(4)*, align 8 -// CHECK: %[[P2:[a-zA-Z0-9_]+]] = alloca i32 addrspace(4)*, align 8 -// CHECK: %[[P1GEN:[a-zA-Z0-9_]+]] = addrspacecast i32 addrspace(4)** %[[P1]] to i32 addrspace(4)* addrspace(4)* -// CHECK: %[[P2GEN:[a-zA-Z0-9_]+]] = addrspacecast i32 addrspace(4)** %[[P2]] to i32 addrspace(4)* addrspace(4)* + int *p1 = &foo; + int *p2 = &i; + // CHECK: %[[P1:[a-zA-Z0-9_]+]] = alloca i32 addrspace(4)*, align 8 + // CHECK: %[[P2:[a-zA-Z0-9_]+]] = alloca i32 addrspace(4)*, align 8 + // CHECK: %[[P1GEN:[a-zA-Z0-9_]+]] = addrspacecast i32 addrspace(4)** %[[P1]] to i32 addrspace(4)* addrspace(4)* + // CHECK: %[[P2GEN:[a-zA-Z0-9_]+]] = addrspacecast i32 addrspace(4)** %[[P2]] to i32 addrspace(4)* addrspace(4)* std::swap(p1, p2); -// CHECK: call spir_func void @_ZSt4swap{{.*}}(i32 addrspace(4)* addrspace(4)* dereferenceable(8) %[[P1GEN]], i32 addrspace(4)* addrspace(4)* dereferenceable(8) %[[P2GEN]]) + // 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]]) } - template __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { kernelFunc(); } - int main() { kernel_single_task([]() { test(); }); return 0; diff --git a/clang/test/CodeGenSYCL/intel-fpga-local.cpp b/clang/test/CodeGenSYCL/intel-fpga-local.cpp index 53bbe783489d9..cad71abf6e362 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-local.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-local.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -fsycl-is-device -emit-llvm %s -o - | FileCheck %s -check-prefixes CHECK-DEVICE,CHECK-BOTH // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefixes CHECK-HOST,CHECK-BOTH +// CHECK-BOTH: @_ZZ15attrs_on_staticvE15static_numbanks = internal{{.*}}constant i32 20, align 4 // CHECK-DEVICE: [[ANN_numbanks_4:@.str]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}{numbanks:4} +// CHECK-BOTH: @_ZZ15attrs_on_staticvE15static_annotate = internal{{.*}}constant i32 30, align 4 // CHECK-BOTH: [[ANN_annotate:@.str[.0-9]*]] = {{.*}}foobar // CHECK-DEVICE: [[ANN_register:@.str.[0-9]*]] = {{.*}}{register:1} // CHECK-DEVICE: [[ANN_memory_default:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4} @@ -25,24 +27,17 @@ // 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: [[ANN_numbanks_4]]{{.*}} i32 39 // 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 40 // 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..62f5719551f9c --- /dev/null +++ b/clang/test/SemaSYCL/sycl-device-const-static.cpp @@ -0,0 +1,29 @@ +// 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 s1; + const static int cs = 0; + constexpr static int ces = 0; +} + +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 s2; + 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 s3; + }); + + return 0; +}