[clang] 8d27be8 - [OpenCL] Add global_device and global_host address spaces
Alexey Bader via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 29 07:25:17 PDT 2020
Author: Alexey Bader
Date: 2020-07-29T17:24:53+03:00
New Revision: 8d27be8dbaffce0519ac41173d51923fc2524b1b
URL: https://github.com/llvm/llvm-project/commit/8d27be8dbaffce0519ac41173d51923fc2524b1b
DIFF: https://github.com/llvm/llvm-project/commit/8d27be8dbaffce0519ac41173d51923fc2524b1b.diff
LOG: [OpenCL] Add global_device and global_host address spaces
This patch introduces 2 new address spaces in OpenCL: global_device and global_host
which are a subset of a global address space, so the address space scheme will be
looking like:
```
generic->global->host
->device
->private
->local
constant
```
Justification: USM allocations may be associated with both host and device memory. We
want to give users a way to tell the compiler the allocation type of a USM pointer for
optimization purposes. (Link to the Unified Shared Memory extension:
https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/USM/cl_intel_unified_shared_memory.asciidoc)
Before this patch USM pointer could be only in opencl_global
address space, hence a device backend can't tell if a particular pointer
points to host or device memory. On FPGAs at least we can generate more
efficient hardware code if the user tells us where the pointer can point -
being able to distinguish between these types of pointers at compile time
allows us to instantiate simpler load-store units to perform memory
transactions.
Patch by Dmitry Sidorov.
Reviewed By: Anastasia
Differential Revision: https://reviews.llvm.org/D82174
Added:
clang/test/SemaOpenCL/usm-address-spaces-conversions.cl
Modified:
clang/include/clang/AST/Type.h
clang/include/clang/Basic/AddressSpaces.h
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Sema/ParsedAttr.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Basic/Targets/AMDGPU.cpp
clang/lib/Basic/Targets/NVPTX.h
clang/lib/Basic/Targets/SPIR.h
clang/lib/Basic/Targets/TCE.h
clang/lib/Basic/Targets/X86.h
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Sema/SemaType.cpp
clang/test/AST/language_address_space_attribute.cpp
clang/test/CodeGenCXX/mangle-address-space.cpp
clang/test/CodeGenOpenCL/address-spaces-conversions.cl
clang/test/CodeGenOpenCL/address-spaces.cl
clang/test/SemaTemplate/address_space-dependent.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 7fe652492b0e..7d943ebc78c0 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -480,6 +480,11 @@ class Qualifiers {
// Otherwise in OpenCLC v2.0 s6.5.5: every address space except
// for __constant can be used as __generic.
(A == LangAS::opencl_generic && B != LangAS::opencl_constant) ||
+ // We also define global_device and global_host address spaces,
+ // to distinguish global pointers allocated on host from pointers
+ // allocated on device, which are a subset of __global.
+ (A == LangAS::opencl_global && (B == LangAS::opencl_global_device ||
+ B == LangAS::opencl_global_host)) ||
// Consider pointer size address spaces to be equivalent to default.
((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
(isPtrSizeAddressSpace(B) || B == LangAS::Default));
diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h
index faf7f303aa2d..a9db52dfcc9c 100644
--- a/clang/include/clang/Basic/AddressSpaces.h
+++ b/clang/include/clang/Basic/AddressSpaces.h
@@ -36,6 +36,8 @@ enum class LangAS : unsigned {
opencl_constant,
opencl_private,
opencl_generic,
+ opencl_global_device,
+ opencl_global_host,
// CUDA specific address spaces.
cuda_device,
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 0ee3c5188563..f9bf3f0acd55 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1178,6 +1178,16 @@ def OpenCLGlobalAddressSpace : TypeAttr {
let Documentation = [OpenCLAddressSpaceGlobalDocs];
}
+def OpenCLGlobalDeviceAddressSpace : TypeAttr {
+ let Spellings = [Clang<"opencl_global_device">];
+ let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
+}
+
+def OpenCLGlobalHostAddressSpace : TypeAttr {
+ let Spellings = [Clang<"opencl_global_host">];
+ let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
+}
+
def OpenCLLocalAddressSpace : TypeAttr {
let Spellings = [Keyword<"__local">, Keyword<"local">, Clang<"opencl_local">];
let Documentation = [OpenCLAddressSpaceLocalDocs];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index c835e6da04d5..b9fcf9af323b 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3123,6 +3123,30 @@ scope) variables and static local variable as well.
}];
}
+def OpenCLAddressSpaceGlobalExtDocs : Documentation {
+ let Category = DocOpenCLAddressSpaces;
+ let Heading = "[[clang::opencl_global_device]], [[clang::opencl_global_host]]";
+ let Content = [{
+The ``global_device`` and ``global_host`` address space attributes specify that
+an object is allocated in global memory on the device/host. It helps to
+distinguish USM (Unified Shared Memory) pointers that access global device
+memory from those that access global host memory. These new address spaces are
+a subset of the ``__global/opencl_global`` address space, the full address space
+set model for OpenCL 2.0 with the extension looks as follows:
+ generic->global->host
+ ->device
+ ->private
+ ->local
+ constant
+
+As ``global_device`` and ``global_host`` are a subset of
+``__global/opencl_global`` address spaces it is allowed to convert
+``global_device`` and ``global_host`` address spaces to
+``__global/opencl_global`` address spaces (following ISO/IEC TR 18037 5.1.3
+"Address space nesting and rules for pointers).
+ }];
+}
+
def OpenCLAddressSpaceLocalDocs : Documentation {
let Category = DocOpenCLAddressSpaces;
let Heading = "__local, local, [[clang::opencl_local]]";
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 21e030fe5134..8946b12ee03f 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -606,6 +606,10 @@ class ParsedAttr final
return LangAS::opencl_constant;
case ParsedAttr::AT_OpenCLGlobalAddressSpace:
return LangAS::opencl_global;
+ case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
+ return LangAS::opencl_global_device;
+ case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
+ return LangAS::opencl_global_host;
case ParsedAttr::AT_OpenCLLocalAddressSpace:
return LangAS::opencl_local;
case ParsedAttr::AT_OpenCLPrivateAddressSpace:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 25bf71519d1c..43bbe41fb611 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -919,18 +919,20 @@ static const LangASMap *getAddressSpaceMap(const TargetInfo &T,
// The fake address space map must have a distinct entry for each
// language-specific address space.
static const unsigned FakeAddrSpaceMap[] = {
- 0, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 0, // opencl_private
- 4, // opencl_generic
- 5, // cuda_device
- 6, // cuda_constant
- 7, // cuda_shared
- 8, // ptr32_sptr
- 9, // ptr32_uptr
- 10 // ptr64
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_private
+ 4, // opencl_generic
+ 5, // opencl_global_device
+ 6, // opencl_global_host
+ 7, // cuda_device
+ 8, // cuda_constant
+ 9, // cuda_shared
+ 10, // ptr32_sptr
+ 11, // ptr32_uptr
+ 12 // ptr64
};
return &FakeAddrSpaceMap;
} else {
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ddfbe9f86499..2b207c17d939 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2388,16 +2388,39 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
switch (AS) {
default: llvm_unreachable("Not a language specific address space");
// <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
- // "private"| "generic" ]
- case LangAS::opencl_global: ASString = "CLglobal"; break;
- case LangAS::opencl_local: ASString = "CLlocal"; break;
- case LangAS::opencl_constant: ASString = "CLconstant"; break;
- case LangAS::opencl_private: ASString = "CLprivate"; break;
- case LangAS::opencl_generic: ASString = "CLgeneric"; break;
+ // "private"| "generic" | "device" |
+ // "host" ]
+ case LangAS::opencl_global:
+ ASString = "CLglobal";
+ break;
+ case LangAS::opencl_global_device:
+ ASString = "CLdevice";
+ break;
+ case LangAS::opencl_global_host:
+ ASString = "CLhost";
+ break;
+ case LangAS::opencl_local:
+ ASString = "CLlocal";
+ break;
+ case LangAS::opencl_constant:
+ ASString = "CLconstant";
+ break;
+ case LangAS::opencl_private:
+ ASString = "CLprivate";
+ break;
+ case LangAS::opencl_generic:
+ ASString = "CLgeneric";
+ break;
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
- case LangAS::cuda_device: ASString = "CUdevice"; break;
- case LangAS::cuda_constant: ASString = "CUconstant"; break;
- case LangAS::cuda_shared: ASString = "CUshared"; break;
+ case LangAS::cuda_device:
+ ASString = "CUdevice";
+ break;
+ case LangAS::cuda_constant:
+ ASString = "CUconstant";
+ break;
+ case LangAS::cuda_shared:
+ ASString = "CUshared";
+ break;
// <ptrsize-addrspace> ::= [ "ptr32_sptr" | "ptr32_uptr" | "ptr64" ]
case LangAS::ptr32_sptr:
ASString = "ptr32_sptr";
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 09579c28061a..55ac7629a54c 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1798,7 +1798,7 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
// where:
// <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>
// <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
- // "private"| "generic" ]
+ // "private"| "generic" | "device" | "host" ]
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
// Note that the above were chosen to match the Itanium mangling for this.
//
@@ -1823,6 +1823,12 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
case LangAS::opencl_global:
Extra.mangleSourceName("_ASCLglobal");
break;
+ case LangAS::opencl_global_device:
+ Extra.mangleSourceName("_ASCLdevice");
+ break;
+ case LangAS::opencl_global_host:
+ Extra.mangleSourceName("_ASCLhost");
+ break;
case LangAS::opencl_local:
Extra.mangleSourceName("_ASCLlocal");
break;
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index eff8e9976435..7286a88f3fc4 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1564,6 +1564,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::OpenCLPrivateAddressSpace:
case attr::OpenCLGlobalAddressSpace:
+ case attr::OpenCLGlobalDeviceAddressSpace:
+ case attr::OpenCLGlobalHostAddressSpace:
case attr::OpenCLLocalAddressSpace:
case attr::OpenCLConstantAddressSpace:
case attr::OpenCLGenericAddressSpace:
@@ -1866,6 +1868,10 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "__constant";
case LangAS::opencl_generic:
return "__generic";
+ case LangAS::opencl_global_device:
+ return "__global_device";
+ case LangAS::opencl_global_host:
+ return "__global_host";
case LangAS::cuda_device:
return "__device__";
case LangAS::cuda_constant:
diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp
index db7db8d36d03..e147045110a9 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -46,6 +46,8 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
Constant, // opencl_constant
Private, // opencl_private
Generic, // opencl_generic
+ Global, // opencl_global_device
+ Global, // opencl_global_host
Global, // cuda_device
Constant, // cuda_constant
Local, // cuda_shared
@@ -61,6 +63,8 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
Constant, // opencl_constant
Private, // opencl_private
Generic, // opencl_generic
+ Global, // opencl_global_device
+ Global, // opencl_global_host
Global, // cuda_device
Constant, // cuda_constant
Local, // cuda_shared
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index f57a0f18efa3..84828f0396c3 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -30,6 +30,8 @@ static const unsigned NVPTXAddrSpaceMap[] = {
0, // opencl_private
// FIXME: generic has to be added to the target
0, // opencl_generic
+ 1, // opencl_global_device
+ 1, // opencl_global_host
1, // cuda_device
4, // cuda_constant
3, // cuda_shared
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index f625d4980e29..6473138982c1 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -28,6 +28,8 @@ static const unsigned SPIRAddrSpaceMap[] = {
2, // opencl_constant
0, // opencl_private
4, // opencl_generic
+ 5, // opencl_global_device
+ 6, // opencl_global_host
0, // cuda_device
0, // cuda_constant
0, // cuda_shared
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index 9cbf2a3688a2..445fe4fe7293 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -35,6 +35,8 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
4, // opencl_local
5, // opencl_constant
0, // opencl_private
+ 1, // opencl_global_device
+ 1, // opencl_global_host
// FIXME: generic has to be added to the target
0, // opencl_generic
0, // cuda_device
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 50e77937febd..d99358d6f806 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -30,6 +30,8 @@ static const unsigned X86AddrSpaceMap[] = {
0, // opencl_constant
0, // opencl_private
0, // opencl_generic
+ 0, // opencl_global_device
+ 0, // opencl_global_host
0, // cuda_device
0, // cuda_constant
0, // cuda_shared
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4c792520b5f3..48a1dddfb331 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1324,10 +1324,18 @@ static void removeImageAccessQualifier(std::string& TyName) {
// (basically all single AS CPUs).
static unsigned ArgInfoAddressSpace(LangAS AS) {
switch (AS) {
- case LangAS::opencl_global: return 1;
- case LangAS::opencl_constant: return 2;
- case LangAS::opencl_local: return 3;
- case LangAS::opencl_generic: return 4; // Not in SPIR 2.0 specs.
+ case LangAS::opencl_global:
+ return 1;
+ case LangAS::opencl_constant:
+ return 2;
+ case LangAS::opencl_local:
+ return 3;
+ case LangAS::opencl_generic:
+ return 4; // Not in SPIR 2.0 specs.
+ case LangAS::opencl_global_device:
+ return 5;
+ case LangAS::opencl_global_host:
+ return 6;
default:
return 0; // Assume private.
}
@@ -3792,6 +3800,8 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
if (LangOpts.OpenCL) {
AddrSpace = D ? D->getType().getAddressSpace() : LangAS::opencl_global;
assert(AddrSpace == LangAS::opencl_global ||
+ AddrSpace == LangAS::opencl_global_device ||
+ AddrSpace == LangAS::opencl_global_host ||
AddrSpace == LangAS::opencl_constant ||
AddrSpace == LangAS::opencl_local ||
AddrSpace >= LangAS::FirstTargetAddressSpace);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 78c65ad01e47..abf1d6450036 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7968,6 +7968,8 @@ static bool isAddressSpaceKind(const ParsedAttr &attr) {
return attrKind == ParsedAttr::AT_AddressSpace ||
attrKind == ParsedAttr::AT_OpenCLPrivateAddressSpace ||
attrKind == ParsedAttr::AT_OpenCLGlobalAddressSpace ||
+ attrKind == ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace ||
+ attrKind == ParsedAttr::AT_OpenCLGlobalHostAddressSpace ||
attrKind == ParsedAttr::AT_OpenCLLocalAddressSpace ||
attrKind == ParsedAttr::AT_OpenCLConstantAddressSpace ||
attrKind == ParsedAttr::AT_OpenCLGenericAddressSpace;
@@ -8048,6 +8050,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
break;
case ParsedAttr::AT_OpenCLPrivateAddressSpace:
case ParsedAttr::AT_OpenCLGlobalAddressSpace:
+ case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
+ case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
case ParsedAttr::AT_OpenCLLocalAddressSpace:
case ParsedAttr::AT_OpenCLConstantAddressSpace:
case ParsedAttr::AT_OpenCLGenericAddressSpace:
diff --git a/clang/test/AST/language_address_space_attribute.cpp b/clang/test/AST/language_address_space_attribute.cpp
index fcf7503302f9..93a23304d9a6 100644
--- a/clang/test/AST/language_address_space_attribute.cpp
+++ b/clang/test/AST/language_address_space_attribute.cpp
@@ -17,6 +17,18 @@ void langas() {
// CHECK: VarDecl {{.*}} z_global '__global int *'
[[clang::opencl_global]] int *z_global;
+ // CHECK: VarDecl {{.*}} x_global_device '__global_device int *'
+ __attribute__((opencl_global_device)) int *x_global_device;
+
+ // CHECK: VarDecl {{.*}} z_global_device '__global_device int *'
+ [[clang::opencl_global_device]] int *z_global_device;
+
+ // CHECK: VarDecl {{.*}} x_global_host '__global_host int *'
+ __attribute__((opencl_global_host)) int *x_global_host;
+
+ // CHECK: VarDecl {{.*}} z_global_host '__global_host int *'
+ [[clang::opencl_global_host]] int *z_global_host;
+
// CHECK: VarDecl {{.*}} x_local '__local int *'
__attribute__((opencl_local)) int *x_local;
diff --git a/clang/test/CodeGenCXX/mangle-address-space.cpp b/clang/test/CodeGenCXX/mangle-address-space.cpp
index 2c5cdfc3dadb..600e64ef7e67 100644
--- a/clang/test/CodeGenCXX/mangle-address-space.cpp
+++ b/clang/test/CodeGenCXX/mangle-address-space.cpp
@@ -43,6 +43,10 @@ void ocl_f0(char __private *p) { }
struct ocl_OpaqueType;
typedef ocl_OpaqueType __global * ocl_OpaqueTypePtr;
+typedef ocl_OpaqueType __attribute__((opencl_global_host)) * ocl_OpaqueTypePtrH;
+typedef ocl_OpaqueType
+ __attribute__((opencl_global_device)) *
+ ocl_OpaqueTypePtrD;
// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU8CLglobal14ocl_OpaqueType
// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLglobal@$$CAUocl_OpaqueType@@@__clang@@@Z"
@@ -61,4 +65,12 @@ __constant float *ocl_f1(char __generic const *p) { return 0;}
// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f2PU9CLgenericKc
// WINOCL-LABEL: define {{.*}}float* @"?ocl_f2@@YAPEAU?$_ASCLgeneric@$$CAM at __clang@@QEAU?$_ASCLgeneric@$$CBD at 2@@Z"
__generic float *ocl_f2(__generic char const * const p) { return 0;}
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f3PU6CLhost14ocl_OpaqueType
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f3@@YAXPEAU?$_ASCLhost@$$CAUocl_OpaqueType@@@__clang@@@Z"
+void ocl_f3(ocl_OpaqueTypePtrH) {}
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f4PU8CLdevice14ocl_OpaqueType
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f4@@YAXPEAU?$_ASCLdevice@$$CAUocl_OpaqueType@@@__clang@@@Z"
+void ocl_f4(ocl_OpaqueTypePtrD) {}
#endif
diff --git a/clang/test/CodeGenOpenCL/address-spaces-conversions.cl b/clang/test/CodeGenOpenCL/address-spaces-conversions.cl
index 52feccc540bb..39cc86fef750 100644
--- a/clang/test/CodeGenOpenCL/address-spaces-conversions.cl
+++ b/clang/test/CodeGenOpenCL/address-spaces-conversions.cl
@@ -6,7 +6,9 @@
// pointers to
diff erent address spaces
// CHECK: define void @test
-void test(global int *arg_glob, generic int *arg_gen) {
+void test(global int *arg_glob, generic int *arg_gen,
+ __attribute__((opencl_global_device)) int *arg_device,
+ __attribute__((opencl_global_host)) int *arg_host) {
int var_priv;
arg_gen = arg_glob; // implicit cast global -> generic
// CHECK: %{{[0-9]+}} = addrspacecast i32 addrspace(1)* %{{[0-9]+}} to i32 addrspace(4)*
@@ -39,6 +41,30 @@ void test(global int *arg_glob, generic int *arg_gen) {
// CHECK-NOT: bitcast
// CHECK-NOFAKE: bitcast
// CHECK-NOFAKE-NOT: addrspacecast
+
+ arg_glob = arg_device; // implicit cast
+ // CHECK: addrspacecast
+ // CHECK-NOFAKE-NOT: addrspacecast
+
+ arg_glob = arg_host; // implicit cast
+ // CHECK: addrspacecast
+ // CHECK-NOFAKE-NOT: addrspacecast
+
+ arg_glob = (global int *)arg_device; // explicit cast
+ // CHECK: addrspacecast
+ // CHECK-NOFAKE-NOT: addrspacecast
+
+ arg_glob = (global int *)arg_host; // explicit cast
+ // CHECK: addrspacecast
+ // CHECK-NOFAKE-NOT: addrspacecast
+
+ arg_device = (__attribute((opencl_global_device)) int *)arg_glob; // explicit cast
+ // CHECK: addrspacecast
+ // CHECK-NOFAKE-NOT: addrspacecast
+
+ arg_host = (__attribute((opencl_global_host)) int *)arg_glob; // explicit cast
+ // CHECK: addrspacecast
+ // CHECK-NOFAKE-NOT: addrspacecast
}
// Test ternary operator.
diff --git a/clang/test/CodeGenOpenCL/address-spaces.cl b/clang/test/CodeGenOpenCL/address-spaces.cl
index 144466a690b3..ebd227a6a9c7 100644
--- a/clang/test/CodeGenOpenCL/address-spaces.cl
+++ b/clang/test/CodeGenOpenCL/address-spaces.cl
@@ -51,6 +51,14 @@ void fl(local int *arg) {}
// AMDGCN: i32 addrspace(4)* %arg
void fc(constant int *arg) {}
+// SPIR: i32 addrspace(5)* %arg
+// AMDGCN: i32 addrspace(1)* %arg
+void fd(__attribute__((opencl_global_device)) int *arg) {}
+
+// SPIR: i32 addrspace(6)* %arg
+// AMDGCN: i32 addrspace(1)* %arg
+void fh(__attribute__((opencl_global_host)) int *arg) {}
+
#ifdef CL20
int i;
// CL20-DAG: @i = {{(dso_local )?}}addrspace(1) global i32 0
diff --git a/clang/test/SemaOpenCL/usm-address-spaces-conversions.cl b/clang/test/SemaOpenCL/usm-address-spaces-conversions.cl
new file mode 100644
index 000000000000..35c333630da8
--- /dev/null
+++ b/clang/test/SemaOpenCL/usm-address-spaces-conversions.cl
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -cl-std=CL2.0
+// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -cl-std=CL2.0 -DGENERIC
+// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -cl-std=CL2.0 -DCONSTANT
+// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -cl-std=CL2.0 -DLOCAL
+
+/* USM (unified shared memory) extension for OpenCLC 2.0 adds two new address
+ * spaces: global_device and global_host that are a subset of __global address
+ * space. As ISO/IEC TR 18037 5.1.3 declares - it's possible to implicitly
+ * convert a subset address space to a superset address space, while conversion
+ * in a reversed direction could be achived only with an explicit cast */
+
+#ifdef GENERIC
+#define AS_COMP __generic
+#else
+#define AS_COMP __global
+#endif // GENERIC
+
+#ifdef CONSTANT
+#define AS_INCOMP __constant
+#elif LOCAL
+#define AS_INCOMP __local
+#else // PRIVATE
+#define AS_INCOMP __private
+#endif // CONSTANT
+
+void test(AS_COMP int *arg_comp,
+ __attribute__((opencl_global_device)) int *arg_device,
+ __attribute__((opencl_global_host)) int *arg_host) {
+ AS_COMP int *var_glob1 = arg_device;
+ AS_COMP int *var_glob2 = arg_host;
+ AS_COMP int *var_glob3 = (AS_COMP int *)arg_device;
+ AS_COMP int *var_glob4 = (AS_COMP int *)arg_host;
+ arg_device = (__attribute__((opencl_global_device)) int *)arg_comp;
+ arg_host = (__attribute__((opencl_global_host)) int *)arg_comp;
+#ifdef GENERIC
+ // expected-error at +6{{assigning '__generic int *__private' to '__global_device int *__private' changes address space of pointer}}
+ // expected-error at +6{{assigning '__generic int *__private' to '__global_host int *__private' changes address space of pointer}}
+#else
+ // expected-error at +3{{assigning '__global int *__private' to '__global_device int *__private' changes address space of pointer}}
+ // expected-error at +3{{assigning '__global int *__private' to '__global_host int *__private' changes address space of pointer}}
+#endif // GENERIC
+ arg_device = arg_comp;
+ arg_host = arg_comp;
+
+#ifdef CONSTANT
+ // expected-error at +15{{initializing '__constant int *__private' with an expression of type '__global_device int *__private' changes address space of pointer}}
+ // expected-error at +15{{initializing '__constant int *__private' with an expression of type '__global_host int *__private' changes address space of pointer}}
+ // expected-error at +15{{initializing '__constant int *__private' with an expression of type '__global_device int *' changes address space of pointer}}
+ // expected-error at +16{{initializing '__constant int *__private' with an expression of type '__global_host int *' changes address space of pointer}}
+#elif LOCAL
+ // expected-error at +10{{initializing '__local int *__private' with an expression of type '__global_device int *__private' changes address space of pointer}}
+ // expected-error at +10{{initializing '__local int *__private' with an expression of type '__global_host int *__private' changes address space of pointer}}
+ // expected-error at +10{{initializing '__local int *__private' with an expression of type '__global_device int *' changes address space of pointer}}
+ // expected-error at +11{{initializing '__local int *__private' with an expression of type '__global_host int *' changes address space of pointer}}
+#else // PRIVATE
+ // expected-error at +5{{initializing '__private int *__private' with an expression of type '__global_device int *__private' changes address space of pointer}}
+ // expected-error at +5{{initializing '__private int *__private' with an expression of type '__global_host int *__private' changes address space of pointer}}
+ // expected-error at +5{{initializing '__private int *__private' with an expression of type '__global_device int *' changes address space of pointer}}
+ // expected-error at +6{{initializing '__private int *__private' with an expression of type '__global_host int *' changes address space of pointer}}
+#endif // CONSTANT
+ AS_INCOMP int *var_incomp1 = arg_device;
+ AS_INCOMP int *var_incomp2 = arg_host;
+ AS_INCOMP int *var_incomp3 =
+ (__attribute__((opencl_global_device)) int *)arg_device;
+ AS_INCOMP int *var_incomp4 =
+ (__attribute__((opencl_global_host)) int *)arg_host;
+}
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index bab6ca5d7b3d..09ae0a620d9f 100644
--- a/clang/test/SemaTemplate/address_space-dependent.cpp
+++ b/clang/test/SemaTemplate/address_space-dependent.cpp
@@ -43,7 +43,7 @@ void neg() {
template <long int I>
void tooBig() {
- __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388595)}}
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388593)}}
}
template <long int I>
@@ -101,7 +101,7 @@ int main() {
car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
HasASTemplateFields<1> HASTF;
neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
- correct<0x7FFFF3>();
+ correct<0x7FFFF1>();
tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650>' requested here}}
__attribute__((address_space(1))) char *x;
More information about the cfe-commits
mailing list