Skip to content

Commit

Permalink
[SYCL] Forbid declaration of non-const static variables inside kernels (
Browse files Browse the repository at this point in the history
#1141)

Signed-off-by: Aleksander Fadeev <aleksander.fadeev@intel.com>
  • Loading branch information
fadeeval authored Feb 20, 2020
1 parent 59f39b2 commit 7743e86
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 29 deletions.
7 changes: 7 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7057,6 +7057,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;
Expand Down
7 changes: 4 additions & 3 deletions clang/test/CodeGenSYCL/address-space-of-returns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)*)
Expand Down
28 changes: 13 additions & 15 deletions clang/test/CodeGenSYCL/address-space-swap.cpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
// RUN: %clang -fsycl-device-only -S -emit-llvm %s -o - | FileCheck %s
#include <algorithm>


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 <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
kernelFunc();
}


int main() {
kernel_single_task<class fake_kernel>([]() { test(); });
return 0;
Expand Down
17 changes: 6 additions & 11 deletions clang/test/CodeGenSYCL/intel-fpga-local.cpp
Original file line number Diff line number Diff line change
@@ -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}
Expand All @@ -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() {
Expand Down
29 changes: 29 additions & 0 deletions clang/test/SemaSYCL/sycl-device-const-static.cpp
Original file line number Diff line number Diff line change
@@ -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 <typename Name, typename Func>
__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<fake_kernel, (lambda at {{.*}})>}}
// expected-note-re@+1{{called by 'kernel_single_task<fake_kernel, (lambda at {{.*}})>}}
kernelFunc();
}

int main() {
static int s2;
kernel_single_task<class fake_kernel>([]() {
// 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;
}

0 comments on commit 7743e86

Please sign in to comment.