Skip to content

Commit

Permalink
[PR41157][OpenCL] Prevent implicit init of local addr space var in C+…
Browse files Browse the repository at this point in the history
…+ mode.

Prevent adding initializers implicitly to variables declared in
local address space. This happens when they get converted into
global variables and therefore theoretically have to be default
initialized in C++.

Differential Revision: https://reviews.llvm.org/D59646

llvm-svn: 357684
  • Loading branch information
Anastasia Stulova committed Apr 4, 2019
1 parent e2622b3 commit 9b4c6b8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
6 changes: 5 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Expand Up @@ -11682,7 +11682,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
setFunctionHasBranchProtectedScope();
}
}

// In OpenCL, we can't initialize objects in the __local address space,
// even implicitly, so don't synthesize an implicit initializer.
if (getLangOpts().OpenCL &&
Var->getType().getAddressSpace() == LangAS::opencl_local)
return;
// C++03 [dcl.init]p9:
// If no initializer is specified for an object, and the
// object is of (possibly cv-qualified) non-POD class type (or
Expand Down
6 changes: 2 additions & 4 deletions clang/test/CodeGenOpenCLCXX/addrspace-of-this.cl
Expand Up @@ -150,15 +150,13 @@ __kernel void test__global() {
TEST(__local)

// COMMON-LABEL: _Z11test__localv
// EXPL: @__cxa_guard_acquire

// Test the address space of 'this' when invoking a constructor for an object in non-default address space
// EXPL: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
// Test that we don't initialize an object in local address space.
// EXPL-NOT: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))

// Test the address space of 'this' when invoking a method.
// COMMON: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))


// Test the address space of 'this' when invoking copy-constructor.
// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
// EXPL: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
Expand Down
20 changes: 20 additions & 0 deletions clang/test/CodeGenOpenCLCXX/local_addrspace_init.cl
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s

// Test that we don't initialize local address space objects.
//CHECK: @_ZZ4testvE1i = internal addrspace(3) global i32 undef
//CHECK: @_ZZ4testvE2ii = internal addrspace(3) global %class.C undef
class C {
int i;
};

kernel void test() {
__local int i;
__local C ii;
// FIXME: In OpenCL C we don't accept initializers for local
// address space variables. User defined initialization could
// make sense, but would it mean that all work items need to
// execute it? Potentially disallowing any initialization would
// make things easier and assingments can be used to set specific
// values. This rules should make it consistent with OpenCL C.
//__local C c();
}

0 comments on commit 9b4c6b8

Please sign in to comment.