diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -396,6 +396,19 @@ HalfFormat = &llvm::APFloat::IEEEhalf(); FloatFormat = &llvm::APFloat::IEEEsingle(); LongDoubleFormat = &llvm::APFloat::IEEEquad(); + + // OpenCL C v3.0 s6.7.5 - The generic address space requires support for + // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space + // feature + // FIXME: OpenCLGenericAddressSpace is also defined in setLangDefaults() + // for OpenCL C 2.0 but with no access to target capabilities. Target + // should be immutable once created and thus this language option needs + // to be defined only once. + if (Opts.OpenCLVersion >= 300) { + const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts(); + Opts.OpenCLGenericAddressSpace = hasFeatureEnabled( + OpenCLFeaturesMap, "__opencl_c_generic_address_space"); + } } if (Opts.DoubleSize) { diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4072,6 +4072,8 @@ case tok::kw___generic: // generic address space is introduced only in OpenCL v2.0 // see OpenCL C Spec v2.0 s6.5.5 + // OpenCL v3.0 introduces __opencl_c_generic_address_space + // feature macro to indicate if generic address space is supported if (!Actions.getLangOpts().OpenCLGenericAddressSpace) { DiagID = diag::err_opencl_unknown_type_specifier; PrevSpec = Tok.getIdentifierInfo()->getNameStart(); diff --git a/clang/test/CodeGenOpenCL/address-spaces-conversions.cl b/clang/test/CodeGenOpenCL/address-spaces-conversions.cl --- a/clang/test/CodeGenOpenCL/address-spaces-conversions.cl +++ b/clang/test/CodeGenOpenCL/address-spaces-conversions.cl @@ -1,5 +1,7 @@ // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -ffake-address-space-map -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -ffake-address-space-map -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -cl-std=CL2.0 -emit-llvm -o - | FileCheck --check-prefix=CHECK-NOFAKE %s +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck --check-prefix=CHECK-NOFAKE %s // When -ffake-address-space-map is not used, all addr space mapped to 0 for x86_64. // test that we generate address space casts everywhere we need conversions of diff --git a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl --- a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl +++ b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl @@ -2,10 +2,14 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="ASMANG,ASMANG20" %s // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG10" %s // RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG20" %s +// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG20" %s +// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="ASMANG,ASMANG20" %s // We check that the address spaces are mangled the same in both version of OpenCL // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s // We can't name this f as private is equivalent to default // no specifier given address space so we get multiple definition @@ -47,7 +51,7 @@ // OCL-20-DAG: @_Z1fPU3AS2i // OCL-12-DAG: @_Z1fPU3AS2i -#if __OPENCL_C_VERSION__ >= 200 +#if (__OPENCL_C_VERSION__ == 200) || defined(__opencl_c_generic_address_space) __attribute__((overloadable)) void f(generic int *arg) { } // ASMANG20: @_Z1fPU3AS4i diff --git a/clang/test/CodeGenOpenCL/address-spaces.cl b/clang/test/CodeGenOpenCL/address-spaces.cl --- a/clang/test/CodeGenOpenCL/address-spaces.cl +++ b/clang/test/CodeGenOpenCL/address-spaces.cl @@ -1,9 +1,13 @@ // RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR +// RUN: %clang_cc1 %s -O0 -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR // RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -DCL20 -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20AMDGCN // RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -cl-std=CL3.0 -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s // RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s +// RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -cl-std=CL3.0 -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s // SPIR: %struct.S = type { i32, i32, i32* } // CL20SPIR: %struct.S = type { i32, i32, i32 addrspace(4)* } diff --git a/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl b/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl --- a/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl @@ -5,6 +5,18 @@ // RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-std=CL1.2 %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-std=CL2.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple r600 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn-mesa-mesa3d -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---opencl -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn-mesa-mesa3d -cl-ext=+__opencl_c_generic_address_space -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---opencl -cl-ext=+__opencl_c_generic_address_space -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-ext=+__opencl_c_generic_address_space -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple r600 -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn-mesa-mesa3d -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---opencl -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s + #ifdef __AMDGCN__ #define PTSIZE 8 #else @@ -58,9 +70,12 @@ check(sizeof(double) == 8); check(__alignof__(double) == 8); #endif - - check(sizeof(void*) == (__OPENCL_C_VERSION__ >= 200 ? 8 : 4)); - check(__alignof__(void*) == (__OPENCL_C_VERSION__ >= 200 ? 8 : 4)); + check(sizeof(private void*) == 4); + check(__alignof__(private void*) == 4); +#if (__OPENCL_C_VERSION__ == 200) || defined(__opencl_c_generic_address_space) + check(sizeof(generic void*) == 8); + check(__alignof__(generic void*) == 8); +#endif check(sizeof(global_ptr_t) == PTSIZE); check(__alignof__(global_ptr_t) == PTSIZE); check(sizeof(constant_ptr_t) == PTSIZE); diff --git a/clang/test/CodeGenOpenCL/overload.cl b/clang/test/CodeGenOpenCL/overload.cl --- a/clang/test/CodeGenOpenCL/overload.cl +++ b/clang/test/CodeGenOpenCL/overload.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s +// RUN: %clang_cc1 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s typedef short short4 __attribute__((ext_vector_type(4))); diff --git a/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl b/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl --- a/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl +++ b/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl @@ -4,6 +4,9 @@ // RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DCONSTANT -cl-std=clc++ // RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGLOBAL -cl-std=clc++ // RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGENERIC -cl-std=clc++ +// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DCONSTANT -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space +// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGLOBAL -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space +// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGENERIC -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space /* OpenCLC v2.0 adds a set of restrictions for conversions between pointers to * different address spaces, mainly described in Sections 6.5.5 and 6.5.6. @@ -17,6 +20,8 @@ * case), and __constant, that should cover all program paths for CL address * space conversions used in initialisations, assignments, casts, comparisons * and arithmetic operations. +* +* OpenCLC v3.0 supports generic address if __opencl_c_generic_address_space feature is supported */ #ifdef GENERIC diff --git a/clang/test/SemaOpenCL/address-spaces.cl b/clang/test/SemaOpenCL/address-spaces.cl --- a/clang/test/SemaOpenCL/address-spaces.cl +++ b/clang/test/SemaOpenCL/address-spaces.cl @@ -1,5 +1,6 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only // RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -verify -pedantic -fsyntax-only // RUN: %clang_cc1 %s -cl-std=clc++ -verify -pedantic -fsyntax-only __constant int ci = 1;