azabaznov created this revision. azabaznov added reviewers: Anastasia, svenvh. Herald added subscribers: ldrumm, yaxunl. azabaznov requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D103191 Files: clang/include/clang/Basic/OpenCLOptions.h clang/lib/Sema/SemaDecl.cpp clang/test/CodeGenOpenCL/addr-space-struct-arg.cl clang/test/SemaOpenCL/storageclass.cl
Index: clang/test/SemaOpenCL/storageclass.cl =================================================================== --- clang/test/SemaOpenCL/storageclass.cl +++ clang/test/SemaOpenCL/storageclass.cl @@ -1,46 +1,77 @@ // 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 -DNO_GENERIC_AS +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables -DNO_GENERIC_AS 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}} +int G3 = 0; +global int G4 = 0; -static float g_implicit_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} +static float g_implicit_static_var = 0; 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}} +static global float g_global_static_var = 0; +static local float g_local_static_var = 0; +static private float g_private_static_var = 0; +static generic float g_generic_static_var = 0; -extern float g_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}} +extern float g_implicit_extern_var; 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; +extern local float g_local_extern_var; +extern private float g_private_extern_var; +extern generic float g_generic_extern_var; +#ifndef __opencl_c_program_scope_global_variables +// expected-error@-17 {{program scope variable must reside in constant address space}} +// expected-error@-17 {{program scope variable must reside in constant address space}} +// expected-error@-16 {{program scope variable must reside in constant address space}} +// expected-error@-15 {{program scope variable must reside in constant address space}} +// expected-error@-15 {{program scope variable must reside in constant address space}} +// expected-error@-15 {{program scope variable must reside in constant address space}} +// expected-error-re@-15 {{OpenCL C version {{1.2|3.0}} does not support the 'generic' type qualifier}} +// expected-error@-16 {{program scope variable must reside in constant address space}} +// expected-error@-15 {{extern variable must reside in constant address space}} +// expected-error@-14 {{extern variable must reside in constant address space}} +// expected-error@-14 {{extern variable must reside in constant address space}} +// expected-error@-14 {{extern variable must reside in constant address space}} +// expected-error-re@-14 {{OpenCL C version {{1.2|3.0}} does not support the 'generic' type qualifier}} +// expected-error@-15 {{extern variable must reside in constant address space}} +#else +// expected-error@-26 {{program scope variable must reside in global or constant address space}} +// expected-error@-26 {{program scope variable must reside in global or constant address space}} +// expected-error@-26 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} +// expected-error@-22 {{extern variable must reside in global or constant address space}} +// expected-error@-22 {{extern variable must reside in global or constant address space}} +// expected-error@-22 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} +#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; + static constant int S2 = 5; +#if __OPENCL_C_VERSION__ < 300 +// expected-error@-3 {{variables in function scope cannot be declared static}} +// expected-error@-3 {{variables in function scope cannot be declared static}} +#elif !defined(__opencl_c_program_scope_global_variables) +// expected-error@-6 {{static local variable must reside in constant address space}} +#endif constant int L1 = 0; local int L2; if (true) { - local int L1; // expected-error {{variables in the local address space can only be declared in the outermost scope of a kernel function}} + local int L1; // expected-error {{variables in the local address space can only be declared in the outermost scope of a kernel function}} 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}} + 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}} +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}} + local int *constant L10 = &L2; // expected-error {{initializer element is not a compile-time constant}} } static void kernel bar() { // expected-error{{kernel functions cannot be declared static}} @@ -59,17 +90,46 @@ __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; + static constant float l_constant_static_var = 0; + static global float l_global_static_var = 0; + static local float l_local_static_var = 0; + static private float l_private_static_var = 0; + static generic float l_generic_static_var = 0; // expected-error-re{{OpenCL C version {{1.2|3.0}} does not support the 'generic' type qualifier}} - extern float l_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}} + extern float l_implicit_extern_var; 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; + extern local float l_local_extern_var; + extern private float l_private_extern_var; + extern generic float l_generic_extern_var; // expected-error-re{{OpenCL C version {{1.2|3.0}} does not support the 'generic' type qualifier}} +#if __OPENCL_C_VERSION__ < 300 +// expected-error@-14 {{variables in function scope cannot be declared static}} +// expected-error@-14 {{variables in function scope cannot be declared static}} +// expected-error@-14 {{variables in function scope cannot be declared static}} +// expected-error@-14 {{variables in function scope cannot be declared static}} +// expected-error@-14 {{variables in function scope cannot be declared static}} +// expected-error@-14 {{variables in function scope cannot be declared static}} +// expected-error@-13 {{extern variable must reside in constant address space}} +// expected-error@-12 {{extern variable must reside in constant address space}} +// expected-error@-12 {{extern variable must reside in constant address space}} +// expected-error@-12 {{extern variable must reside in constant address space}} +// expected-error@-12 {{extern variable must reside in constant address space}} +#elif !defined(__opencl_c_program_scope_global_variables) +// expected-error@-26 {{static local variable must reside in constant address space}} +// expected-error@-25 {{static local variable must reside in constant address space}} +// expected-error@-25 {{static local variable must reside in constant address space}} +// expected-error@-25 {{static local variable must reside in constant address space}} +// expected-error@-25 {{static local variable must reside in constant address space}} +// expected-error@-24 {{extern variable must reside in constant address space}} +// expected-error@-23 {{extern variable must reside in constant address space}} +// expected-error@-23 {{extern variable must reside in constant address space}} +// expected-error@-23 {{extern variable must reside in constant address space}} +// expected-error@-23 {{extern variable must reside in constant address space}} +#elif defined(__opencl_c_program_scope_global_variables) +// expected-error@-34 {{static local variable must reside in global or constant address space}} +// expected-error@-34 {{static local variable must reside in global or constant address space}} +// expected-error@-29 {{extern variable must reside in global or constant address space}} +// expected-error@-29 {{extern variable must reside in global or constant address space}} +#endif } Index: clang/test/CodeGenOpenCL/addr-space-struct-arg.cl =================================================================== --- clang/test/CodeGenOpenCL/addr-space-struct-arg.cl +++ clang/test/CodeGenOpenCL/addr-space-struct-arg.cl @@ -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 @@ 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 @@ // 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); } Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -6361,7 +6361,7 @@ if (Type->isSamplerT() || Type->isVoidType()) return; LangAS ImplAS = LangAS::opencl_private; - if ((getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) && + 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 @@ -7956,23 +7956,16 @@ } } - // 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 Index: clang/include/clang/Basic/OpenCLOptions.h =================================================================== --- clang/include/clang/Basic/OpenCLOptions.h +++ clang/include/clang/Basic/OpenCLOptions.h @@ -64,7 +64,24 @@ /// 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.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. + // 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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits