[OpenCL] Add support of __opencl_c_program_scope_global_variables feature macro
Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D103191
This commit is contained in:
parent
f24335c69e
commit
05eb59e1d0
|
@ -67,7 +67,23 @@ static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
|
|||
|
||||
/// OpenCL supported extensions and optional core features
|
||||
class OpenCLOptions {
|
||||
|
||||
public:
|
||||
// OpenCL C v1.2 s6.5 - All program scope variables must be declared in the
|
||||
// __constant address space.
|
||||
// OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static
|
||||
// variables inside a function can also be declared in the global
|
||||
// address space.
|
||||
// OpenCL C v3.0 s6.7.1 - Variables at program scope or static or extern
|
||||
// variables inside functions can be declared in global address space if
|
||||
// the __opencl_c_program_scope_global_variables feature is supported
|
||||
// C++ for OpenCL inherits rule from OpenCL C v2.0.
|
||||
bool areProgramScopeVariablesSupported(const LangOptions &Opts) const {
|
||||
return Opts.OpenCLCPlusPlus || Opts.OpenCLVersion == 200 ||
|
||||
(Opts.OpenCLVersion == 300 &&
|
||||
isSupported("__opencl_c_program_scope_global_variables", Opts));
|
||||
}
|
||||
|
||||
struct OpenCLOptionInfo {
|
||||
// Does this option have pragma.
|
||||
bool WithPragma = false;
|
||||
|
|
|
@ -6424,7 +6424,11 @@ void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) {
|
|||
if (Type->isSamplerT() || Type->isVoidType())
|
||||
return;
|
||||
LangAS ImplAS = LangAS::opencl_private;
|
||||
if ((getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) &&
|
||||
// OpenCL C v3.0 s6.7.8 - For OpenCL C 2.0 or with the
|
||||
// __opencl_c_program_scope_global_variables feature, the address space
|
||||
// for a variable at program scope or a static or extern variable inside
|
||||
// a function are inferred to be __global.
|
||||
if (getOpenCLOptions().areProgramScopeVariablesSupported(getLangOpts()) &&
|
||||
Var->hasGlobalStorage())
|
||||
ImplAS = LangAS::opencl_global;
|
||||
// If the original type from a decayed type is an array type and that array
|
||||
|
@ -8018,23 +8022,16 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
|
|||
}
|
||||
}
|
||||
|
||||
// OpenCL C v1.2 s6.5 - All program scope variables must be declared in the
|
||||
// __constant address space.
|
||||
// OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static
|
||||
// variables inside a function can also be declared in the global
|
||||
// address space.
|
||||
// C++ for OpenCL inherits rule from OpenCL C v2.0.
|
||||
// FIXME: Adding local AS in C++ for OpenCL might make sense.
|
||||
if (NewVD->isFileVarDecl() || NewVD->isStaticLocal() ||
|
||||
NewVD->hasExternalStorage()) {
|
||||
if (!T->isSamplerT() &&
|
||||
!T->isDependentType() &&
|
||||
if (!T->isSamplerT() && !T->isDependentType() &&
|
||||
!(T.getAddressSpace() == LangAS::opencl_constant ||
|
||||
(T.getAddressSpace() == LangAS::opencl_global &&
|
||||
(getLangOpts().OpenCLVersion == 200 ||
|
||||
getLangOpts().OpenCLCPlusPlus)))) {
|
||||
getOpenCLOptions().areProgramScopeVariablesSupported(
|
||||
getLangOpts())))) {
|
||||
int Scope = NewVD->isStaticLocal() | NewVD->hasExternalStorage() << 1;
|
||||
if (getLangOpts().OpenCLVersion == 200 || getLangOpts().OpenCLCPlusPlus)
|
||||
if (getOpenCLOptions().areProgramScopeVariablesSupported(getLangOpts()))
|
||||
Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space)
|
||||
<< Scope << "global or constant";
|
||||
else
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN,AMDGCN20 %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL1.2 -O0 -triple spir-unknown-unknown-unknown | FileCheck -enable-var-scope -check-prefixes=SPIR %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL3.0 -O0 -triple amdgcn -cl-ext=+__opencl_c_program_scope_global_variables | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN,AMDGCN20 %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL3.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN %s
|
||||
|
||||
typedef int int2 __attribute__((ext_vector_type(2)));
|
||||
|
||||
|
@ -39,7 +41,7 @@ struct LargeStructTwoMember {
|
|||
int2 y[20];
|
||||
};
|
||||
|
||||
#if __OPENCL_C_VERSION__ >= 200
|
||||
#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ >= 300 && defined(__opencl_c_program_scope_global_variables))
|
||||
struct LargeStructOneMember g_s;
|
||||
#endif
|
||||
|
||||
|
@ -98,7 +100,7 @@ void FuncOneLargeMember(struct LargeStructOneMember u) {
|
|||
// AMDGCN20: %[[r0:.*]] = bitcast %struct.LargeStructOneMember addrspace(5)* %[[byval_temp]] to i8 addrspace(5)*
|
||||
// AMDGCN20: call void @llvm.memcpy.p5i8.p1i8.i64(i8 addrspace(5)* align 8 %[[r0]], i8 addrspace(1)* align 8 bitcast (%struct.LargeStructOneMember addrspace(1)* @g_s to i8 addrspace(1)*), i64 800, i1 false)
|
||||
// AMDGCN20: call void @FuncOneLargeMember(%struct.LargeStructOneMember addrspace(5)* byval(%struct.LargeStructOneMember) align 8 %[[byval_temp]])
|
||||
#if __OPENCL_C_VERSION__ >= 200
|
||||
#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ >= 300 && defined(__opencl_c_program_scope_global_variables))
|
||||
void test_indirect_arg_globl(void) {
|
||||
FuncOneLargeMember(g_s);
|
||||
}
|
||||
|
|
|
@ -1,28 +1,118 @@
|
|||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2
|
||||
|
||||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space
|
||||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space
|
||||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,+__opencl_c_generic_address_space
|
||||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,+__opencl_c_generic_address_space
|
||||
static constant int G1 = 0;
|
||||
constant int G2 = 0;
|
||||
int G3 = 0; // expected-error{{program scope variable must reside in constant address space}}
|
||||
global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}}
|
||||
|
||||
static float g_implicit_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
int G3 = 0;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{program scope variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
global int G4 = 0;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{program scope variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
static float g_implicit_static_var = 0;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{program scope variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
static constant float g_constant_static_var = 0;
|
||||
static global float g_global_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
static generic float g_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{program scope variable must reside in constant address space}}
|
||||
|
||||
extern float g_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
static global float g_global_static_var = 0;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{program scope variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
static local float g_local_static_var = 0;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{program scope variable must reside in constant address space}}
|
||||
#else
|
||||
// expected-error@-4 {{program scope variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
static private float g_private_static_var = 0;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{program scope variable must reside in constant address space}}
|
||||
#else
|
||||
// expected-error@-4 {{program scope variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
static generic float g_generic_static_var = 0;
|
||||
#if (__OPENCL_C_VERSION__ < 300)
|
||||
// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-3 {{program scope variable must reside in constant address space}}
|
||||
#elif (__OPENCL_C_VERSION__ == 300)
|
||||
#if !defined(__opencl_c_generic_address_space)
|
||||
// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}}
|
||||
#endif
|
||||
#if !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-9 {{program scope variable must reside in constant address space}}
|
||||
#endif
|
||||
#if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-12 {{program scope variable must reside in global or constant address space}}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern float g_implicit_extern_var;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
extern constant float g_constant_extern_var;
|
||||
extern global float g_global_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern local float g_local_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern private float g_private_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern generic float g_generic_extern_var; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
|
||||
|
||||
extern global float g_global_extern_var;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
extern local float g_local_extern_var;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#else
|
||||
// expected-error@-4 {{extern variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
extern private float g_private_extern_var;
|
||||
#ifndef __opencl_c_program_scope_global_variables
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#else
|
||||
// expected-error@-4 {{extern variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
extern generic float g_generic_extern_var;
|
||||
#if (__OPENCL_C_VERSION__ < 300)
|
||||
// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-3 {{extern variable must reside in constant address space}}
|
||||
#elif (__OPENCL_C_VERSION__ == 300)
|
||||
#if !defined(__opencl_c_generic_address_space)
|
||||
// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}}
|
||||
#endif
|
||||
#if !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-9 {{extern variable must reside in constant address space}}
|
||||
#endif
|
||||
#if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-12 {{extern variable must reside in global or constant address space}}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void kernel foo(int x) {
|
||||
// static is not allowed at local scope before CL2.0
|
||||
static int S1 = 5; // expected-error{{variables in function scope cannot be declared static}}
|
||||
static constant int S2 = 5; // expected-error{{variables in function scope cannot be declared static}}
|
||||
static int S1 = 5;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{static local variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
static constant int S2 = 5;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#endif
|
||||
|
||||
constant int L1 = 0;
|
||||
local int L2;
|
||||
|
@ -32,12 +122,13 @@ void kernel foo(int x) {
|
|||
constant int L1 = 42; // expected-error {{variables in the constant address space can only be declared in the outermost scope of a kernel function}}
|
||||
}
|
||||
|
||||
auto int L3 = 7; // expected-error{{OpenCL C version 1.2 does not support the 'auto' storage class specifier}}
|
||||
auto int L3 = 7; // expected-error-re{{OpenCL C version {{1.2|3.0}} does not support the 'auto' storage class specifier}}
|
||||
global int L4; // expected-error{{function scope variable cannot be declared in global address space}}
|
||||
__attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}}
|
||||
|
||||
constant int L6 = x; // expected-error {{initializer element is not a compile-time constant}}
|
||||
global int *constant L7 = &G4;
|
||||
|
||||
private int *constant L8 = &x; // expected-error {{initializer element is not a compile-time constant}}
|
||||
constant int *constant L9 = &L1;
|
||||
local int *constant L10 = &L2; // expected-error {{initializer element is not a compile-time constant}}
|
||||
|
@ -59,17 +150,106 @@ void f() {
|
|||
__attribute__((address_space(100))) int L4; // expected-error{{automatic variable qualified with an invalid address space}}
|
||||
}
|
||||
|
||||
static float l_implicit_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static constant float l_constant_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static global float l_global_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static local float l_local_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static private float l_private_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static generic float l_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{variables in function scope cannot be declared static}}
|
||||
static float l_implicit_static_var = 0;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{static local variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
static constant float l_constant_static_var = 0;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#endif
|
||||
|
||||
static global float l_global_static_var = 0;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{static local variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
static local float l_local_static_var = 0;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{static local variable must reside in constant address space}}
|
||||
#elif defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-6 {{static local variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
static private float l_private_static_var = 0;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{variables in function scope cannot be declared static}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{static local variable must reside in constant address space}}
|
||||
#elif defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-6 {{static local variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
static generic float l_generic_static_var = 0;
|
||||
#if (__OPENCL_C_VERSION__ < 300)
|
||||
// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-3 {{variables in function scope cannot be declared static}}
|
||||
#elif (__OPENCL_C_VERSION__ == 300)
|
||||
#if !defined(__opencl_c_generic_address_space)
|
||||
// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}}
|
||||
#endif
|
||||
#if !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-9 {{static local variable must reside in constant address space}}
|
||||
#endif
|
||||
#if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-12 {{static local variable must reside in global or constant address space}}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern float l_implicit_extern_var;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{extern variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
extern float l_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern constant float l_constant_extern_var;
|
||||
extern global float l_global_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern local float l_local_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern private float l_private_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern generic float l_generic_extern_var; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
|
||||
|
||||
extern global float l_global_extern_var;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{extern variable must reside in constant address space}}
|
||||
#endif
|
||||
|
||||
extern local float l_local_extern_var;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{extern variable must reside in constant address space}}
|
||||
#elif defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-6 {{extern variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
extern private float l_private_extern_var;
|
||||
#if __OPENCL_C_VERSION__ < 300
|
||||
// expected-error@-2 {{extern variable must reside in constant address space}}
|
||||
#elif !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-4 {{extern variable must reside in constant address space}}
|
||||
#elif defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-6 {{extern variable must reside in global or constant address space}}
|
||||
#endif
|
||||
|
||||
extern generic float l_generic_extern_var;
|
||||
#if (__OPENCL_C_VERSION__ < 300)
|
||||
// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-3 {{extern variable must reside in constant address space}}
|
||||
#elif (__OPENCL_C_VERSION__ == 300)
|
||||
#if !defined(__opencl_c_generic_address_space)
|
||||
// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}}
|
||||
#endif
|
||||
#if !defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-9 {{extern variable must reside in constant address space}}
|
||||
#endif
|
||||
#if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables)
|
||||
// expected-error@-12 {{extern variable must reside in global or constant address space}}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue