[clang] [clang][SYCL] Implement address space attributes for SYCL (PR #200849)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 12 11:52:35 PDT 2026
https://github.com/elizabethandrews updated https://github.com/llvm/llvm-project/pull/200849
>From 8df10139dac2986fe9df25745fe90e99f1663b33 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 8 May 2026 04:10:12 -0700
Subject: [PATCH 01/15] [clang][SYCL] Add SYCL spelling for AS attributes
This change renames OpenCL address space attributes in Attr.td
to generic offload variants to support OpenCL and SYCL spellings.
The following spellings were added - [[clang::sycl_private]],
[[clang::sycl_global]], [[clang::sycl_local]], [[clang::sycl_constant]],
and [[clang::sycl_generic]].
LangAS::sycl_generic was added to support SYCL's generic address space.
---
clang/include/clang/Basic/AddressSpaces.h | 5 ++
clang/include/clang/Basic/Attr.td | 32 ++++----
clang/include/clang/Basic/AttrDocs.td | 77 +++++++++++++------
.../clang/Basic/DiagnosticSemaKinds.td | 3 +
clang/include/clang/Sema/ParsedAttr.h | 25 +++---
clang/lib/AST/ItaniumMangle.cpp | 5 +-
clang/lib/AST/Type.cpp | 7 +-
clang/lib/AST/TypePrinter.cpp | 23 ++++--
clang/lib/Basic/TargetInfo.cpp | 1 +
clang/lib/Basic/Targets/AArch64.h | 1 +
clang/lib/Basic/Targets/AMDGPU.cpp | 2 +
clang/lib/Basic/Targets/DirectX.h | 1 +
clang/lib/Basic/Targets/NVPTX.h | 1 +
clang/lib/Basic/Targets/SPIR.h | 2 +
clang/lib/Basic/Targets/SystemZ.h | 1 +
clang/lib/Basic/Targets/TCE.h | 1 +
clang/lib/Basic/Targets/WebAssembly.h | 1 +
clang/lib/Basic/Targets/X86.h | 1 +
clang/lib/Headers/__clang_spirv_builtins.h | 10 ++-
clang/lib/Sema/ParsedAttr.cpp | 10 +--
clang/lib/Sema/SemaType.cpp | 19 +++--
.../CodeGenSYCL/address-space-conversions.cpp | 22 +++---
.../CodeGenSYCL/address-space-mangling.cpp | 12 +--
.../SemaSYCL/address-space-conversions.cpp | 39 +++++-----
.../address-space-opencl-sycl-compat.cpp | 34 ++++++++
.../SemaTemplate/address_space-dependent.cpp | 4 +-
26 files changed, 223 insertions(+), 116 deletions(-)
create mode 100644 clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h
index a941805423bca..58b04e50c2e3d 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,
+ // TODO: Remove opencl_global_device and opencl_global_host after corresponding
+ // attributes are deprecated for the required time.
opencl_global_device,
opencl_global_host,
@@ -46,10 +48,13 @@ enum class LangAS : unsigned {
// SYCL specific address spaces.
sycl_global,
+ // TODO: Remove sycl_global_device and sycl_global_host after corresponding attributes
+ // are deprecated for the required time.
sycl_global_device,
sycl_global_host,
sycl_local,
sycl_private,
+ sycl_generic,
// Pointer size and extension address spaces.
ptr32_sptr,
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 328e70b3ed900..aa0fb8d913322 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1791,44 +1791,46 @@ def OpenCLAccess : Attr {
let Documentation = [OpenCLAccessDocs];
}
-def OpenCLPrivateAddressSpace : TypeAttr {
+def OffloadPrivateAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__private">, CustomKeyword<"private">,
- Clang<"opencl_private">];
- let Documentation = [OpenCLAddressSpacePrivateDocs];
+ Clang<"opencl_private">, Clang<"sycl_private">];
+ let Documentation = [OffloadAddressSpacePrivateDocs];
}
-def OpenCLGlobalAddressSpace : TypeAttr {
+def OffloadGlobalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__global">, CustomKeyword<"global">,
- Clang<"opencl_global">];
- let Documentation = [OpenCLAddressSpaceGlobalDocs];
+ Clang<"opencl_global">, Clang<"sycl_global">];
+ let Documentation = [OffloadAddressSpaceGlobalDocs];
}
+// TODO: Remove OpenCLGlobalDeviceAddressSpace after deprecation.
def OpenCLGlobalDeviceAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_device">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
}
+// TODO: Remove OpenCLGlobalHostAddressSpace after deprecation.
def OpenCLGlobalHostAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_host">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
}
-def OpenCLLocalAddressSpace : TypeAttr {
+def OffloadLocalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__local">, CustomKeyword<"local">,
- Clang<"opencl_local">];
- let Documentation = [OpenCLAddressSpaceLocalDocs];
+ Clang<"opencl_local">, Clang<"sycl_local">];
+ let Documentation = [OffloadAddressSpaceLocalDocs];
}
-def OpenCLConstantAddressSpace : TypeAttr {
+def OffloadConstantAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__constant">, CustomKeyword<"constant">,
- Clang<"opencl_constant">];
- let Documentation = [OpenCLAddressSpaceConstantDocs];
+ Clang<"opencl_constant">, Clang<"sycl_constant">];
+ let Documentation = [OffloadAddressSpaceConstantDocs];
}
-def OpenCLGenericAddressSpace : TypeAttr {
+def OffloadGenericAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__generic">, CustomKeyword<"generic">,
- Clang<"opencl_generic">];
- let Documentation = [OpenCLAddressSpaceGenericDocs];
+ Clang<"opencl_generic">, Clang<"sycl_generic">];
+ let Documentation = [OffloadAddressSpaceGenericDocs];
}
def OpenCLNoSVM : Attr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 502af9b562ef0..74a6d7edaa4a2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5003,13 +5003,20 @@ More details can be found in the OpenCL C language Spec v2.0, Section 6.6.
}];
}
-def DocOpenCLAddressSpaces : DocumentationCategory<"OpenCL Address Spaces"> {
+def DocOffloadAddressSpaces : DocumentationCategory<"OpenCL and SYCL Address Spaces"> {
let Content = [{
The address space qualifier may be used to specify the region of memory that is
-used to allocate the object. OpenCL supports the following address spaces:
-__generic(generic), __global(global), __local(local), __private(private),
+used to allocate the object.
+
+OpenCL supports the following address spaces:
+
+__generic(generic), __global(global), __local(local), __private(private) and
__constant(constant).
+More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
+
+Example:
+
.. code-block:: c
__constant int c = ...;
@@ -5021,14 +5028,32 @@ __constant(constant).
return l;
}
-More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
+The memory model for SYCL devices is derived from the OpenCL memory model. Accordingly
+SYCL defines five address spaces: global, local, private, generic and constant. The
+following attributes correspond to these address spaces:
+
+[[clang::sycl_global]], [[clang::sycl_local]], [[clang::sycl_private]],
+[[clang::sycl_generic]] and [[clang::sycl_constant]] (deprecated)
+
+These attributes are intended for use in the implementation of SYCL run-time
+libraries. A direct declaration of pointers with address spaces is discouraged. Users
+should use the sycl::multi_ptr class to handle address space boundaries and
+interoperability.
+
+More details can be found in SYCL 2020 Specification, Section 3.8.2
+"SYCL device memory model" and Section 4.7.7, "Address space classes"
}];
+
}
-def OpenCLAddressSpaceGenericDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Heading = "__generic, generic, [[clang::opencl_generic]]";
+def OffloadAddressSpaceGenericDocs : Documentation {
+ let Category = DocOffloadAddressSpaces;
+ let Heading = "__generic, generic, [[clang::opencl_generic]], [[clang::sycl_generic]]";
let Content = [{
+The generic address space is a virtual address space which overlaps the global, local
+and private address spaces.
+
+OpenCL:
The generic address space attribute is only available with OpenCL v2.0 and later.
It can be used with pointer types. Variables in global and local scope and
function parameters in non-kernel functions can have the generic address space
@@ -5038,33 +5063,35 @@ spaces.
}];
}
-def OpenCLAddressSpaceConstantDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Heading = "__constant, constant, [[clang::opencl_constant]]";
+def OffloadAddressSpaceConstantDocs : Documentation {
+ let Category = DocOffloadAddressSpaces;
+ let Heading = "__constant, constant, [[clang::opencl_constant]], [[clang::sycl_constant]]";
let Content = [{
The constant address space attribute signals that an object is located in
a constant (non-modifiable) memory region. It is available to all work items.
Any type can be annotated with the constant address space attribute. Objects
with the constant address space qualifier can be declared in any scope and must
-have an initializer.
+have an initializer. The constant address space is deprecated in SYCL 2020
+specification.
}];
}
-def OpenCLAddressSpaceGlobalDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Heading = "__global, global, [[clang::opencl_global]]";
+def OffloadAddressSpaceGlobalDocs : Documentation {
+ let Category = DocOffloadAddressSpaces;
+ let Heading = "__global, global, [[clang::opencl_global]], [[clang::sycl_global]]";
let Content = [{
The global address space attribute specifies that an object is allocated in
global memory, which is accessible by all work items. The content stored in this
-memory area persists between kernel executions. Pointer types to the global
-address space are allowed as function parameters or local variables. Starting
-with OpenCL v2.0, the global address space can be used with global (program
-scope) variables and static local variable as well.
+memory area persists between kernel executions.
+
+In OpenCL, pointer types to the global address space are allowed as function parameters or
+local variables. Starting with OpenCL v2.0, the global address space can be used with global
+(program scope) variables and static local variable as well.
}];
}
def OpenCLAddressSpaceGlobalExtDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
+ let Category = DocOffloadAddressSpaces;
let Heading = "[[clang::opencl_global_device]], [[clang::opencl_global_host]]";
let Content = [{
The ``global_device`` and ``global_host`` address space attributes specify that
@@ -5088,9 +5115,9 @@ As ``global_device`` and ``global_host`` are a subset of
}];
}
-def OpenCLAddressSpaceLocalDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Heading = "__local, local, [[clang::opencl_local]]";
+def OffloadAddressSpaceLocalDocs : Documentation {
+ let Category = DocOffloadAddressSpaces;
+ let Heading = "__local, local, [[clang::opencl_local]], [[clang::sycl_local]]";
let Content = [{
The local address space specifies that an object is allocated in the local (work
group) memory area, which is accessible to all work items in the same work
@@ -5101,9 +5128,9 @@ space are allowed. Local address space variables cannot have an initializer.
}];
}
-def OpenCLAddressSpacePrivateDocs : Documentation {
- let Category = DocOpenCLAddressSpaces;
- let Heading = "__private, private, [[clang::opencl_private]]";
+def OffloadAddressSpacePrivateDocs : Documentation {
+ let Category = DocOffloadAddressSpaces;
+ let Heading = "__private, private, [[clang::opencl_private]], [[clang::sycl_private]]";
let Content = [{
The private address space specifies that an object is allocated in the private
(work item) memory. Other work items cannot access the same memory area and its
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4cd4efc55c416..45ab89aa9ebc4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3597,6 +3597,9 @@ def err_attribute_address_multiple_qualifiers : Error<
def warn_attribute_address_multiple_identical_qualifiers : Warning<
"multiple identical address spaces specified for type">,
InGroup<DuplicateDeclSpecifier>;
+def warn_deprecated_sycl_constant : Warning<
+ "'sycl_constant' address space attribute is deprecated">,
+ InGroup<DeprecatedAttributes>;
def err_attribute_not_clinkage : Error<
"function type with %0 attribute must have C linkage">;
def err_function_decl_cmse_ns_call : Error<
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 5387f9fad6cd2..9251c8aafdc71 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -553,44 +553,45 @@ class ParsedAttr final
/// a Spelling enumeration, the value UINT_MAX is returned.
unsigned getSemanticSpelling() const;
- /// If this is an OpenCL address space attribute, returns its representation
- /// in LangAS, otherwise returns default address space.
+ /// If this is a named address space attribute for OpenCL compilation, returns its
+ /// representation in LangAS, otherwise returns default address space.
LangAS asOpenCLLangAS() const {
switch (getParsedKind()) {
- case ParsedAttr::AT_OpenCLConstantAddressSpace:
+ case ParsedAttr::AT_OffloadConstantAddressSpace:
return LangAS::opencl_constant;
- case ParsedAttr::AT_OpenCLGlobalAddressSpace:
+ case ParsedAttr::AT_OffloadGlobalAddressSpace:
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:
+ case ParsedAttr::AT_OffloadLocalAddressSpace:
return LangAS::opencl_local;
- case ParsedAttr::AT_OpenCLPrivateAddressSpace:
+ case ParsedAttr::AT_OffloadPrivateAddressSpace:
return LangAS::opencl_private;
- case ParsedAttr::AT_OpenCLGenericAddressSpace:
+ case ParsedAttr::AT_OffloadGenericAddressSpace:
return LangAS::opencl_generic;
default:
return LangAS::Default;
}
}
- /// If this is an OpenCL address space attribute, returns its SYCL
+ /// If this is a named address space attribute for SYCL compilation, returns its
/// representation in LangAS, otherwise returns default address space.
LangAS asSYCLLangAS() const {
switch (getKind()) {
- case ParsedAttr::AT_OpenCLGlobalAddressSpace:
+ case ParsedAttr::AT_OffloadGlobalAddressSpace:
return LangAS::sycl_global;
case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
return LangAS::sycl_global_device;
case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
return LangAS::sycl_global_host;
- case ParsedAttr::AT_OpenCLLocalAddressSpace:
+ case ParsedAttr::AT_OffloadLocalAddressSpace:
return LangAS::sycl_local;
- case ParsedAttr::AT_OpenCLPrivateAddressSpace:
+ case ParsedAttr::AT_OffloadPrivateAddressSpace:
return LangAS::sycl_private;
- case ParsedAttr::AT_OpenCLGenericAddressSpace:
+ case ParsedAttr::AT_OffloadGenericAddressSpace:
+ return LangAS::sycl_generic;
default:
return LangAS::Default;
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index f58faa03bfa8c..6be573966781c 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2822,7 +2822,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
ASString = "CLgeneric";
break;
// <SYCL-addrspace> ::= "SY" [ "global" | "local" | "private" |
- // "device" | "host" ]
+ // "generic" | "device" | "host" ]
case LangAS::sycl_global:
ASString = "SYglobal";
break;
@@ -2838,6 +2838,9 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
case LangAS::sycl_private:
ASString = "SYprivate";
break;
+ case LangAS::sycl_generic:
+ ASString = "SYgeneric";
+ break;
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
case LangAS::cuda_device:
ASString = "CUdevice";
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 78983fd38410d..f368b75600d58 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -84,11 +84,14 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
// Consider pointer size address spaces to be equivalent to default.
((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
(isPtrSizeAddressSpace(B) || B == LangAS::Default)) ||
- // Default is a superset of SYCL address spaces.
- (A == LangAS::Default &&
+ // Default and sycl_generic are supersets of SYCL address spaces.
+ ((A == LangAS::Default || A == LangAS::sycl_generic) &&
(B == LangAS::sycl_private || B == LangAS::sycl_local ||
B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
B == LangAS::sycl_global_host)) ||
+ // Consider sycl_generic address space to be equivalent to default.
+ (A == LangAS::Default && B == LangAS::sycl_generic) ||
+ (B == LangAS::Default && A == LangAS::sycl_generic) ||
// In HIP device compilation, any cuda address space is allowed
// to implicitly cast into the default address space.
(A == LangAS::Default &&
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 80f5b90ba35c4..ed5d95c360303 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1992,13 +1992,13 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::HLSLResourceDimension:
llvm_unreachable("HLSL resource type attributes handled separately");
- case attr::OpenCLPrivateAddressSpace:
- case attr::OpenCLGlobalAddressSpace:
+ case attr::OffloadPrivateAddressSpace:
+ case attr::OffloadGlobalAddressSpace:
case attr::OpenCLGlobalDeviceAddressSpace:
case attr::OpenCLGlobalHostAddressSpace:
- case attr::OpenCLLocalAddressSpace:
- case attr::OpenCLConstantAddressSpace:
- case attr::OpenCLGenericAddressSpace:
+ case attr::OffloadLocalAddressSpace:
+ case attr::OffloadConstantAddressSpace:
+ case attr::OffloadGenericAddressSpace:
case attr::HLSLGroupSharedAddressSpace:
// FIXME: Update printAttributedBefore to print these once we generate
// AttributedType nodes for them.
@@ -2667,24 +2667,31 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
case LangAS::Default:
return "";
case LangAS::opencl_global:
- case LangAS::sycl_global:
return "__global";
case LangAS::opencl_local:
- case LangAS::sycl_local:
return "__local";
case LangAS::opencl_private:
- case LangAS::sycl_private:
return "__private";
case LangAS::opencl_constant:
return "__constant";
case LangAS::opencl_generic:
return "__generic";
+ // TODO: Remove *_global_device and *_global_host after corresponding
+ // attributes are deprecated for the required time.
case LangAS::opencl_global_device:
case LangAS::sycl_global_device:
return "__global_device";
case LangAS::opencl_global_host:
case LangAS::sycl_global_host:
return "__global_host";
+ case LangAS::sycl_global:
+ return "sycl_global";
+ case LangAS::sycl_local:
+ return "sycl_local";
+ case LangAS::sycl_private:
+ return "sycl_private";
+ case LangAS::sycl_generic:
+ return "sycl_generic";
case LangAS::cuda_device:
return "__device__";
case LangAS::cuda_constant:
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index e6ae89e0948c5..1d91bbaee21ef 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -44,6 +44,7 @@ static const LangASMap FakeAddrSpaceMap = {
6, // sycl_global_host
3, // sycl_local
0, // sycl_private
+ 4, // sycl_generic
10, // ptr32_sptr
11, // ptr32_uptr
12, // ptr64
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 0a29bad81939b..90d8401149c37 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -41,6 +41,7 @@ static const unsigned ARM64AddrSpaceMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
static_cast<unsigned>(AArch64AddrSpace::ptr32_sptr),
static_cast<unsigned>(AArch64AddrSpace::ptr32_uptr),
static_cast<unsigned>(AArch64AddrSpace::ptr64),
diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp
index 48ba5d94df581..5d102e015790f 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -43,6 +43,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_host
llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local
llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_generic
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
@@ -75,6 +76,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_generic
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 8b21b86bac264..6eb770f4a960e 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -38,6 +38,7 @@ static const unsigned DirectXAddrSpaceMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 69ee20f38343b..62bf6a514d444 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -42,6 +42,7 @@ static const unsigned NVPTXAddrSpaceMap[] = {
1, // sycl_global_host
3, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 37fe4a970dfef..88a9e5841b5a3 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -44,6 +44,7 @@ static const unsigned SPIRDefIsPrivMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
@@ -82,6 +83,7 @@ static const unsigned SPIRDefIsGenMap[] = {
6, // sycl_global_host
3, // sycl_local
0, // sycl_private
+ 4, // sycl_generic
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index 00f7d7a055b24..bc597fe30165b 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -38,6 +38,7 @@ static const unsigned ZOSAddressMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
0, // ptr32_sptr
1, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index 2b22f4c4ec724..d7086b23232c4 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -47,6 +47,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h
index 808342485cad0..b0ee4505625c2 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -38,6 +38,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index c7afcc7c86053..31fb984caac51 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -42,6 +42,7 @@ static const unsigned X86AddrSpaceMap[] = {
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
+ 0, // sycl_generic
270, // ptr32_sptr
271, // ptr32_uptr
272, // ptr64
diff --git a/clang/lib/Headers/__clang_spirv_builtins.h b/clang/lib/Headers/__clang_spirv_builtins.h
index 9c7215f506508..9b3ac8c134ab1 100644
--- a/clang/lib/Headers/__clang_spirv_builtins.h
+++ b/clang/lib/Headers/__clang_spirv_builtins.h
@@ -26,13 +26,17 @@
#define __SPIRV_convergent __attribute__((convergent))
#define __SPIRV_inline __attribute__((always_inline))
+#ifdef __SYCL_DEVICE_ONLY__
+#define __global __attribute__((sycl_global))
+#define __local __attribute__((sycl_local))
+#define __private __attribute__((sycl_private))
+#define __constant __attribute__((sycl_constant))
+#define __generic __attribute__((sycl_generic))
+#else
#define __global __attribute__((opencl_global))
#define __local __attribute__((opencl_local))
#define __private __attribute__((opencl_private))
#define __constant __attribute__((opencl_constant))
-#ifdef __SYCL_DEVICE_ONLY__
-#define __generic
-#else
#define __generic __attribute__((opencl_generic))
#endif
diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp
index 2b5ad33ad7b29..49dec6188d877 100644
--- a/clang/lib/Sema/ParsedAttr.cpp
+++ b/clang/lib/Sema/ParsedAttr.cpp
@@ -228,13 +228,13 @@ bool ParsedAttr::slidesFromDeclToDeclSpecLegacyBehavior() const {
// possible, we would like this list to go away entirely.
switch (getParsedKind()) {
case AT_AddressSpace:
- case AT_OpenCLPrivateAddressSpace:
- case AT_OpenCLGlobalAddressSpace:
+ case AT_OffloadPrivateAddressSpace:
+ case AT_OffloadGlobalAddressSpace:
case AT_OpenCLGlobalDeviceAddressSpace:
case AT_OpenCLGlobalHostAddressSpace:
- case AT_OpenCLLocalAddressSpace:
- case AT_OpenCLConstantAddressSpace:
- case AT_OpenCLGenericAddressSpace:
+ case AT_OffloadLocalAddressSpace:
+ case AT_OffloadConstantAddressSpace:
+ case AT_OffloadGenericAddressSpace:
case AT_NeonPolyVectorType:
case AT_NeonVectorType:
case AT_ArmMveStrictPolymorphism:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 846474fe94adf..1d13e632c51d6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6684,8 +6684,13 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
if (S.getLangOpts().HLSL)
ASIdx = Attr.asHLSLLangAS();
- if (ASIdx == LangAS::Default)
- llvm_unreachable("Invalid address space");
+ if (ASIdx == LangAS::Default) {
+ if (S.getLangOpts().SYCLIsDevice &&
+ Attr.getKind() == ParsedAttr::AT_OffloadConstantAddressSpace)
+ S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
+ else
+ llvm_unreachable("Invalid address space");
+ }
if (DiagnoseMultipleAddrSpaceAttributes(S, Type.getAddressSpace(), ASIdx,
Attr.getLoc())) {
@@ -9092,13 +9097,13 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
// it it breaks large amounts of Linux software.
attr.setUsedAsTypeAttr();
break;
- case ParsedAttr::AT_OpenCLPrivateAddressSpace:
- case ParsedAttr::AT_OpenCLGlobalAddressSpace:
+ case ParsedAttr::AT_OffloadPrivateAddressSpace:
+ case ParsedAttr::AT_OffloadGlobalAddressSpace:
case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- case ParsedAttr::AT_OpenCLLocalAddressSpace:
- case ParsedAttr::AT_OpenCLConstantAddressSpace:
- case ParsedAttr::AT_OpenCLGenericAddressSpace:
+ case ParsedAttr::AT_OffloadLocalAddressSpace:
+ case ParsedAttr::AT_OffloadConstantAddressSpace:
+ case ParsedAttr::AT_OffloadGenericAddressSpace:
case ParsedAttr::AT_AddressSpace:
HandleAddressSpaceTypeAttribute(type, attr, state);
attr.setUsedAsTypeAttr();
diff --git a/clang/test/CodeGenSYCL/address-space-conversions.cpp b/clang/test/CodeGenSYCL/address-space-conversions.cpp
index 506a24fb4a3ba..3eecdded06364 100644
--- a/clang/test/CodeGenSYCL/address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef align 4 dereferenceable(4) %
-void bar(__attribute__((opencl_local)) int &Data) {}
+void bar(__attribute__((sycl_local)) int &Data) {}
// CHECK-DAG: define{{.*}} void [[LOC_REF:@[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef %
void foo2(int *Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef %
-void foo(__attribute__((opencl_local)) int *Data) {}
+void foo(__attribute__((sycl_local)) int *Data) {}
// CHECK-DAG: define{{.*}} void [[LOC_PTR:@[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,11 +19,11 @@ void tmpl(T t) {}
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr addrspace(4)
- __attribute__((opencl_global)) int *GLOB;
+ __attribute__((sycl_global)) int *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1)
- __attribute__((opencl_local)) int *LOC;
+ __attribute__((sycl_local)) int *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3)
- __attribute__((opencl_private)) int *PRIV;
+ __attribute__((sycl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr
__attribute__((opencl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5)
@@ -57,24 +57,24 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[NoAS]].ascast
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[NoAS_CAST]], ptr addrspace(4) [[GLOB]].ascast
- GLOB = (__attribute__((opencl_global)) int *)NoAS;
+ GLOB = (__attribute__((sycl_global)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[NoAS]].ascast
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) [[NoAS_CAST]], ptr addrspace(4) [[LOC]].ascast
- LOC = (__attribute__((opencl_local)) int *)NoAS;
+ LOC = (__attribute__((sycl_local)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[NoAS]].ascast
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr [[NoAS_CAST]], ptr addrspace(4) [[PRIV]].ascast
- PRIV = (__attribute__((opencl_private)) int *)NoAS;
- // From opencl_global_[host/device] address spaces to opencl_global
+ PRIV = (__attribute__((sycl_private)) int *)NoAS;
+ // From opencl_global_[host/device] address spaces to sycl_global
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr addrspace(4) [[GLOB_DEVICE]].ascast
// CHECK-DAG: [[GLOBDEVICE_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[GLOBDEVICE_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_CAST]], ptr addrspace(4) [[GLOB]].ascast
- GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
+ GLOB = (__attribute__((sycl_global)) int *)GLOBDEVICE;
// CHECK-DAG: [[GLOBHOST_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(6), ptr addrspace(4) [[GLOB_HOST]].ascast
// CHECK-DAG: [[GLOBHOST_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(6) [[GLOBHOST_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[GLOBHOST_CAST]], ptr addrspace(4) [[GLOB]].ascast
- GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
+ GLOB = (__attribute__((sycl_global)) int *)GLOBHOST;
bar(*GLOB);
// CHECK-DAG: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr addrspace(4) [[GLOB]].ascast
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index ecc2d4b43a159..3e44be24ffc3e 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -3,9 +3,9 @@
// REQUIRES: x86-registered-target
-void foo(__attribute__((opencl_global)) int *);
-void foo(__attribute__((opencl_local)) int *);
-void foo(__attribute__((opencl_private)) int *);
+void foo(__attribute__((sycl_global)) int *);
+void foo(__attribute__((sycl_local)) int *);
+void foo(__attribute__((sycl_private)) int *);
void foo(int *);
// SPIR: declare spir_func void @_Z3fooPU3AS1i(ptr addrspace(1) noundef) #1
@@ -19,9 +19,9 @@ void foo(int *);
// X86: declare void @_Z3fooPi(ptr noundef) #1
[[clang::sycl_external]] void test() {
- __attribute__((opencl_global)) int *glob;
- __attribute__((opencl_local)) int *loc;
- __attribute__((opencl_private)) int *priv;
+ __attribute__((sycl_global)) int *glob;
+ __attribute__((sycl_local)) int *loc;
+ __attribute__((sycl_private)) int *priv;
int *def;
foo(glob);
foo(loc);
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index d8758248499de..9d209dbe5f8d7 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -2,28 +2,29 @@
void bar(int &Data) {}
void bar2(int &Data) {}
-void bar(__attribute__((opencl_private)) int &Data) {}
+void bar(__attribute__((sycl_private)) int &Data) {}
void foo(int *Data) {}
void foo2(int *Data) {}
-void foo(__attribute__((opencl_private)) int *Data) {}
-void baz(__attribute__((opencl_private)) int *Data) {} // expected-note {{candidate function not viable: cannot pass pointer to generic address space as a pointer to address space '__private' in 1st argument}}
+void foo(__attribute__((sycl_private)) int *Data) {}
+void baz(__attribute__((sycl_private)) int *Data) {} // expected-note {{candidate function not viable: cannot pass pointer to generic address space as a pointer to address space 'sycl_private' in 1st argument}}
template <typename T>
void tmpl(T *t) {}
void usages() {
- __attribute__((opencl_global)) int *GLOB;
- __attribute__((opencl_private)) int *PRIV;
- __attribute__((opencl_local)) int *LOC;
+ __attribute__((sycl_global)) int *GLOB;
+ __attribute__((sycl_private)) int *PRIV;
+ __attribute__((sycl_local)) int *LOC;
+ __attribute__((sycl_constant)) int *ptr1; // expected-warning {{'sycl_constant' address space attribute is deprecated}}
int *NoAS;
- GLOB = PRIV; // expected-error {{assigning '__private int *' to '__global int *' changes address space of pointer}}
- GLOB = LOC; // expected-error {{assigning '__local int *' to '__global int *' changes address space of pointer}}
- PRIV = static_cast<__attribute__((opencl_private)) int *>(GLOB); // expected-error {{static_cast from '__global int *' to '__private int *' is not allowed}}
- PRIV = static_cast<__attribute__((opencl_private)) int *>(LOC); // expected-error {{static_cast from '__local int *' to '__private int *' is not allowed}}
- NoAS = GLOB + PRIV; // expected-error {{invalid operands to binary expression ('__global int *' and '__private int *')}}
- NoAS = GLOB + LOC; // expected-error {{invalid operands to binary expression ('__global int *' and '__local int *')}}
- NoAS += GLOB; // expected-error {{invalid operands to binary expression ('int *' and '__global int *')}}
+ GLOB = PRIV; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
+ GLOB = LOC; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
+ PRIV = static_cast<__attribute__((sycl_private)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_private int *' is not allowed}}
+ PRIV = static_cast<__attribute__((sycl_private)) int *>(LOC); // expected-error {{static_cast from 'sycl_local int *' to 'sycl_private int *' is not allowed}}
+ NoAS = GLOB + PRIV; // expected-error {{invalid operands to binary expression ('sycl_global int *' and 'sycl_private int *')}}
+ NoAS = GLOB + LOC; // expected-error {{invalid operands to binary expression ('sycl_global int *' and 'sycl_local int *')}}
+ NoAS += GLOB; // expected-error {{invalid operands to binary expression ('int *' and 'sycl_global int *')}}
bar(*GLOB);
bar2(*GLOB);
@@ -53,10 +54,10 @@ void usages() {
// Implicit casts to named address space are disallowed
baz(NoAS); // expected-error {{no matching function for call to 'baz'}}
- __attribute__((opencl_local)) int *l = NoAS; // expected-error {{cannot initialize a variable of type '__local int *' with an lvalue of type 'int *'}}
+ __attribute__((sycl_local)) int *l = NoAS; // expected-error {{cannot initialize a variable of type 'sycl_local int *' with an lvalue of type 'int *'}}
// Explicit casts between disjoint address spaces are disallowed
- GLOB = (__attribute__((opencl_global)) int *)PRIV; // expected-error {{C-style cast from '__private int *' to '__global int *' converts between mismatching address spaces}}
+ GLOB = (__attribute__((sycl_global)) int *)PRIV; // expected-error {{C-style cast from 'sycl_private int *' to 'sycl_global int *' converts between mismatching address spaces}}
(void)static_cast<int *>(GLOB);
(void)static_cast<void *>(GLOB);
@@ -69,12 +70,12 @@ void usages() {
bar(*GLOB_HOST);
bar2(*GLOB_HOST);
GLOB = GLOB_HOST;
- GLOB_HOST = GLOB; // expected-error {{assigning '__global int *' to '__global_host int *' changes address space of pointer}}
- GLOB_HOST = static_cast<__attribute__((opencl_global_host)) int *>(GLOB); // expected-error {{static_cast from '__global int *' to '__global_host int *' is not allowed}}
+ GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_host int *' changes address space of pointer}}
+ GLOB_HOST = static_cast<__attribute__((opencl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
__attribute__((opencl_global_device)) int *GLOB_DEVICE;
bar(*GLOB_DEVICE);
bar2(*GLOB_DEVICE);
GLOB = GLOB_DEVICE;
- GLOB_DEVICE = GLOB; // expected-error {{assigning '__global int *' to '__global_device int *' changes address space of pointer}}
- GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from '__global int *' to '__global_device int *' is not allowed}}
+ GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
+ GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
}
diff --git a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
new file mode 100644
index 0000000000000..89c4fa4873086
--- /dev/null
+++ b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only %s
+
+// Test openCL and SYCL spelling conversions for address space
+// attributes.
+
+void test_incompatible() {
+ __attribute__((opencl_global)) int *opencl_global;
+ int [[clang::sycl_local]] *sycl_local;
+ int [[clang::sycl_private]] *sycl_private;
+
+ // Address space attributes are resolved using mode of compilation and not the spelling itself. This results in the SYCL spelling
+ // being used in both instances of each diagnostic despite openCL spelling being used.
+ opencl_global = sycl_local; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
+ opencl_global = sycl_private; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
+ sycl_local = opencl_global; // expected-error {{assigning 'sycl_global int *' to 'sycl_local int *' changes address space of pointer}}
+}
+
+void test_to_generic_mixed() {
+ __attribute__((opencl_generic)) int *opencl_gen;
+ int [[clang::sycl_generic]] *sycl_gen;
+
+ __attribute__((opencl_global)) int *opencl_global;
+ int [[clang::sycl_local]] *sycl_local;
+ int [[clang::sycl_private]] *sycl_private;
+
+ opencl_gen = sycl_local;
+ opencl_gen = sycl_private;
+ sycl_gen = opencl_global;
+
+}
+
+void overload_test(__attribute__((opencl_global)) int *p) { (void)p; } // expected-note {{previous definition is here}}
+void overload_test(__attribute__((sycl_global)) int *p) { (void)p; } // expected-error {{redefinition of 'overload_test'}}
+
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index 3fdccb2c71a76..d6f25923b69b5 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 (8388580)}}
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388579)}}
}
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<0x7FFFE4>();
+ correct<0x7FFFE3>();
tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
__attribute__((address_space(1))) char *x;
>From bfe1c766e0e5a35afb834f3b8f2b787ffc261cb5 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 29 May 2026 12:58:46 -0700
Subject: [PATCH 02/15] Choose address space mapping based on spelling
LangAS is selected based on spelling of attribute as opposed
to mode of compilation. It is unclear to me whether this is the
right move, and I am hoping for review comments to further discuss
this.
This changes behavior for all current sycl code using openCL spelling
for attributes and does not allow conversions between openCL and
sycl spellings even though they technically refer to the same
address space.
---
clang/include/clang/Basic/Attr.td | 74 ++++++++++++++++++-
clang/include/clang/Sema/ParsedAttr.h | 56 +-------------
clang/lib/Parse/ParseDecl.cpp | 2 +-
clang/lib/Sema/ParsedAttr.cpp | 24 ++++++
clang/lib/Sema/SemaType.cpp | 17 ++---
.../Builtins/generic_cast_to_ptr_explicit.c | 12 ++-
.../CodeGenSYCL/address-space-conversions.cpp | 6 +-
.../amd-address-space-conversions.cpp | 24 +++---
.../cuda-address-space-conversions.cpp | 24 +++---
.../SemaSYCL/address-space-conversions.cpp | 8 +-
.../address-space-opencl-sycl-compat.cpp | 13 ++--
11 files changed, 153 insertions(+), 107 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index aa0fb8d913322..86ba95eef4d7c 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1795,42 +1795,112 @@ def OffloadPrivateAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__private">, CustomKeyword<"private">,
Clang<"opencl_private">, Clang<"sycl_private">];
let Documentation = [OffloadAddressSpacePrivateDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_private ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_private ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_private;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::sycl_private : LangAS::opencl_private;
+ }
+ }];
}
def OffloadGlobalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__global">, CustomKeyword<"global">,
Clang<"opencl_global">, Clang<"sycl_global">];
let Documentation = [OffloadAddressSpaceGlobalDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_global ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_global ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_global;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::sycl_global : LangAS::opencl_global;
+ }
+ }];
}
// TODO: Remove OpenCLGlobalDeviceAddressSpace after deprecation.
def OpenCLGlobalDeviceAddressSpace : TypeAttr {
- let Spellings = [Clang<"opencl_global_device">];
+ let Spellings = [Clang<"opencl_global_device">, Clang<"sycl_global_device">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_global_device ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_global_device ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_global_device;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::sycl_global_device : LangAS::opencl_global_device;
+ }
+ }];
}
// TODO: Remove OpenCLGlobalHostAddressSpace after deprecation.
def OpenCLGlobalHostAddressSpace : TypeAttr {
- let Spellings = [Clang<"opencl_global_host">];
+ let Spellings = [Clang<"opencl_global_host">, Clang<"sycl_global_host">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_global_host ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_global_host ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_global_host;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::sycl_global_host : LangAS::opencl_global_host;
+ }
+ }];
}
def OffloadLocalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__local">, CustomKeyword<"local">,
Clang<"opencl_local">, Clang<"sycl_local">];
let Documentation = [OffloadAddressSpaceLocalDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_local ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_local ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_local;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::sycl_local : LangAS::opencl_local;
+ }
+ }];
}
def OffloadConstantAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__constant">, CustomKeyword<"constant">,
Clang<"opencl_constant">, Clang<"sycl_constant">];
let Documentation = [OffloadAddressSpaceConstantDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_constant ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_constant ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_constant;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::Default : LangAS::opencl_constant;
+ }
+ }];
}
def OffloadGenericAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__generic">, CustomKeyword<"generic">,
Clang<"opencl_generic">, Clang<"sycl_generic">];
let Documentation = [OffloadAddressSpaceGenericDocs];
+ let AdditionalMembers = [{
+ static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
+ return A.getAttributeSpellingListIndex() == GNU_sycl_generic ||
+ A.getAttributeSpellingListIndex() == CXX11_clang_sycl_generic ||
+ A.getAttributeSpellingListIndex() == C23_clang_sycl_generic;
+ }
+ static inline LangAS getLangAS(const AttributeCommonInfo& A) {
+ return isSYCLSpelling(A) ? LangAS::sycl_generic : LangAS::opencl_generic;
+ }
+ }];
}
def OpenCLNoSVM : Attr {
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 9251c8aafdc71..ddb26e89bdaa6 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -553,60 +553,8 @@ class ParsedAttr final
/// a Spelling enumeration, the value UINT_MAX is returned.
unsigned getSemanticSpelling() const;
- /// If this is a named address space attribute for OpenCL compilation, returns its
- /// representation in LangAS, otherwise returns default address space.
- LangAS asOpenCLLangAS() const {
- switch (getParsedKind()) {
- case ParsedAttr::AT_OffloadConstantAddressSpace:
- return LangAS::opencl_constant;
- case ParsedAttr::AT_OffloadGlobalAddressSpace:
- 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_OffloadLocalAddressSpace:
- return LangAS::opencl_local;
- case ParsedAttr::AT_OffloadPrivateAddressSpace:
- return LangAS::opencl_private;
- case ParsedAttr::AT_OffloadGenericAddressSpace:
- return LangAS::opencl_generic;
- default:
- return LangAS::Default;
- }
- }
-
- /// If this is a named address space attribute for SYCL compilation, returns its
- /// representation in LangAS, otherwise returns default address space.
- LangAS asSYCLLangAS() const {
- switch (getKind()) {
- case ParsedAttr::AT_OffloadGlobalAddressSpace:
- return LangAS::sycl_global;
- case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
- return LangAS::sycl_global_device;
- case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- return LangAS::sycl_global_host;
- case ParsedAttr::AT_OffloadLocalAddressSpace:
- return LangAS::sycl_local;
- case ParsedAttr::AT_OffloadPrivateAddressSpace:
- return LangAS::sycl_private;
- case ParsedAttr::AT_OffloadGenericAddressSpace:
- return LangAS::sycl_generic;
- default:
- return LangAS::Default;
- }
- }
-
- /// If this is an HLSL address space attribute, returns its representation
- /// in LangAS, otherwise returns default address space.
- LangAS asHLSLLangAS() const {
- switch (getParsedKind()) {
- case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
- return LangAS::hlsl_groupshared;
- default:
- return LangAS::Default;
- }
- }
+ /// Returns the appropriate LangAS for this address space attribute.
+ LangAS asLangAS() const;
AttributeCommonInfo::Kind getKind() const {
return AttributeCommonInfo::Kind(Info.AttrKind);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index e2ac86bc5e064..1a4b92ca99b99 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -7227,7 +7227,7 @@ void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
// prototype for the method.
if (getLangOpts().OpenCLCPlusPlus) {
for (ParsedAttr &attr : DS.getAttributes()) {
- LangAS ASIdx = attr.asOpenCLLangAS();
+ LangAS ASIdx = attr.asLangAS();
if (ASIdx != LangAS::Default) {
Q.addAddressSpace(ASIdx);
break;
diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp
index 49dec6188d877..08b9aea3bdb15 100644
--- a/clang/lib/Sema/ParsedAttr.cpp
+++ b/clang/lib/Sema/ParsedAttr.cpp
@@ -12,6 +12,7 @@
#include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"
@@ -312,3 +313,26 @@ void clang::takeAndConcatenateAttrs(ParsedAttributes &First,
if (Second.Range.getEnd().isValid())
First.Range.setEnd(Second.Range.getEnd());
}
+
+LangAS ParsedAttr::asLangAS() const {
+ switch (getParsedKind()) {
+ case ParsedAttr::AT_OffloadGlobalAddressSpace:
+ return OffloadGlobalAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
+ return OpenCLGlobalDeviceAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
+ return OpenCLGlobalHostAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OffloadLocalAddressSpace:
+ return OffloadLocalAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OffloadPrivateAddressSpace:
+ return OffloadPrivateAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OffloadConstantAddressSpace:
+ return OffloadConstantAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OffloadGenericAddressSpace:
+ return OffloadGenericAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
+ return LangAS::hlsl_groupshared;
+ default:
+ return LangAS::Default;
+ }
+}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1d13e632c51d6..326910b564df1 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5407,7 +5407,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// them later while creating QualType.
if (FTI.MethodQualifiers)
for (ParsedAttr &attr : FTI.MethodQualifiers->getAttributes()) {
- LangAS ASIdxNew = attr.asOpenCLLangAS();
+ LangAS ASIdxNew = attr.asLangAS();
if (DiagnoseMultipleAddrSpaceAttributes(S, ASIdx, ASIdxNew,
attr.getLoc()))
D.setInvalidType(true);
@@ -6678,15 +6678,12 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
else
Attr.setInvalid();
} else {
- // The keyword-based type attributes imply which address space to use.
- ASIdx = S.getLangOpts().SYCLIsDevice ? Attr.asSYCLLangAS()
- : Attr.asOpenCLLangAS();
- if (S.getLangOpts().HLSL)
- ASIdx = Attr.asHLSLLangAS();
-
- if (ASIdx == LangAS::Default) {
- if (S.getLangOpts().SYCLIsDevice &&
- Attr.getKind() == ParsedAttr::AT_OffloadConstantAddressSpace)
+ // Type attributes imply which address space to use.
+ ASIdx = Attr.asLangAS();
+
+ if (ASIdx == LangAS::Default &&
+ Attr.getKind() == ParsedAttr::AT_OffloadConstantAddressSpace) {
+ if (OffloadConstantAddressSpaceAttr::isSYCLSpelling(Attr))
S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
else
llvm_unreachable("Invalid address space");
diff --git a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
index 30f4ecb589a5c..b896d76897fbf 100644
--- a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
+++ b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
@@ -4,8 +4,14 @@
#ifdef __SYCL_DEVICE_ONLY__
#define SYCL_EXTERNAL [[clang::sycl_external]]
+#define __global __attribute__((sycl_global))
+#define __local __attribute__((sycl_local))
+#define __private __attribute__((sycl_private))
#else
#define SYCL_EXTERNAL
+#define __global __attribute__((opencl_global))
+#define __local __attribute__((opencl_local))
+#define __private __attribute__((opencl_private))
#endif
// CHECK: spir_func noundef ptr @{{.*}}test_cast_to_private{{.*}}(ptr addrspace(4) noundef readnone [[P:%.*]]
@@ -13,7 +19,7 @@
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr [[SPV_CAST]]
//
-SYCL_EXTERNAL __attribute__((opencl_private)) int* test_cast_to_private(int* p) {
+SYCL_EXTERNAL __private int* test_cast_to_private(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 7);
}
@@ -22,7 +28,7 @@ SYCL_EXTERNAL __attribute__((opencl_private)) int* test_cast_to_private(int* p)
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr addrspace(1) [[SPV_CAST]]
//
-SYCL_EXTERNAL __attribute__((opencl_global)) int* test_cast_to_global(int* p) {
+SYCL_EXTERNAL __global int* test_cast_to_global(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 5);
}
@@ -31,6 +37,6 @@ SYCL_EXTERNAL __attribute__((opencl_global)) int* test_cast_to_global(int* p) {
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr addrspace(3) [[SPV_CAST]]
//
-SYCL_EXTERNAL __attribute__((opencl_local)) int* test_cast_to_local(int* p) {
+SYCL_EXTERNAL __local int* test_cast_to_local(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 4);
}
diff --git a/clang/test/CodeGenSYCL/address-space-conversions.cpp b/clang/test/CodeGenSYCL/address-space-conversions.cpp
index 3eecdded06364..f331b8367b614 100644
--- a/clang/test/CodeGenSYCL/address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/address-space-conversions.cpp
@@ -25,9 +25,9 @@ void tmpl(T t) {}
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3)
__attribute__((sycl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr
- __attribute__((opencl_global_device)) int *GLOBDEVICE;
+ __attribute__((sycl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5)
- __attribute__((opencl_global_host)) int *GLOBHOST;
+ __attribute__((sycl_global_host)) int *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(6)
// CHECK-DAG: [[NoAS]].ascast = addrspacecast ptr [[NoAS]] to ptr addrspace(4)
@@ -66,7 +66,7 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr [[NoAS_CAST]], ptr addrspace(4) [[PRIV]].ascast
PRIV = (__attribute__((sycl_private)) int *)NoAS;
- // From opencl_global_[host/device] address spaces to sycl_global
+ // From sycl_global_[host/device] address spaces to sycl_global
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr addrspace(4) [[GLOB_DEVICE]].ascast
// CHECK-DAG: [[GLOBDEVICE_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[GLOBDEVICE_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_CAST]], ptr addrspace(4) [[GLOB]].ascast
diff --git a/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp b/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
index 17a98195318ad..a46b9660b2ef9 100644
--- a/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
-void bar(__attribute__((opencl_local)) int &Data) {}
+void bar(__attribute__((sycl_local)) int &Data) {}
// CHECK-DAG: define {{.*}} void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef %
void foo2(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef %
-void foo(__attribute__((opencl_local)) int *Data) {}
+void foo(__attribute__((sycl_local)) int *Data) {}
// CHECK-DAG: define {{.*}} void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t) {}
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8, addrspace(5)
- __attribute__((opencl_global)) int *GLOB;
+ __attribute__((sycl_global)) int *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
- __attribute__((opencl_local)) int *LOC;
+ __attribute__((sycl_local)) int *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 4, addrspace(5)
- __attribute__((opencl_private)) int *PRIV;
+ __attribute__((sycl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5), align 4, addrspace(5)
- __attribute__((opencl_global_device)) int *GLOBDEVICE;
+ __attribute__((sycl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
- __attribute__((opencl_global_host)) int *GLOBHOST;
+ __attribute__((sycl_global_host)) int *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
LOC = nullptr;
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]].ascast, align 4
@@ -45,22 +45,22 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr [[PRIV]].ascast, align 4
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr %5, ptr [[NoAS]].ascast, align 8
- GLOB = (__attribute__((opencl_global)) int *)NoAS;
+ GLOB = (__attribute__((sycl_global)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr %6 to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) %7, ptr [[GLOB]].ascast, align 8
- LOC = (__attribute__((opencl_local)) int *)NoAS;
+ LOC = (__attribute__((sycl_local)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) %9, ptr [[LOC]].ascast, align 4
- PRIV = (__attribute__((opencl_private)) int *)NoAS;
+ PRIV = (__attribute__((sycl_private)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(5)
// CHECK-DAG: store ptr addrspace(5) [[NoAS_CAST]], ptr [[PRIV]].ascast, align 4
- GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
+ GLOB = (__attribute__((sycl_global)) int *)GLOBDEVICE;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]DEVICE.ascast, align 8
// CHECK-DAG: store ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8
- GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
+ GLOB = (__attribute__((sycl_global)) int *)GLOBHOST;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]HOST.ascast, align 8
// CHECK-DAG: tore ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8
bar(*GLOB);
diff --git a/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp b/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
index ffb601e62c118..3427450547fce 100644
--- a/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
-void bar(__attribute__((opencl_local)) int &Data) {}
+void bar(__attribute__((sycl_local)) int &Data) {}
// CHECK-DAG: define {{.*}} void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef %
void foo2(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef %
-void foo(__attribute__((opencl_local)) int *Data) {}
+void foo(__attribute__((sycl_local)) int *Data) {}
// CHECK-DAG: define {{.*}} void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t);
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8
- __attribute__((opencl_global)) int *GLOB;
+ __attribute__((sycl_global)) int *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
- __attribute__((opencl_local)) int *LOC;
+ __attribute__((sycl_local)) int *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 8
- __attribute__((opencl_private)) int *PRIV;
+ __attribute__((sycl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr, align 8
- __attribute__((opencl_global_device)) int *GLOBDEVICE;
+ __attribute__((sycl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
- __attribute__((opencl_global_host)) int *GLOBHOST;
+ __attribute__((sycl_global_host)) int *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
LOC = nullptr;
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]], align 8
@@ -44,21 +44,21 @@ void tmpl(T t);
NoAS = (int *)PRIV;
// CHECK-DAG: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[PRIV]], align 8
// CHECK-DAG: store ptr [[LOC_LOAD]], ptr [[NoAS]], align 8
- GLOB = (__attribute__((opencl_global)) int *)NoAS;
+ GLOB = (__attribute__((sycl_global)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[NoAS_CAST]], ptr [[GLOB]], align 8
- LOC = (__attribute__((opencl_local)) int *)NoAS;
+ LOC = (__attribute__((sycl_local)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) [[NoAS_CAST]], ptr [[LOC]], align 8
- PRIV = (__attribute__((opencl_private)) int *)NoAS;
+ PRIV = (__attribute__((sycl_private)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: store ptr [[NoAS_LOAD]], ptr [[PRIV]], align 8
- GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
+ GLOB = (__attribute__((sycl_global)) int *)GLOBDEVICE;
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_DEVICE]], align 8
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_LOAD]], ptr %GLOB, align 8
- GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
+ GLOB = (__attribute__((sycl_global)) int *)GLOBHOST;
// CHECK-DAG: [[GLOB_HOST_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_HOST]], align 8
// CHECK-DAG: store ptr addrspace(1) [[GLOB_HOST_LOAD]], ptr [[GLOB]], align 8
bar(*GLOB);
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 9d209dbe5f8d7..0112ccae4c775 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -66,16 +66,16 @@ void usages() {
(void)i;
(void)v;
- __attribute__((opencl_global_host)) int *GLOB_HOST;
+ __attribute__((sycl_global_host)) int *GLOB_HOST;
bar(*GLOB_HOST);
bar2(*GLOB_HOST);
GLOB = GLOB_HOST;
GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_host int *' changes address space of pointer}}
- GLOB_HOST = static_cast<__attribute__((opencl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
- __attribute__((opencl_global_device)) int *GLOB_DEVICE;
+ GLOB_HOST = static_cast<__attribute__((sycl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
+ __attribute__((sycl_global_device)) int *GLOB_DEVICE;
bar(*GLOB_DEVICE);
bar2(*GLOB_DEVICE);
GLOB = GLOB_DEVICE;
GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
- GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
+ GLOB_DEVICE = static_cast<__attribute__((sycl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
}
diff --git a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
index 89c4fa4873086..7b4575e60c8ad 100644
--- a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
+++ b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
@@ -10,9 +10,9 @@ void test_incompatible() {
// Address space attributes are resolved using mode of compilation and not the spelling itself. This results in the SYCL spelling
// being used in both instances of each diagnostic despite openCL spelling being used.
- opencl_global = sycl_local; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
- opencl_global = sycl_private; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
- sycl_local = opencl_global; // expected-error {{assigning 'sycl_global int *' to 'sycl_local int *' changes address space of pointer}}
+ opencl_global = sycl_local; // expected-error {{assigning 'sycl_local int *' to '__global int *' changes address space of pointer}}
+ opencl_global = sycl_private; // expected-error {{assigning 'sycl_private int *' to '__global int *' changes address space of pointer}}
+ sycl_local = opencl_global; // expected-error {{assigning '__global int *' to 'sycl_local int *' changes address space of pointer}}
}
void test_to_generic_mixed() {
@@ -23,12 +23,13 @@ void test_to_generic_mixed() {
int [[clang::sycl_local]] *sycl_local;
int [[clang::sycl_private]] *sycl_private;
+ //FIXME: Why don't these throw an error?
opencl_gen = sycl_local;
opencl_gen = sycl_private;
- sycl_gen = opencl_global;
+ sycl_gen = opencl_global; // expected-error {{assigning '__global int *' to 'sycl_generic int *' changes address space of pointer}}
}
-void overload_test(__attribute__((opencl_global)) int *p) { (void)p; } // expected-note {{previous definition is here}}
-void overload_test(__attribute__((sycl_global)) int *p) { (void)p; } // expected-error {{redefinition of 'overload_test'}}
+void overload_test(__attribute__((opencl_global)) int *p) { (void)p; }
+void overload_test(__attribute__((sycl_global)) int *p) { (void)p; }
>From 071ba770ef59dd5c5c8338d2dce360a5cf925feb Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Mon, 1 Jun 2026 08:34:55 -0700
Subject: [PATCH 03/15] Update global_host and global_device attributes as well
for uniformity.
---
clang/include/clang/Basic/Attr.td | 12 ++++++------
clang/include/clang/Basic/AttrDocs.td | 4 ++--
clang/lib/AST/TypePrinter.cpp | 12 ++++++------
clang/lib/Sema/ParsedAttr.cpp | 12 ++++++------
clang/lib/Sema/SemaType.cpp | 4 ++--
clang/test/SemaSYCL/address-space-conversions.cpp | 8 ++++----
6 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 86ba95eef4d7c..00fb4dc8e24ee 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1823,10 +1823,10 @@ def OffloadGlobalAddressSpace : TypeAttr {
}];
}
-// TODO: Remove OpenCLGlobalDeviceAddressSpace after deprecation.
-def OpenCLGlobalDeviceAddressSpace : TypeAttr {
+// TODO: Remove OffloadGlobalDeviceAddressSpace after deprecation.
+def OffloadGlobalDeviceAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_device">, Clang<"sycl_global_device">];
- let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
+ let Documentation = [OffloadAddressSpaceGlobalExtDocs];
let AdditionalMembers = [{
static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
return A.getAttributeSpellingListIndex() == GNU_sycl_global_device ||
@@ -1839,10 +1839,10 @@ def OpenCLGlobalDeviceAddressSpace : TypeAttr {
}];
}
-// TODO: Remove OpenCLGlobalHostAddressSpace after deprecation.
-def OpenCLGlobalHostAddressSpace : TypeAttr {
+// TODO: Remove OffloadGlobalHostAddressSpace after deprecation.
+def OffloadGlobalHostAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_host">, Clang<"sycl_global_host">];
- let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
+ let Documentation = [OffloadAddressSpaceGlobalExtDocs];
let AdditionalMembers = [{
static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
return A.getAttributeSpellingListIndex() == GNU_sycl_global_host ||
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 74a6d7edaa4a2..d8e009121df44 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5090,9 +5090,9 @@ local variables. Starting with OpenCL v2.0, the global address space can be used
}];
}
-def OpenCLAddressSpaceGlobalExtDocs : Documentation {
+def OffloadAddressSpaceGlobalExtDocs : Documentation {
let Category = DocOffloadAddressSpaces;
- let Heading = "[[clang::opencl_global_device]], [[clang::opencl_global_host]]";
+ let Heading = "[[clang::opencl_global_device]], [[clang::opencl_global_host]], [[clang::sycl_global_device]], [[clang::sycl_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
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ed5d95c360303..ace0963158b84 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1994,8 +1994,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::OffloadPrivateAddressSpace:
case attr::OffloadGlobalAddressSpace:
- case attr::OpenCLGlobalDeviceAddressSpace:
- case attr::OpenCLGlobalHostAddressSpace:
+ case attr::OffloadGlobalDeviceAddressSpace:
+ case attr::OffloadGlobalHostAddressSpace:
case attr::OffloadLocalAddressSpace:
case attr::OffloadConstantAddressSpace:
case attr::OffloadGenericAddressSpace:
@@ -2676,13 +2676,9 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "__constant";
case LangAS::opencl_generic:
return "__generic";
- // TODO: Remove *_global_device and *_global_host after corresponding
- // attributes are deprecated for the required time.
case LangAS::opencl_global_device:
- case LangAS::sycl_global_device:
return "__global_device";
case LangAS::opencl_global_host:
- case LangAS::sycl_global_host:
return "__global_host";
case LangAS::sycl_global:
return "sycl_global";
@@ -2692,6 +2688,10 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "sycl_private";
case LangAS::sycl_generic:
return "sycl_generic";
+ case LangAS::sycl_global_device:
+ return "sycl_global_device";
+ case LangAS::sycl_global_host:
+ return "sycl_global_host";
case LangAS::cuda_device:
return "__device__";
case LangAS::cuda_constant:
diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp
index 08b9aea3bdb15..be60e19819431 100644
--- a/clang/lib/Sema/ParsedAttr.cpp
+++ b/clang/lib/Sema/ParsedAttr.cpp
@@ -231,8 +231,8 @@ bool ParsedAttr::slidesFromDeclToDeclSpecLegacyBehavior() const {
case AT_AddressSpace:
case AT_OffloadPrivateAddressSpace:
case AT_OffloadGlobalAddressSpace:
- case AT_OpenCLGlobalDeviceAddressSpace:
- case AT_OpenCLGlobalHostAddressSpace:
+ case AT_OffloadGlobalDeviceAddressSpace:
+ case AT_OffloadGlobalHostAddressSpace:
case AT_OffloadLocalAddressSpace:
case AT_OffloadConstantAddressSpace:
case AT_OffloadGenericAddressSpace:
@@ -318,10 +318,10 @@ LangAS ParsedAttr::asLangAS() const {
switch (getParsedKind()) {
case ParsedAttr::AT_OffloadGlobalAddressSpace:
return OffloadGlobalAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
- return OpenCLGlobalDeviceAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- return OpenCLGlobalHostAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OffloadGlobalDeviceAddressSpace:
+ return OffloadGlobalDeviceAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OffloadGlobalHostAddressSpace:
+ return OffloadGlobalHostAddressSpaceAttr::getLangAS(*this);
case ParsedAttr::AT_OffloadLocalAddressSpace:
return OffloadLocalAddressSpaceAttr::getLangAS(*this);
case ParsedAttr::AT_OffloadPrivateAddressSpace:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 326910b564df1..1fdf5c1a183c0 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9096,8 +9096,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
break;
case ParsedAttr::AT_OffloadPrivateAddressSpace:
case ParsedAttr::AT_OffloadGlobalAddressSpace:
- case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
- case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
+ case ParsedAttr::AT_OffloadGlobalDeviceAddressSpace:
+ case ParsedAttr::AT_OffloadGlobalHostAddressSpace:
case ParsedAttr::AT_OffloadLocalAddressSpace:
case ParsedAttr::AT_OffloadConstantAddressSpace:
case ParsedAttr::AT_OffloadGenericAddressSpace:
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 0112ccae4c775..0b0ec9fe2f09b 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -70,12 +70,12 @@ void usages() {
bar(*GLOB_HOST);
bar2(*GLOB_HOST);
GLOB = GLOB_HOST;
- GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_host int *' changes address space of pointer}}
- GLOB_HOST = static_cast<__attribute__((sycl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
+ GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to 'sycl_global_host int *' changes address space of pointer}}
+ GLOB_HOST = static_cast<__attribute__((sycl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_global_host int *' is not allowed}}
__attribute__((sycl_global_device)) int *GLOB_DEVICE;
bar(*GLOB_DEVICE);
bar2(*GLOB_DEVICE);
GLOB = GLOB_DEVICE;
- GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
- GLOB_DEVICE = static_cast<__attribute__((sycl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
+ GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to 'sycl_global_device int *' changes address space of pointer}}
+ GLOB_DEVICE = static_cast<__attribute__((sycl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_global_device int *' is not allowed}}
}
>From dab659e3fd360cb97ff5d422e2e80627ecb9c505 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Mon, 8 Jun 2026 07:31:58 -0700
Subject: [PATCH 04/15] Revert "Update global_host and global_device attributes
as well for uniformity."
This reverts commit 071ba770ef59dd5c5c8338d2dce360a5cf925feb.
---
clang/include/clang/Basic/Attr.td | 12 ++++++------
clang/include/clang/Basic/AttrDocs.td | 4 ++--
clang/lib/AST/TypePrinter.cpp | 12 ++++++------
clang/lib/Sema/ParsedAttr.cpp | 12 ++++++------
clang/lib/Sema/SemaType.cpp | 4 ++--
clang/test/SemaSYCL/address-space-conversions.cpp | 8 ++++----
6 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 00fb4dc8e24ee..86ba95eef4d7c 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1823,10 +1823,10 @@ def OffloadGlobalAddressSpace : TypeAttr {
}];
}
-// TODO: Remove OffloadGlobalDeviceAddressSpace after deprecation.
-def OffloadGlobalDeviceAddressSpace : TypeAttr {
+// TODO: Remove OpenCLGlobalDeviceAddressSpace after deprecation.
+def OpenCLGlobalDeviceAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_device">, Clang<"sycl_global_device">];
- let Documentation = [OffloadAddressSpaceGlobalExtDocs];
+ let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
let AdditionalMembers = [{
static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
return A.getAttributeSpellingListIndex() == GNU_sycl_global_device ||
@@ -1839,10 +1839,10 @@ def OffloadGlobalDeviceAddressSpace : TypeAttr {
}];
}
-// TODO: Remove OffloadGlobalHostAddressSpace after deprecation.
-def OffloadGlobalHostAddressSpace : TypeAttr {
+// TODO: Remove OpenCLGlobalHostAddressSpace after deprecation.
+def OpenCLGlobalHostAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_host">, Clang<"sycl_global_host">];
- let Documentation = [OffloadAddressSpaceGlobalExtDocs];
+ let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
let AdditionalMembers = [{
static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
return A.getAttributeSpellingListIndex() == GNU_sycl_global_host ||
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index d8e009121df44..74a6d7edaa4a2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5090,9 +5090,9 @@ local variables. Starting with OpenCL v2.0, the global address space can be used
}];
}
-def OffloadAddressSpaceGlobalExtDocs : Documentation {
+def OpenCLAddressSpaceGlobalExtDocs : Documentation {
let Category = DocOffloadAddressSpaces;
- let Heading = "[[clang::opencl_global_device]], [[clang::opencl_global_host]], [[clang::sycl_global_device]], [[clang::sycl_global_host]]";
+ 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
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ace0963158b84..ed5d95c360303 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1994,8 +1994,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::OffloadPrivateAddressSpace:
case attr::OffloadGlobalAddressSpace:
- case attr::OffloadGlobalDeviceAddressSpace:
- case attr::OffloadGlobalHostAddressSpace:
+ case attr::OpenCLGlobalDeviceAddressSpace:
+ case attr::OpenCLGlobalHostAddressSpace:
case attr::OffloadLocalAddressSpace:
case attr::OffloadConstantAddressSpace:
case attr::OffloadGenericAddressSpace:
@@ -2676,9 +2676,13 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "__constant";
case LangAS::opencl_generic:
return "__generic";
+ // TODO: Remove *_global_device and *_global_host after corresponding
+ // attributes are deprecated for the required time.
case LangAS::opencl_global_device:
+ case LangAS::sycl_global_device:
return "__global_device";
case LangAS::opencl_global_host:
+ case LangAS::sycl_global_host:
return "__global_host";
case LangAS::sycl_global:
return "sycl_global";
@@ -2688,10 +2692,6 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "sycl_private";
case LangAS::sycl_generic:
return "sycl_generic";
- case LangAS::sycl_global_device:
- return "sycl_global_device";
- case LangAS::sycl_global_host:
- return "sycl_global_host";
case LangAS::cuda_device:
return "__device__";
case LangAS::cuda_constant:
diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp
index be60e19819431..08b9aea3bdb15 100644
--- a/clang/lib/Sema/ParsedAttr.cpp
+++ b/clang/lib/Sema/ParsedAttr.cpp
@@ -231,8 +231,8 @@ bool ParsedAttr::slidesFromDeclToDeclSpecLegacyBehavior() const {
case AT_AddressSpace:
case AT_OffloadPrivateAddressSpace:
case AT_OffloadGlobalAddressSpace:
- case AT_OffloadGlobalDeviceAddressSpace:
- case AT_OffloadGlobalHostAddressSpace:
+ case AT_OpenCLGlobalDeviceAddressSpace:
+ case AT_OpenCLGlobalHostAddressSpace:
case AT_OffloadLocalAddressSpace:
case AT_OffloadConstantAddressSpace:
case AT_OffloadGenericAddressSpace:
@@ -318,10 +318,10 @@ LangAS ParsedAttr::asLangAS() const {
switch (getParsedKind()) {
case ParsedAttr::AT_OffloadGlobalAddressSpace:
return OffloadGlobalAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OffloadGlobalDeviceAddressSpace:
- return OffloadGlobalDeviceAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OffloadGlobalHostAddressSpace:
- return OffloadGlobalHostAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
+ return OpenCLGlobalDeviceAddressSpaceAttr::getLangAS(*this);
+ case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
+ return OpenCLGlobalHostAddressSpaceAttr::getLangAS(*this);
case ParsedAttr::AT_OffloadLocalAddressSpace:
return OffloadLocalAddressSpaceAttr::getLangAS(*this);
case ParsedAttr::AT_OffloadPrivateAddressSpace:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1fdf5c1a183c0..326910b564df1 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9096,8 +9096,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
break;
case ParsedAttr::AT_OffloadPrivateAddressSpace:
case ParsedAttr::AT_OffloadGlobalAddressSpace:
- case ParsedAttr::AT_OffloadGlobalDeviceAddressSpace:
- case ParsedAttr::AT_OffloadGlobalHostAddressSpace:
+ case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
+ case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
case ParsedAttr::AT_OffloadLocalAddressSpace:
case ParsedAttr::AT_OffloadConstantAddressSpace:
case ParsedAttr::AT_OffloadGenericAddressSpace:
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 0b0ec9fe2f09b..0112ccae4c775 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -70,12 +70,12 @@ void usages() {
bar(*GLOB_HOST);
bar2(*GLOB_HOST);
GLOB = GLOB_HOST;
- GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to 'sycl_global_host int *' changes address space of pointer}}
- GLOB_HOST = static_cast<__attribute__((sycl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_global_host int *' is not allowed}}
+ GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_host int *' changes address space of pointer}}
+ GLOB_HOST = static_cast<__attribute__((sycl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
__attribute__((sycl_global_device)) int *GLOB_DEVICE;
bar(*GLOB_DEVICE);
bar2(*GLOB_DEVICE);
GLOB = GLOB_DEVICE;
- GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to 'sycl_global_device int *' changes address space of pointer}}
- GLOB_DEVICE = static_cast<__attribute__((sycl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_global_device int *' is not allowed}}
+ GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
+ GLOB_DEVICE = static_cast<__attribute__((sycl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
}
>From 3461ac6844a5e2e1f4e5c30910a32d691ebecff7 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Mon, 8 Jun 2026 07:32:10 -0700
Subject: [PATCH 05/15] Revert "Choose address space mapping based on spelling"
This reverts commit bfe1c766e0e5a35afb834f3b8f2b787ffc261cb5.
---
clang/include/clang/Basic/Attr.td | 74 +------------------
clang/include/clang/Sema/ParsedAttr.h | 56 +++++++++++++-
clang/lib/Parse/ParseDecl.cpp | 2 +-
clang/lib/Sema/ParsedAttr.cpp | 24 ------
clang/lib/Sema/SemaType.cpp | 17 +++--
.../Builtins/generic_cast_to_ptr_explicit.c | 12 +--
.../CodeGenSYCL/address-space-conversions.cpp | 6 +-
.../amd-address-space-conversions.cpp | 24 +++---
.../cuda-address-space-conversions.cpp | 24 +++---
.../SemaSYCL/address-space-conversions.cpp | 8 +-
.../address-space-opencl-sycl-compat.cpp | 13 ++--
11 files changed, 107 insertions(+), 153 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 86ba95eef4d7c..aa0fb8d913322 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1795,112 +1795,42 @@ def OffloadPrivateAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__private">, CustomKeyword<"private">,
Clang<"opencl_private">, Clang<"sycl_private">];
let Documentation = [OffloadAddressSpacePrivateDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_private ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_private ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_private;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::sycl_private : LangAS::opencl_private;
- }
- }];
}
def OffloadGlobalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__global">, CustomKeyword<"global">,
Clang<"opencl_global">, Clang<"sycl_global">];
let Documentation = [OffloadAddressSpaceGlobalDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_global ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_global ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_global;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::sycl_global : LangAS::opencl_global;
- }
- }];
}
// TODO: Remove OpenCLGlobalDeviceAddressSpace after deprecation.
def OpenCLGlobalDeviceAddressSpace : TypeAttr {
- let Spellings = [Clang<"opencl_global_device">, Clang<"sycl_global_device">];
+ let Spellings = [Clang<"opencl_global_device">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_global_device ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_global_device ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_global_device;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::sycl_global_device : LangAS::opencl_global_device;
- }
- }];
}
// TODO: Remove OpenCLGlobalHostAddressSpace after deprecation.
def OpenCLGlobalHostAddressSpace : TypeAttr {
- let Spellings = [Clang<"opencl_global_host">, Clang<"sycl_global_host">];
+ let Spellings = [Clang<"opencl_global_host">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_global_host ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_global_host ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_global_host;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::sycl_global_host : LangAS::opencl_global_host;
- }
- }];
}
def OffloadLocalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__local">, CustomKeyword<"local">,
Clang<"opencl_local">, Clang<"sycl_local">];
let Documentation = [OffloadAddressSpaceLocalDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_local ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_local ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_local;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::sycl_local : LangAS::opencl_local;
- }
- }];
}
def OffloadConstantAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__constant">, CustomKeyword<"constant">,
Clang<"opencl_constant">, Clang<"sycl_constant">];
let Documentation = [OffloadAddressSpaceConstantDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_constant ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_constant ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_constant;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::Default : LangAS::opencl_constant;
- }
- }];
}
def OffloadGenericAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__generic">, CustomKeyword<"generic">,
Clang<"opencl_generic">, Clang<"sycl_generic">];
let Documentation = [OffloadAddressSpaceGenericDocs];
- let AdditionalMembers = [{
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_generic ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_generic ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_generic;
- }
- static inline LangAS getLangAS(const AttributeCommonInfo& A) {
- return isSYCLSpelling(A) ? LangAS::sycl_generic : LangAS::opencl_generic;
- }
- }];
}
def OpenCLNoSVM : Attr {
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index ddb26e89bdaa6..9251c8aafdc71 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -553,8 +553,60 @@ class ParsedAttr final
/// a Spelling enumeration, the value UINT_MAX is returned.
unsigned getSemanticSpelling() const;
- /// Returns the appropriate LangAS for this address space attribute.
- LangAS asLangAS() const;
+ /// If this is a named address space attribute for OpenCL compilation, returns its
+ /// representation in LangAS, otherwise returns default address space.
+ LangAS asOpenCLLangAS() const {
+ switch (getParsedKind()) {
+ case ParsedAttr::AT_OffloadConstantAddressSpace:
+ return LangAS::opencl_constant;
+ case ParsedAttr::AT_OffloadGlobalAddressSpace:
+ 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_OffloadLocalAddressSpace:
+ return LangAS::opencl_local;
+ case ParsedAttr::AT_OffloadPrivateAddressSpace:
+ return LangAS::opencl_private;
+ case ParsedAttr::AT_OffloadGenericAddressSpace:
+ return LangAS::opencl_generic;
+ default:
+ return LangAS::Default;
+ }
+ }
+
+ /// If this is a named address space attribute for SYCL compilation, returns its
+ /// representation in LangAS, otherwise returns default address space.
+ LangAS asSYCLLangAS() const {
+ switch (getKind()) {
+ case ParsedAttr::AT_OffloadGlobalAddressSpace:
+ return LangAS::sycl_global;
+ case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
+ return LangAS::sycl_global_device;
+ case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
+ return LangAS::sycl_global_host;
+ case ParsedAttr::AT_OffloadLocalAddressSpace:
+ return LangAS::sycl_local;
+ case ParsedAttr::AT_OffloadPrivateAddressSpace:
+ return LangAS::sycl_private;
+ case ParsedAttr::AT_OffloadGenericAddressSpace:
+ return LangAS::sycl_generic;
+ default:
+ return LangAS::Default;
+ }
+ }
+
+ /// If this is an HLSL address space attribute, returns its representation
+ /// in LangAS, otherwise returns default address space.
+ LangAS asHLSLLangAS() const {
+ switch (getParsedKind()) {
+ case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
+ return LangAS::hlsl_groupshared;
+ default:
+ return LangAS::Default;
+ }
+ }
AttributeCommonInfo::Kind getKind() const {
return AttributeCommonInfo::Kind(Info.AttrKind);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 1a4b92ca99b99..e2ac86bc5e064 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -7227,7 +7227,7 @@ void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
// prototype for the method.
if (getLangOpts().OpenCLCPlusPlus) {
for (ParsedAttr &attr : DS.getAttributes()) {
- LangAS ASIdx = attr.asLangAS();
+ LangAS ASIdx = attr.asOpenCLLangAS();
if (ASIdx != LangAS::Default) {
Q.addAddressSpace(ASIdx);
break;
diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp
index 08b9aea3bdb15..49dec6188d877 100644
--- a/clang/lib/Sema/ParsedAttr.cpp
+++ b/clang/lib/Sema/ParsedAttr.cpp
@@ -12,7 +12,6 @@
#include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"
@@ -313,26 +312,3 @@ void clang::takeAndConcatenateAttrs(ParsedAttributes &First,
if (Second.Range.getEnd().isValid())
First.Range.setEnd(Second.Range.getEnd());
}
-
-LangAS ParsedAttr::asLangAS() const {
- switch (getParsedKind()) {
- case ParsedAttr::AT_OffloadGlobalAddressSpace:
- return OffloadGlobalAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
- return OpenCLGlobalDeviceAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- return OpenCLGlobalHostAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OffloadLocalAddressSpace:
- return OffloadLocalAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OffloadPrivateAddressSpace:
- return OffloadPrivateAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OffloadConstantAddressSpace:
- return OffloadConstantAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_OffloadGenericAddressSpace:
- return OffloadGenericAddressSpaceAttr::getLangAS(*this);
- case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
- return LangAS::hlsl_groupshared;
- default:
- return LangAS::Default;
- }
-}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 326910b564df1..1d13e632c51d6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5407,7 +5407,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// them later while creating QualType.
if (FTI.MethodQualifiers)
for (ParsedAttr &attr : FTI.MethodQualifiers->getAttributes()) {
- LangAS ASIdxNew = attr.asLangAS();
+ LangAS ASIdxNew = attr.asOpenCLLangAS();
if (DiagnoseMultipleAddrSpaceAttributes(S, ASIdx, ASIdxNew,
attr.getLoc()))
D.setInvalidType(true);
@@ -6678,12 +6678,15 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
else
Attr.setInvalid();
} else {
- // Type attributes imply which address space to use.
- ASIdx = Attr.asLangAS();
-
- if (ASIdx == LangAS::Default &&
- Attr.getKind() == ParsedAttr::AT_OffloadConstantAddressSpace) {
- if (OffloadConstantAddressSpaceAttr::isSYCLSpelling(Attr))
+ // The keyword-based type attributes imply which address space to use.
+ ASIdx = S.getLangOpts().SYCLIsDevice ? Attr.asSYCLLangAS()
+ : Attr.asOpenCLLangAS();
+ if (S.getLangOpts().HLSL)
+ ASIdx = Attr.asHLSLLangAS();
+
+ if (ASIdx == LangAS::Default) {
+ if (S.getLangOpts().SYCLIsDevice &&
+ Attr.getKind() == ParsedAttr::AT_OffloadConstantAddressSpace)
S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
else
llvm_unreachable("Invalid address space");
diff --git a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
index b896d76897fbf..30f4ecb589a5c 100644
--- a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
+++ b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
@@ -4,14 +4,8 @@
#ifdef __SYCL_DEVICE_ONLY__
#define SYCL_EXTERNAL [[clang::sycl_external]]
-#define __global __attribute__((sycl_global))
-#define __local __attribute__((sycl_local))
-#define __private __attribute__((sycl_private))
#else
#define SYCL_EXTERNAL
-#define __global __attribute__((opencl_global))
-#define __local __attribute__((opencl_local))
-#define __private __attribute__((opencl_private))
#endif
// CHECK: spir_func noundef ptr @{{.*}}test_cast_to_private{{.*}}(ptr addrspace(4) noundef readnone [[P:%.*]]
@@ -19,7 +13,7 @@
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr [[SPV_CAST]]
//
-SYCL_EXTERNAL __private int* test_cast_to_private(int* p) {
+SYCL_EXTERNAL __attribute__((opencl_private)) int* test_cast_to_private(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 7);
}
@@ -28,7 +22,7 @@ SYCL_EXTERNAL __private int* test_cast_to_private(int* p) {
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr addrspace(1) [[SPV_CAST]]
//
-SYCL_EXTERNAL __global int* test_cast_to_global(int* p) {
+SYCL_EXTERNAL __attribute__((opencl_global)) int* test_cast_to_global(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 5);
}
@@ -37,6 +31,6 @@ SYCL_EXTERNAL __global int* test_cast_to_global(int* p) {
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr addrspace(3) [[SPV_CAST]]
//
-SYCL_EXTERNAL __local int* test_cast_to_local(int* p) {
+SYCL_EXTERNAL __attribute__((opencl_local)) int* test_cast_to_local(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 4);
}
diff --git a/clang/test/CodeGenSYCL/address-space-conversions.cpp b/clang/test/CodeGenSYCL/address-space-conversions.cpp
index f331b8367b614..3eecdded06364 100644
--- a/clang/test/CodeGenSYCL/address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/address-space-conversions.cpp
@@ -25,9 +25,9 @@ void tmpl(T t) {}
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3)
__attribute__((sycl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr
- __attribute__((sycl_global_device)) int *GLOBDEVICE;
+ __attribute__((opencl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5)
- __attribute__((sycl_global_host)) int *GLOBHOST;
+ __attribute__((opencl_global_host)) int *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(6)
// CHECK-DAG: [[NoAS]].ascast = addrspacecast ptr [[NoAS]] to ptr addrspace(4)
@@ -66,7 +66,7 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr [[NoAS_CAST]], ptr addrspace(4) [[PRIV]].ascast
PRIV = (__attribute__((sycl_private)) int *)NoAS;
- // From sycl_global_[host/device] address spaces to sycl_global
+ // From opencl_global_[host/device] address spaces to sycl_global
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr addrspace(4) [[GLOB_DEVICE]].ascast
// CHECK-DAG: [[GLOBDEVICE_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[GLOBDEVICE_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_CAST]], ptr addrspace(4) [[GLOB]].ascast
diff --git a/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp b/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
index a46b9660b2ef9..17a98195318ad 100644
--- a/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
-void bar(__attribute__((sycl_local)) int &Data) {}
+void bar(__attribute__((opencl_local)) int &Data) {}
// CHECK-DAG: define {{.*}} void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef %
void foo2(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef %
-void foo(__attribute__((sycl_local)) int *Data) {}
+void foo(__attribute__((opencl_local)) int *Data) {}
// CHECK-DAG: define {{.*}} void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t) {}
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8, addrspace(5)
- __attribute__((sycl_global)) int *GLOB;
+ __attribute__((opencl_global)) int *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
- __attribute__((sycl_local)) int *LOC;
+ __attribute__((opencl_local)) int *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 4, addrspace(5)
- __attribute__((sycl_private)) int *PRIV;
+ __attribute__((opencl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5), align 4, addrspace(5)
- __attribute__((sycl_global_device)) int *GLOBDEVICE;
+ __attribute__((opencl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
- __attribute__((sycl_global_host)) int *GLOBHOST;
+ __attribute__((opencl_global_host)) int *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
LOC = nullptr;
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]].ascast, align 4
@@ -45,22 +45,22 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr [[PRIV]].ascast, align 4
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr %5, ptr [[NoAS]].ascast, align 8
- GLOB = (__attribute__((sycl_global)) int *)NoAS;
+ GLOB = (__attribute__((opencl_global)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr %6 to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) %7, ptr [[GLOB]].ascast, align 8
- LOC = (__attribute__((sycl_local)) int *)NoAS;
+ LOC = (__attribute__((opencl_local)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) %9, ptr [[LOC]].ascast, align 4
- PRIV = (__attribute__((sycl_private)) int *)NoAS;
+ PRIV = (__attribute__((opencl_private)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(5)
// CHECK-DAG: store ptr addrspace(5) [[NoAS_CAST]], ptr [[PRIV]].ascast, align 4
- GLOB = (__attribute__((sycl_global)) int *)GLOBDEVICE;
+ GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]DEVICE.ascast, align 8
// CHECK-DAG: store ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8
- GLOB = (__attribute__((sycl_global)) int *)GLOBHOST;
+ GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]HOST.ascast, align 8
// CHECK-DAG: tore ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8
bar(*GLOB);
diff --git a/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp b/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
index 3427450547fce..ffb601e62c118 100644
--- a/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
-void bar(__attribute__((sycl_local)) int &Data) {}
+void bar(__attribute__((opencl_local)) int &Data) {}
// CHECK-DAG: define {{.*}} void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef %
void foo2(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef %
-void foo(__attribute__((sycl_local)) int *Data) {}
+void foo(__attribute__((opencl_local)) int *Data) {}
// CHECK-DAG: define {{.*}} void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t);
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8
- __attribute__((sycl_global)) int *GLOB;
+ __attribute__((opencl_global)) int *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
- __attribute__((sycl_local)) int *LOC;
+ __attribute__((opencl_local)) int *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 8
- __attribute__((sycl_private)) int *PRIV;
+ __attribute__((opencl_private)) int *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr, align 8
- __attribute__((sycl_global_device)) int *GLOBDEVICE;
+ __attribute__((opencl_global_device)) int *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
- __attribute__((sycl_global_host)) int *GLOBHOST;
+ __attribute__((opencl_global_host)) int *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
LOC = nullptr;
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]], align 8
@@ -44,21 +44,21 @@ void tmpl(T t);
NoAS = (int *)PRIV;
// CHECK-DAG: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[PRIV]], align 8
// CHECK-DAG: store ptr [[LOC_LOAD]], ptr [[NoAS]], align 8
- GLOB = (__attribute__((sycl_global)) int *)NoAS;
+ GLOB = (__attribute__((opencl_global)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[NoAS_CAST]], ptr [[GLOB]], align 8
- LOC = (__attribute__((sycl_local)) int *)NoAS;
+ LOC = (__attribute__((opencl_local)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) [[NoAS_CAST]], ptr [[LOC]], align 8
- PRIV = (__attribute__((sycl_private)) int *)NoAS;
+ PRIV = (__attribute__((opencl_private)) int *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: store ptr [[NoAS_LOAD]], ptr [[PRIV]], align 8
- GLOB = (__attribute__((sycl_global)) int *)GLOBDEVICE;
+ GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_DEVICE]], align 8
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_LOAD]], ptr %GLOB, align 8
- GLOB = (__attribute__((sycl_global)) int *)GLOBHOST;
+ GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
// CHECK-DAG: [[GLOB_HOST_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_HOST]], align 8
// CHECK-DAG: store ptr addrspace(1) [[GLOB_HOST_LOAD]], ptr [[GLOB]], align 8
bar(*GLOB);
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 0112ccae4c775..9d209dbe5f8d7 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -66,16 +66,16 @@ void usages() {
(void)i;
(void)v;
- __attribute__((sycl_global_host)) int *GLOB_HOST;
+ __attribute__((opencl_global_host)) int *GLOB_HOST;
bar(*GLOB_HOST);
bar2(*GLOB_HOST);
GLOB = GLOB_HOST;
GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_host int *' changes address space of pointer}}
- GLOB_HOST = static_cast<__attribute__((sycl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
- __attribute__((sycl_global_device)) int *GLOB_DEVICE;
+ GLOB_HOST = static_cast<__attribute__((opencl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
+ __attribute__((opencl_global_device)) int *GLOB_DEVICE;
bar(*GLOB_DEVICE);
bar2(*GLOB_DEVICE);
GLOB = GLOB_DEVICE;
GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
- GLOB_DEVICE = static_cast<__attribute__((sycl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
+ GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
}
diff --git a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
index 7b4575e60c8ad..89c4fa4873086 100644
--- a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
+++ b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
@@ -10,9 +10,9 @@ void test_incompatible() {
// Address space attributes are resolved using mode of compilation and not the spelling itself. This results in the SYCL spelling
// being used in both instances of each diagnostic despite openCL spelling being used.
- opencl_global = sycl_local; // expected-error {{assigning 'sycl_local int *' to '__global int *' changes address space of pointer}}
- opencl_global = sycl_private; // expected-error {{assigning 'sycl_private int *' to '__global int *' changes address space of pointer}}
- sycl_local = opencl_global; // expected-error {{assigning '__global int *' to 'sycl_local int *' changes address space of pointer}}
+ opencl_global = sycl_local; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
+ opencl_global = sycl_private; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
+ sycl_local = opencl_global; // expected-error {{assigning 'sycl_global int *' to 'sycl_local int *' changes address space of pointer}}
}
void test_to_generic_mixed() {
@@ -23,13 +23,12 @@ void test_to_generic_mixed() {
int [[clang::sycl_local]] *sycl_local;
int [[clang::sycl_private]] *sycl_private;
- //FIXME: Why don't these throw an error?
opencl_gen = sycl_local;
opencl_gen = sycl_private;
- sycl_gen = opencl_global; // expected-error {{assigning '__global int *' to 'sycl_generic int *' changes address space of pointer}}
+ sycl_gen = opencl_global;
}
-void overload_test(__attribute__((opencl_global)) int *p) { (void)p; }
-void overload_test(__attribute__((sycl_global)) int *p) { (void)p; }
+void overload_test(__attribute__((opencl_global)) int *p) { (void)p; } // expected-note {{previous definition is here}}
+void overload_test(__attribute__((sycl_global)) int *p) { (void)p; } // expected-error {{redefinition of 'overload_test'}}
>From 7613ed9cff0d306de2428fcd4075d9ce0ec11dde Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 10 Jun 2026 08:28:13 -0700
Subject: [PATCH 06/15] Apply review comments to separate out SYCL attributes.
---
clang/include/clang/Basic/AddressSpaces.h | 10 +-
clang/include/clang/Basic/Attr.td | 60 ++++--
clang/include/clang/Basic/AttrDocs.td | 98 +++++----
clang/include/clang/Sema/ParsedAttr.h | 31 +--
clang/lib/AST/TypePrinter.cpp | 15 +-
clang/lib/Headers/__clang_spirv_builtins.h | 192 ++++++++----------
clang/lib/Sema/ParsedAttr.cpp | 10 +-
clang/lib/Sema/SemaType.cpp | 21 +-
.../Builtins/generic_cast_to_ptr_explicit.c | 12 +-
.../CodeGenSYCL/address-space-conversions.cpp | 24 +--
.../CodeGenSYCL/address-space-mangling.cpp | 12 +-
.../amd-address-space-conversions.cpp | 24 +--
.../cuda-address-space-conversions.cpp | 24 +--
.../BuiltIns/generic_cast_to_ptr_explicit.c | 10 +-
.../SemaSYCL/address-space-conversions.cpp | 21 +-
.../address-space-opencl-sycl-compat.cpp | 34 ----
16 files changed, 301 insertions(+), 297 deletions(-)
delete mode 100644 clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h
index 58b04e50c2e3d..c3654ebbab82c 100644
--- a/clang/include/clang/Basic/AddressSpaces.h
+++ b/clang/include/clang/Basic/AddressSpaces.h
@@ -36,8 +36,9 @@ enum class LangAS : unsigned {
opencl_constant,
opencl_private,
opencl_generic,
- // TODO: Remove opencl_global_device and opencl_global_host after corresponding
- // attributes are deprecated for the required time.
+ // TODO: Remove opencl_global_device and opencl_global_host after
+ // corresponding attributes are deprecated for the required time.
+ // https://discourse.llvm.org/t/rfc-remove-opencl-global-device-and-opencl-global-host-address-space-attributes/90677
opencl_global_device,
opencl_global_host,
@@ -48,8 +49,9 @@ enum class LangAS : unsigned {
// SYCL specific address spaces.
sycl_global,
- // TODO: Remove sycl_global_device and sycl_global_host after corresponding attributes
- // are deprecated for the required time.
+ // TODO: Remove sycl_global_device and sycl_global_host after corresponding
+ // attributes are deprecated for the required time.
+ // https://discourse.llvm.org/t/rfc-remove-opencl-global-device-and-opencl-global-host-address-space-attributes/90677
sycl_global_device,
sycl_global_host,
sycl_local,
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index aa0fb8d913322..2f68fe1f91cc7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1791,16 +1791,16 @@ def OpenCLAccess : Attr {
let Documentation = [OpenCLAccessDocs];
}
-def OffloadPrivateAddressSpace : TypeAttr {
+def OpenCLPrivateAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__private">, CustomKeyword<"private">,
- Clang<"opencl_private">, Clang<"sycl_private">];
- let Documentation = [OffloadAddressSpacePrivateDocs];
+ Clang<"opencl_private">];
+ let Documentation = [OpenCLAddressSpacePrivateDocs];
}
-def OffloadGlobalAddressSpace : TypeAttr {
+def OpenCLGlobalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__global">, CustomKeyword<"global">,
- Clang<"opencl_global">, Clang<"sycl_global">];
- let Documentation = [OffloadAddressSpaceGlobalDocs];
+ Clang<"opencl_global">];
+ let Documentation = [OpenCLAddressSpaceGlobalDocs];
}
// TODO: Remove OpenCLGlobalDeviceAddressSpace after deprecation.
@@ -1815,22 +1815,52 @@ def OpenCLGlobalHostAddressSpace : TypeAttr {
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
}
-def OffloadLocalAddressSpace : TypeAttr {
+def OpenCLLocalAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__local">, CustomKeyword<"local">,
- Clang<"opencl_local">, Clang<"sycl_local">];
- let Documentation = [OffloadAddressSpaceLocalDocs];
+ Clang<"opencl_local">];
+ let Documentation = [OpenCLAddressSpaceLocalDocs];
}
-def OffloadConstantAddressSpace : TypeAttr {
+def OpenCLConstantAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__constant">, CustomKeyword<"constant">,
- Clang<"opencl_constant">, Clang<"sycl_constant">];
- let Documentation = [OffloadAddressSpaceConstantDocs];
+ Clang<"opencl_constant">];
+ let Documentation = [OpenCLAddressSpaceConstantDocs];
}
-def OffloadGenericAddressSpace : TypeAttr {
+def OpenCLGenericAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"__generic">, CustomKeyword<"generic">,
- Clang<"opencl_generic">, Clang<"sycl_generic">];
- let Documentation = [OffloadAddressSpaceGenericDocs];
+ Clang<"opencl_generic">];
+ let Documentation = [OpenCLAddressSpaceGenericDocs];
+}
+
+def SYCLPrivateAddressSpace : TypeAttr {
+ let Spellings = [CXX11<"clang", "sycl_private">];
+ let LangOpts = [SYCLHost, SYCLDevice];
+ let Documentation = [SYCLAddressSpaceDocs];
+}
+
+def SYCLGlobalAddressSpace : TypeAttr {
+ let Spellings = [CXX11<"clang", "sycl_global">];
+ let LangOpts = [SYCLHost, SYCLDevice];
+ let Documentation = [SYCLAddressSpaceDocs];
+}
+
+def SYCLLocalAddressSpace : TypeAttr {
+ let Spellings = [CXX11<"clang", "sycl_local">];
+ let LangOpts = [SYCLHost, SYCLDevice];
+ let Documentation = [SYCLAddressSpaceDocs];
+}
+
+def SYCLConstantAddressSpace : TypeAttr {
+ let Spellings = [CXX11<"clang", "sycl_constant">];
+ let LangOpts = [SYCLHost, SYCLDevice];
+ let Documentation = [SYCLAddressSpaceDocs];
+}
+
+def SYCLGenericAddressSpace : TypeAttr {
+ let Spellings = [CXX11<"clang", "sycl_generic">];
+ let LangOpts = [SYCLHost, SYCLDevice];
+ let Documentation = [SYCLAddressSpaceDocs];
}
def OpenCLNoSVM : Attr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 74a6d7edaa4a2..b058cc3d3fdbd 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -786,6 +786,27 @@ expression.
}];
}
+def SYCLAddressSpaceDocs : Documentation {
+ let Category = DocCatType;
+ let Heading = "Address space attributes for SYCL";
+ let Content = [{
+The memory model for SYCL devices is derived from the OpenCL memory model. Accordingly
+SYCL defines five address spaces: global, local, private, generic and constant. The
+following attributes correspond to these address spaces:
+
+[[clang::sycl_global]], [[clang::sycl_local]], [[clang::sycl_private]],
+[[clang::sycl_generic]] and [[clang::sycl_constant]] (deprecated)
+
+These attributes are intended for use in the implementation of SYCL run-time
+libraries. A direct declaration of pointers with address spaces is discouraged. Users
+should use the sycl::multi_ptr class to handle address space boundaries and
+interoperability.
+
+More details can be found in SYCL 2020 Specification, Section 3.8.2
+"SYCL device memory model" and Section 4.7.7, "Address space classes"
+ }];
+}
+
def SYCLSpecialClassDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
@@ -5003,20 +5024,13 @@ More details can be found in the OpenCL C language Spec v2.0, Section 6.6.
}];
}
-def DocOffloadAddressSpaces : DocumentationCategory<"OpenCL and SYCL Address Spaces"> {
+def DocOpenCLAddressSpaces : DocumentationCategory<"OpenCL Address Spaces"> {
let Content = [{
The address space qualifier may be used to specify the region of memory that is
-used to allocate the object.
-
-OpenCL supports the following address spaces:
-
-__generic(generic), __global(global), __local(local), __private(private) and
+used to allocate the object. OpenCL supports the following address spaces:
+__generic(generic), __global(global), __local(local), __private(private),
__constant(constant).
-More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
-
-Example:
-
.. code-block:: c
__constant int c = ...;
@@ -5028,32 +5042,14 @@ Example:
return l;
}
-The memory model for SYCL devices is derived from the OpenCL memory model. Accordingly
-SYCL defines five address spaces: global, local, private, generic and constant. The
-following attributes correspond to these address spaces:
-
-[[clang::sycl_global]], [[clang::sycl_local]], [[clang::sycl_private]],
-[[clang::sycl_generic]] and [[clang::sycl_constant]] (deprecated)
-
-These attributes are intended for use in the implementation of SYCL run-time
-libraries. A direct declaration of pointers with address spaces is discouraged. Users
-should use the sycl::multi_ptr class to handle address space boundaries and
-interoperability.
-
-More details can be found in SYCL 2020 Specification, Section 3.8.2
-"SYCL device memory model" and Section 4.7.7, "Address space classes"
+More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
}];
-
}
-def OffloadAddressSpaceGenericDocs : Documentation {
- let Category = DocOffloadAddressSpaces;
- let Heading = "__generic, generic, [[clang::opencl_generic]], [[clang::sycl_generic]]";
+def OpenCLAddressSpaceGenericDocs : Documentation {
+ let Category = DocOpenCLAddressSpaces;
+ let Heading = "__generic, generic, [[clang::opencl_generic]]";
let Content = [{
-The generic address space is a virtual address space which overlaps the global, local
-and private address spaces.
-
-OpenCL:
The generic address space attribute is only available with OpenCL v2.0 and later.
It can be used with pointer types. Variables in global and local scope and
function parameters in non-kernel functions can have the generic address space
@@ -5063,35 +5059,33 @@ spaces.
}];
}
-def OffloadAddressSpaceConstantDocs : Documentation {
- let Category = DocOffloadAddressSpaces;
- let Heading = "__constant, constant, [[clang::opencl_constant]], [[clang::sycl_constant]]";
+def OpenCLAddressSpaceConstantDocs : Documentation {
+ let Category = DocOpenCLAddressSpaces;
+ let Heading = "__constant, constant, [[clang::opencl_constant]]";
let Content = [{
The constant address space attribute signals that an object is located in
a constant (non-modifiable) memory region. It is available to all work items.
Any type can be annotated with the constant address space attribute. Objects
with the constant address space qualifier can be declared in any scope and must
-have an initializer. The constant address space is deprecated in SYCL 2020
-specification.
+have an initializer.
}];
}
-def OffloadAddressSpaceGlobalDocs : Documentation {
- let Category = DocOffloadAddressSpaces;
- let Heading = "__global, global, [[clang::opencl_global]], [[clang::sycl_global]]";
+def OpenCLAddressSpaceGlobalDocs : Documentation {
+ let Category = DocOpenCLAddressSpaces;
+ let Heading = "__global, global, [[clang::opencl_global]]";
let Content = [{
The global address space attribute specifies that an object is allocated in
global memory, which is accessible by all work items. The content stored in this
-memory area persists between kernel executions.
-
-In OpenCL, pointer types to the global address space are allowed as function parameters or
-local variables. Starting with OpenCL v2.0, the global address space can be used with global
-(program scope) variables and static local variable as well.
+memory area persists between kernel executions. Pointer types to the global
+address space are allowed as function parameters or local variables. Starting
+with OpenCL v2.0, the global address space can be used with global (program
+scope) variables and static local variable as well.
}];
}
def OpenCLAddressSpaceGlobalExtDocs : Documentation {
- let Category = DocOffloadAddressSpaces;
+ 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
@@ -5115,9 +5109,9 @@ As ``global_device`` and ``global_host`` are a subset of
}];
}
-def OffloadAddressSpaceLocalDocs : Documentation {
- let Category = DocOffloadAddressSpaces;
- let Heading = "__local, local, [[clang::opencl_local]], [[clang::sycl_local]]";
+def OpenCLAddressSpaceLocalDocs : Documentation {
+ let Category = DocOpenCLAddressSpaces;
+ let Heading = "__local, local, [[clang::opencl_local]]";
let Content = [{
The local address space specifies that an object is allocated in the local (work
group) memory area, which is accessible to all work items in the same work
@@ -5128,9 +5122,9 @@ space are allowed. Local address space variables cannot have an initializer.
}];
}
-def OffloadAddressSpacePrivateDocs : Documentation {
- let Category = DocOffloadAddressSpaces;
- let Heading = "__private, private, [[clang::opencl_private]], [[clang::sycl_private]]";
+def OpenCLAddressSpacePrivateDocs : Documentation {
+ let Category = DocOpenCLAddressSpaces;
+ let Heading = "__private, private, [[clang::opencl_private]]";
let Content = [{
The private address space specifies that an object is allocated in the private
(work item) memory. Other work items cannot access the same memory area and its
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 9251c8aafdc71..7dd1290000f7c 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -553,44 +553,47 @@ class ParsedAttr final
/// a Spelling enumeration, the value UINT_MAX is returned.
unsigned getSemanticSpelling() const;
- /// If this is a named address space attribute for OpenCL compilation, returns its
- /// representation in LangAS, otherwise returns default address space.
+ /// If this is an OpenCL address space attribute, returns its representation
+ /// in LangAS, otherwise returns default address space.
LangAS asOpenCLLangAS() const {
switch (getParsedKind()) {
- case ParsedAttr::AT_OffloadConstantAddressSpace:
+ case ParsedAttr::AT_OpenCLConstantAddressSpace:
return LangAS::opencl_constant;
- case ParsedAttr::AT_OffloadGlobalAddressSpace:
+ 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_OffloadLocalAddressSpace:
+ case ParsedAttr::AT_OpenCLLocalAddressSpace:
return LangAS::opencl_local;
- case ParsedAttr::AT_OffloadPrivateAddressSpace:
+ case ParsedAttr::AT_OpenCLPrivateAddressSpace:
return LangAS::opencl_private;
- case ParsedAttr::AT_OffloadGenericAddressSpace:
+ case ParsedAttr::AT_OpenCLGenericAddressSpace:
return LangAS::opencl_generic;
default:
return LangAS::Default;
}
}
- /// If this is a named address space attribute for SYCL compilation, returns its
- /// representation in LangAS, otherwise returns default address space.
+ /// If this is a SYCL address space attribute, returns its SYCL
+ /// representation in LangAS.
LangAS asSYCLLangAS() const {
- switch (getKind()) {
- case ParsedAttr::AT_OffloadGlobalAddressSpace:
+ switch (getParsedKind()) {
+ case ParsedAttr::AT_SYCLGlobalAddressSpace:
return LangAS::sycl_global;
+ // TODO: OpenCLGlobalDeviceAddressSpace and OpenCLGlobalHostAddressSpace
+ // will be removed after deprecation.
+ // https://discourse.llvm.org/t/rfc-remove-opencl-global-device-and-opencl-global-host-address-space-attributes/90677
case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
return LangAS::sycl_global_device;
case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
return LangAS::sycl_global_host;
- case ParsedAttr::AT_OffloadLocalAddressSpace:
+ case ParsedAttr::AT_SYCLLocalAddressSpace:
return LangAS::sycl_local;
- case ParsedAttr::AT_OffloadPrivateAddressSpace:
+ case ParsedAttr::AT_SYCLPrivateAddressSpace:
return LangAS::sycl_private;
- case ParsedAttr::AT_OffloadGenericAddressSpace:
+ case ParsedAttr::AT_SYCLGenericAddressSpace:
return LangAS::sycl_generic;
default:
return LangAS::Default;
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ed5d95c360303..1ac5566c31904 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1992,14 +1992,19 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::HLSLResourceDimension:
llvm_unreachable("HLSL resource type attributes handled separately");
- case attr::OffloadPrivateAddressSpace:
- case attr::OffloadGlobalAddressSpace:
+ case attr::OpenCLPrivateAddressSpace:
+ case attr::OpenCLGlobalAddressSpace:
case attr::OpenCLGlobalDeviceAddressSpace:
case attr::OpenCLGlobalHostAddressSpace:
- case attr::OffloadLocalAddressSpace:
- case attr::OffloadConstantAddressSpace:
- case attr::OffloadGenericAddressSpace:
+ case attr::OpenCLLocalAddressSpace:
+ case attr::OpenCLConstantAddressSpace:
+ case attr::OpenCLGenericAddressSpace:
case attr::HLSLGroupSharedAddressSpace:
+ case attr::SYCLPrivateAddressSpace:
+ case attr::SYCLGlobalAddressSpace:
+ case attr::SYCLLocalAddressSpace:
+ case attr::SYCLConstantAddressSpace:
+ case attr::SYCLGenericAddressSpace:
// FIXME: Update printAttributedBefore to print these once we generate
// AttributedType nodes for them.
break;
diff --git a/clang/lib/Headers/__clang_spirv_builtins.h b/clang/lib/Headers/__clang_spirv_builtins.h
index 9b3ac8c134ab1..4a5af96fdf1e0 100644
--- a/clang/lib/Headers/__clang_spirv_builtins.h
+++ b/clang/lib/Headers/__clang_spirv_builtins.h
@@ -27,17 +27,15 @@
#define __SPIRV_inline __attribute__((always_inline))
#ifdef __SYCL_DEVICE_ONLY__
-#define __global __attribute__((sycl_global))
-#define __local __attribute__((sycl_local))
-#define __private __attribute__((sycl_private))
-#define __constant __attribute__((sycl_constant))
-#define __generic __attribute__((sycl_generic))
+#define __GLOBALAS [[clang::sycl_global]]
+#define __LOCALAS [[clang::sycl_local]]
+#define __PRIVATEAS [[clang::sycl_private]]
+#define __GENERICAS [[clang::sycl_generic]]
#else
-#define __global __attribute__((opencl_global))
-#define __local __attribute__((opencl_local))
-#define __private __attribute__((opencl_private))
-#define __constant __attribute__((opencl_constant))
-#define __generic __attribute__((opencl_generic))
+#define __GLOBALAS __attribute__((opencl_global))
+#define __LOCALAS __attribute__((opencl_local))
+#define __PRIVATEAS __attribute__((opencl_private))
+#define __GENERICAS __attribute__((opencl_generic))
#endif
// Check if SPIR-V builtins are supported.
@@ -83,123 +81,113 @@ extern __SPIRV_BUILTIN_ALIAS(__builtin_spirv_subgroup_local_invocation_id)
// OpGenericCastToPtrExplicit
+extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
+ __builtin_spirv_generic_cast_to_ptr_explicit) void __GLOBALAS
+ *__spirv_GenericCastToPtrExplicit_ToGlobal(void __GENERICAS *,
+ int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__global void *__spirv_GenericCastToPtrExplicit_ToGlobal(__generic void *,
- int) __SPIRV_NOEXCEPT;
+ __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
+ void __GLOBALAS *__spirv_GenericCastToPtrExplicit_ToGlobal(
+ const void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
+ __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __GLOBALAS
+ *__spirv_GenericCastToPtrExplicit_ToGlobal(volatile void __GENERICAS *,
+ int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__global const void *
-__spirv_GenericCastToPtrExplicit_ToGlobal(__generic const void *,
- int) __SPIRV_NOEXCEPT;
+ __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
+ volatile void __GLOBALAS *__spirv_GenericCastToPtrExplicit_ToGlobal(
+ const volatile void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
+ __builtin_spirv_generic_cast_to_ptr_explicit) void __LOCALAS
+ *__spirv_GenericCastToPtrExplicit_ToLocal(void __GENERICAS *,
+ int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__global volatile void *
-__spirv_GenericCastToPtrExplicit_ToGlobal(__generic volatile void *,
- int) __SPIRV_NOEXCEPT;
+ __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
+ void __LOCALAS *__spirv_GenericCastToPtrExplicit_ToLocal(
+ const void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
+ __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __LOCALAS
+ *__spirv_GenericCastToPtrExplicit_ToLocal(volatile void __GENERICAS *,
+ int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__global const volatile void *
-__spirv_GenericCastToPtrExplicit_ToGlobal(__generic const volatile void *,
- int) __SPIRV_NOEXCEPT;
+ __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
+ volatile void __LOCALAS *__spirv_GenericCastToPtrExplicit_ToLocal(
+ const volatile void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
+ __builtin_spirv_generic_cast_to_ptr_explicit) void __PRIVATEAS
+ *__spirv_GenericCastToPtrExplicit_ToPrivate(void __GENERICAS *,
+ int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__local void *__spirv_GenericCastToPtrExplicit_ToLocal(__generic void *,
- int) __SPIRV_NOEXCEPT;
+ __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
+ void __PRIVATEAS *__spirv_GenericCastToPtrExplicit_ToPrivate(
+ const void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
+ __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __PRIVATEAS
+ *__spirv_GenericCastToPtrExplicit_ToPrivate(volatile void __GENERICAS *,
+ int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__local const void *
-__spirv_GenericCastToPtrExplicit_ToLocal(__generic const void *,
- int) __SPIRV_NOEXCEPT;
-extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__local volatile void *
-__spirv_GenericCastToPtrExplicit_ToLocal(__generic volatile void *,
- int) __SPIRV_NOEXCEPT;
-extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__local const volatile void *
-__spirv_GenericCastToPtrExplicit_ToLocal(__generic const volatile void *,
- int) __SPIRV_NOEXCEPT;
-extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__private void *
-__spirv_GenericCastToPtrExplicit_ToPrivate(__generic void *,
- int) __SPIRV_NOEXCEPT;
-extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__private const void *
-__spirv_GenericCastToPtrExplicit_ToPrivate(__generic const void *,
- int) __SPIRV_NOEXCEPT;
-extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__private volatile void *
-__spirv_GenericCastToPtrExplicit_ToPrivate(__generic volatile void *,
- int) __SPIRV_NOEXCEPT;
-extern __SPIRV_overloadable
-__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
-__private const volatile void *
-__spirv_GenericCastToPtrExplicit_ToPrivate(__generic const volatile void *,
- int) __SPIRV_NOEXCEPT;
+ __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
+ volatile void __PRIVATEAS *__spirv_GenericCastToPtrExplicit_ToPrivate(
+ const volatile void __GENERICAS *, int) __SPIRV_NOEXCEPT;
// OpGenericCastToPtr
-static __SPIRV_overloadable __SPIRV_inline __global void *
-__spirv_GenericCastToPtr_ToGlobal(__generic void *p, int) __SPIRV_NOEXCEPT {
- return (__global void *)p;
+static __SPIRV_overloadable __SPIRV_inline void __GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(void __GENERICAS *p, int) __SPIRV_NOEXCEPT {
+ return (void __GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __global const void *
-__spirv_GenericCastToPtr_ToGlobal(__generic const void *p,
+static __SPIRV_overloadable __SPIRV_inline const void __GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(const void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__global const void *)p;
+ return (const void __GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __global volatile void *
-__spirv_GenericCastToPtr_ToGlobal(__generic volatile void *p,
+static __SPIRV_overloadable __SPIRV_inline volatile void __GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(volatile void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__global volatile void *)p;
+ return (volatile void __GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __global const volatile void *
-__spirv_GenericCastToPtr_ToGlobal(__generic const volatile void *p,
+static __SPIRV_overloadable __SPIRV_inline const volatile void __GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(const volatile void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__global const volatile void *)p;
+ return (const volatile void __GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __local void *
-__spirv_GenericCastToPtr_ToLocal(__generic void *p, int) __SPIRV_NOEXCEPT {
- return (__local void *)p;
+static __SPIRV_overloadable __SPIRV_inline void __LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(void __GENERICAS *p, int) __SPIRV_NOEXCEPT {
+ return (void __LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __local const void *
-__spirv_GenericCastToPtr_ToLocal(__generic const void *p,
+static __SPIRV_overloadable __SPIRV_inline const void __LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(const void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__local const void *)p;
+ return (const void __LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __local volatile void *
-__spirv_GenericCastToPtr_ToLocal(__generic volatile void *p,
+static __SPIRV_overloadable __SPIRV_inline volatile void __LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(volatile void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__local volatile void *)p;
+ return (volatile void __LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __local const volatile void *
-__spirv_GenericCastToPtr_ToLocal(__generic const volatile void *p,
+static __SPIRV_overloadable __SPIRV_inline const volatile void __LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(const volatile void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__local const volatile void *)p;
+ return (const volatile void __LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __private void *
-__spirv_GenericCastToPtr_ToPrivate(__generic void *p, int) __SPIRV_NOEXCEPT {
- return (__private void *)p;
+static __SPIRV_overloadable __SPIRV_inline void __PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(void __GENERICAS *p, int) __SPIRV_NOEXCEPT {
+ return (void __PRIVATEAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __private const void *
-__spirv_GenericCastToPtr_ToPrivate(__generic const void *p,
+static __SPIRV_overloadable __SPIRV_inline const void __PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(const void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__private const void *)p;
+ return (const void __PRIVATEAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __private volatile void *
-__spirv_GenericCastToPtr_ToPrivate(__generic volatile void *p,
+static __SPIRV_overloadable __SPIRV_inline volatile void __PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(volatile void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__private volatile void *)p;
+ return (volatile void __PRIVATEAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline __private const volatile void *
-__spirv_GenericCastToPtr_ToPrivate(__generic const volatile void *p,
+static __SPIRV_overloadable __SPIRV_inline const volatile void __PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(const volatile void __GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (__private const volatile void *)p;
+ return (const volatile void __PRIVATEAS *)p;
}
#pragma pop_macro("__size_t")
@@ -210,10 +198,10 @@ __spirv_GenericCastToPtr_ToPrivate(__generic const volatile void *p,
#undef __SPIRV_convergent
#undef __SPIRV_inline
-#undef __global
-#undef __local
-#undef __constant
-#undef __generic
+#undef __GLOBALAS
+#undef __LOCALAS
+#undef __PRIVATEAS
+#undef __GENERICAS
#undef __SPIRV_BUILTIN_ALIAS
#undef __SPIRV_NOEXCEPT
diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp
index 49dec6188d877..2b5ad33ad7b29 100644
--- a/clang/lib/Sema/ParsedAttr.cpp
+++ b/clang/lib/Sema/ParsedAttr.cpp
@@ -228,13 +228,13 @@ bool ParsedAttr::slidesFromDeclToDeclSpecLegacyBehavior() const {
// possible, we would like this list to go away entirely.
switch (getParsedKind()) {
case AT_AddressSpace:
- case AT_OffloadPrivateAddressSpace:
- case AT_OffloadGlobalAddressSpace:
+ case AT_OpenCLPrivateAddressSpace:
+ case AT_OpenCLGlobalAddressSpace:
case AT_OpenCLGlobalDeviceAddressSpace:
case AT_OpenCLGlobalHostAddressSpace:
- case AT_OffloadLocalAddressSpace:
- case AT_OffloadConstantAddressSpace:
- case AT_OffloadGenericAddressSpace:
+ case AT_OpenCLLocalAddressSpace:
+ case AT_OpenCLConstantAddressSpace:
+ case AT_OpenCLGenericAddressSpace:
case AT_NeonPolyVectorType:
case AT_NeonVectorType:
case AT_ArmMveStrictPolymorphism:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1d13e632c51d6..3c2fcffcde85b 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6685,11 +6685,11 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
ASIdx = Attr.asHLSLLangAS();
if (ASIdx == LangAS::Default) {
- if (S.getLangOpts().SYCLIsDevice &&
- Attr.getKind() == ParsedAttr::AT_OffloadConstantAddressSpace)
+ if (Attr.getKind() == ParsedAttr::AT_SYCLConstantAddressSpace) {
S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
- else
+ } else {
llvm_unreachable("Invalid address space");
+ }
}
if (DiagnoseMultipleAddrSpaceAttributes(S, Type.getAddressSpace(), ASIdx,
@@ -9097,14 +9097,19 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
// it it breaks large amounts of Linux software.
attr.setUsedAsTypeAttr();
break;
- case ParsedAttr::AT_OffloadPrivateAddressSpace:
- case ParsedAttr::AT_OffloadGlobalAddressSpace:
+ case ParsedAttr::AT_OpenCLPrivateAddressSpace:
+ case ParsedAttr::AT_OpenCLGlobalAddressSpace:
case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- case ParsedAttr::AT_OffloadLocalAddressSpace:
- case ParsedAttr::AT_OffloadConstantAddressSpace:
- case ParsedAttr::AT_OffloadGenericAddressSpace:
+ case ParsedAttr::AT_OpenCLLocalAddressSpace:
+ case ParsedAttr::AT_OpenCLConstantAddressSpace:
+ case ParsedAttr::AT_OpenCLGenericAddressSpace:
case ParsedAttr::AT_AddressSpace:
+ case ParsedAttr::AT_SYCLPrivateAddressSpace:
+ case ParsedAttr::AT_SYCLGlobalAddressSpace:
+ case ParsedAttr::AT_SYCLLocalAddressSpace:
+ case ParsedAttr::AT_SYCLConstantAddressSpace:
+ case ParsedAttr::AT_SYCLGenericAddressSpace:
HandleAddressSpaceTypeAttribute(type, attr, state);
attr.setUsedAsTypeAttr();
break;
diff --git a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
index 30f4ecb589a5c..640186a012444 100644
--- a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
+++ b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c
@@ -4,8 +4,14 @@
#ifdef __SYCL_DEVICE_ONLY__
#define SYCL_EXTERNAL [[clang::sycl_external]]
+#define GLOBALAS [[clang::sycl_global]]
+#define LOCALAS [[clang::sycl_local]]
+#define PRIVATEAS [[clang::sycl_private]]
#else
#define SYCL_EXTERNAL
+#define GLOBALAS __attribute__((opencl_global))
+#define LOCALAS __attribute__((opencl_local))
+#define PRIVATEAS __attribute__((opencl_private))
#endif
// CHECK: spir_func noundef ptr @{{.*}}test_cast_to_private{{.*}}(ptr addrspace(4) noundef readnone [[P:%.*]]
@@ -13,7 +19,7 @@
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr [[SPV_CAST]]
//
-SYCL_EXTERNAL __attribute__((opencl_private)) int* test_cast_to_private(int* p) {
+SYCL_EXTERNAL int PRIVATEAS * test_cast_to_private(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 7);
}
@@ -22,7 +28,7 @@ SYCL_EXTERNAL __attribute__((opencl_private)) int* test_cast_to_private(int* p)
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr addrspace(1) [[SPV_CAST]]
//
-SYCL_EXTERNAL __attribute__((opencl_global)) int* test_cast_to_global(int* p) {
+SYCL_EXTERNAL int GLOBALAS * test_cast_to_global(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 5);
}
@@ -31,6 +37,6 @@ SYCL_EXTERNAL __attribute__((opencl_global)) int* test_cast_to_global(int* p) {
// CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4) %p)
// CHECK-NEXT: ret ptr addrspace(3) [[SPV_CAST]]
//
-SYCL_EXTERNAL __attribute__((opencl_local)) int* test_cast_to_local(int* p) {
+SYCL_EXTERNAL int LOCALAS * test_cast_to_local(int* p) {
return __builtin_spirv_generic_cast_to_ptr_explicit(p, 4);
}
diff --git a/clang/test/CodeGenSYCL/address-space-conversions.cpp b/clang/test/CodeGenSYCL/address-space-conversions.cpp
index 3eecdded06364..811f776cc845f 100644
--- a/clang/test/CodeGenSYCL/address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef align 4 dereferenceable(4) %
-void bar(__attribute__((sycl_local)) int &Data) {}
+void bar(int [[clang::sycl_local]] &Data) {}
// CHECK-DAG: define{{.*}} void [[LOC_REF:@[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef %
void foo2(int *Data) {}
// CHECK-DAG: define{{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr addrspace(4) noundef %
-void foo(__attribute__((sycl_local)) int *Data) {}
+void foo(int [[clang::sycl_local]] *Data) {}
// CHECK-DAG: define{{.*}} void [[LOC_PTR:@[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t) {}
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr addrspace(4)
- __attribute__((sycl_global)) int *GLOB;
+ int [[clang::sycl_global]] *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1)
- __attribute__((sycl_local)) int *LOC;
+ int [[clang::sycl_local]] *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3)
- __attribute__((sycl_private)) int *PRIV;
+ int [[clang::sycl_private]] *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr
- __attribute__((opencl_global_device)) int *GLOBDEVICE;
+ int __attribute__((opencl_global_device)) *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5)
- __attribute__((opencl_global_host)) int *GLOBHOST;
+ int __attribute__((opencl_global_host)) *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(6)
// CHECK-DAG: [[NoAS]].ascast = addrspacecast ptr [[NoAS]] to ptr addrspace(4)
@@ -57,24 +57,24 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[NoAS]].ascast
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[NoAS_CAST]], ptr addrspace(4) [[GLOB]].ascast
- GLOB = (__attribute__((sycl_global)) int *)NoAS;
+ GLOB = (int [[clang::sycl_global]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[NoAS]].ascast
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) [[NoAS_CAST]], ptr addrspace(4) [[LOC]].ascast
- LOC = (__attribute__((sycl_local)) int *)NoAS;
+ LOC = (int [[clang::sycl_local]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(4), ptr addrspace(4) [[NoAS]].ascast
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(4) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr [[NoAS_CAST]], ptr addrspace(4) [[PRIV]].ascast
- PRIV = (__attribute__((sycl_private)) int *)NoAS;
+ PRIV = (int [[clang::sycl_private]] *)NoAS;
// From opencl_global_[host/device] address spaces to sycl_global
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr addrspace(4) [[GLOB_DEVICE]].ascast
// CHECK-DAG: [[GLOBDEVICE_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[GLOBDEVICE_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_CAST]], ptr addrspace(4) [[GLOB]].ascast
- GLOB = (__attribute__((sycl_global)) int *)GLOBDEVICE;
+ GLOB = (int [[clang::sycl_global]] *)GLOBDEVICE;
// CHECK-DAG: [[GLOBHOST_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(6), ptr addrspace(4) [[GLOB_HOST]].ascast
// CHECK-DAG: [[GLOBHOST_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(6) [[GLOBHOST_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[GLOBHOST_CAST]], ptr addrspace(4) [[GLOB]].ascast
- GLOB = (__attribute__((sycl_global)) int *)GLOBHOST;
+ GLOB = (int [[clang::sycl_global]] *)GLOBHOST;
bar(*GLOB);
// CHECK-DAG: [[GLOB_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr addrspace(4) [[GLOB]].ascast
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index 3e44be24ffc3e..c006905ab82cd 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -3,9 +3,9 @@
// REQUIRES: x86-registered-target
-void foo(__attribute__((sycl_global)) int *);
-void foo(__attribute__((sycl_local)) int *);
-void foo(__attribute__((sycl_private)) int *);
+void foo(int [[clang::sycl_global]] *);
+void foo(int [[clang::sycl_local]] *);
+void foo(int [[clang::sycl_private]] *);
void foo(int *);
// SPIR: declare spir_func void @_Z3fooPU3AS1i(ptr addrspace(1) noundef) #1
@@ -19,9 +19,9 @@ void foo(int *);
// X86: declare void @_Z3fooPi(ptr noundef) #1
[[clang::sycl_external]] void test() {
- __attribute__((sycl_global)) int *glob;
- __attribute__((sycl_local)) int *loc;
- __attribute__((sycl_private)) int *priv;
+ int [[clang::sycl_global]] *glob;
+ int [[clang::sycl_local]] *loc;
+ int [[clang::sycl_private]] *priv;
int *def;
foo(glob);
foo(loc);
diff --git a/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp b/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
index 17a98195318ad..3ead6a7533860 100644
--- a/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/amd-address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
-void bar(__attribute__((opencl_local)) int &Data) {}
+void bar(int [[clang::sycl_local]] &Data) {}
// CHECK-DAG: define {{.*}} void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef %
void foo2(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef %
-void foo(__attribute__((opencl_local)) int *Data) {}
+void foo(int [[clang::sycl_local]] *Data) {}
// CHECK-DAG: define {{.*}} void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t) {}
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8, addrspace(5)
- __attribute__((opencl_global)) int *GLOB;
+ int [[clang::sycl_global]] *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
- __attribute__((opencl_local)) int *LOC;
+ int [[clang::sycl_local]] *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 4, addrspace(5)
- __attribute__((opencl_private)) int *PRIV;
+ int [[clang::sycl_private]] *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr addrspace(5), align 4, addrspace(5)
- __attribute__((opencl_global_device)) int *GLOBDEVICE;
+ int __attribute__((opencl_global_device)) *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
- __attribute__((opencl_global_host)) int *GLOBHOST;
+ int __attribute__((opencl_global_host)) *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8, addrspace(5)
LOC = nullptr;
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]].ascast, align 4
@@ -45,22 +45,22 @@ void tmpl(T t) {}
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(5), ptr [[PRIV]].ascast, align 4
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr addrspace(5) [[NoAS_LOAD]] to ptr
// CHECK-DAG: store ptr %5, ptr [[NoAS]].ascast, align 8
- GLOB = (__attribute__((opencl_global)) int *)NoAS;
+ GLOB = (int [[clang::sycl_global]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr %6 to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) %7, ptr [[GLOB]].ascast, align 8
- LOC = (__attribute__((opencl_local)) int *)NoAS;
+ LOC = (int [[clang::sycl_local]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) %9, ptr [[LOC]].ascast, align 4
- PRIV = (__attribute__((opencl_private)) int *)NoAS;
+ PRIV = (int [[clang::sycl_private]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]].ascast, align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(5)
// CHECK-DAG: store ptr addrspace(5) [[NoAS_CAST]], ptr [[PRIV]].ascast, align 4
- GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
+ GLOB = (int [[clang::sycl_global]] *)GLOBDEVICE;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]DEVICE.ascast, align 8
// CHECK-DAG: store ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8
- GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
+ GLOB = (int [[clang::sycl_global]] *)GLOBHOST;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB]]HOST.ascast, align 8
// CHECK-DAG: tore ptr addrspace(1) [[NoAS_LOAD]], ptr [[GLOB]].ascast, align 8
bar(*GLOB);
diff --git a/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp b/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
index ffb601e62c118..305c86c0ef09b 100644
--- a/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
+++ b/clang/test/CodeGenSYCL/cuda-address-space-conversions.cpp
@@ -3,13 +3,13 @@ void bar(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
void bar2(int &Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_REF2:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) %
-void bar(__attribute__((opencl_local)) int &Data) {}
+void bar(int [[clang::sycl_local]] &Data) {}
// CHECK-DAG: define {{.*}} void @[[LOCAL_REF:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef align 4 dereferenceable(4) %
void foo(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR:[a-zA-Z0-9_]+]](ptr noundef %
void foo2(int *Data) {}
// CHECK-DAG: define {{.*}} void @[[RAW_PTR2:[a-zA-Z0-9_]+]](ptr noundef %
-void foo(__attribute__((opencl_local)) int *Data) {}
+void foo(int [[clang::sycl_local]] *Data) {}
// CHECK-DAG: define {{.*}} void @[[LOC_PTR:[a-zA-Z0-9_]+]](ptr addrspace(3) noundef %
template <typename T>
@@ -19,15 +19,15 @@ void tmpl(T t);
[[clang::sycl_external]] void usages() {
int *NoAS;
// CHECK-DAG: [[NoAS:%[a-zA-Z0-9]+]] = alloca ptr, align 8
- __attribute__((opencl_global)) int *GLOB;
+ int [[clang::sycl_global]] *GLOB;
// CHECK-DAG: [[GLOB:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
- __attribute__((opencl_local)) int *LOC;
+ int [[clang::sycl_local]] *LOC;
// CHECK-DAG: [[LOC:%[a-zA-Z0-9]+]] = alloca ptr addrspace(3), align 8
- __attribute__((opencl_private)) int *PRIV;
+ int [[clang::sycl_private]] *PRIV;
// CHECK-DAG: [[PRIV:%[a-zA-Z0-9]+]] = alloca ptr, align 8
- __attribute__((opencl_global_device)) int *GLOBDEVICE;
+ int __attribute__((opencl_global_device)) *GLOBDEVICE;
// CHECK-DAG: [[GLOB_DEVICE:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
- __attribute__((opencl_global_host)) int *GLOBHOST;
+ int __attribute__((opencl_global_host)) *GLOBHOST;
// CHECK-DAG: [[GLOB_HOST:%[a-zA-Z0-9]+]] = alloca ptr addrspace(1), align 8
LOC = nullptr;
// CHECK-DAG: store ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3)), ptr [[LOC]], align 8
@@ -44,21 +44,21 @@ void tmpl(T t);
NoAS = (int *)PRIV;
// CHECK-DAG: [[LOC_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[PRIV]], align 8
// CHECK-DAG: store ptr [[LOC_LOAD]], ptr [[NoAS]], align 8
- GLOB = (__attribute__((opencl_global)) int *)NoAS;
+ GLOB = (int [[clang::sycl_global]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(1)
// CHECK-DAG: store ptr addrspace(1) [[NoAS_CAST]], ptr [[GLOB]], align 8
- LOC = (__attribute__((opencl_local)) int *)NoAS;
+ LOC = (int [[clang::sycl_local]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: [[NoAS_CAST:%[a-zA-Z0-9]+]] = addrspacecast ptr [[NoAS_LOAD]] to ptr addrspace(3)
// CHECK-DAG: store ptr addrspace(3) [[NoAS_CAST]], ptr [[LOC]], align 8
- PRIV = (__attribute__((opencl_private)) int *)NoAS;
+ PRIV = (int [[clang::sycl_private]] *)NoAS;
// CHECK-DAG: [[NoAS_LOAD:%[a-zA-Z0-9]+]] = load ptr, ptr [[NoAS]], align 8
// CHECK-DAG: store ptr [[NoAS_LOAD]], ptr [[PRIV]], align 8
- GLOB = (__attribute__((opencl_global)) int *)GLOBDEVICE;
+ GLOB = (int [[clang::sycl_global]] *)GLOBDEVICE;
// CHECK-DAG: [[GLOBDEVICE_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_DEVICE]], align 8
// CHECK-DAG: store ptr addrspace(1) [[GLOBDEVICE_LOAD]], ptr %GLOB, align 8
- GLOB = (__attribute__((opencl_global)) int *)GLOBHOST;
+ GLOB = (int [[clang::sycl_global]] *)GLOBHOST;
// CHECK-DAG: [[GLOB_HOST_LOAD:%[a-zA-Z0-9]+]] = load ptr addrspace(1), ptr [[GLOB_HOST]], align 8
// CHECK-DAG: store ptr addrspace(1) [[GLOB_HOST_LOAD]], ptr [[GLOB]], align 8
bar(*GLOB);
diff --git a/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c b/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c
index 5a839961e20f5..13d595d87d114 100644
--- a/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c
+++ b/clang/test/SemaSPIRV/BuiltIns/generic_cast_to_ptr_explicit.c
@@ -1,7 +1,13 @@
-// RUN: %clang_cc1 -O1 -triple spirv64 -fsycl-is-device -verify %s -o -
+// RUN: %clang_cc1 -O1 -triple spirv64 -fsycl-is-device -x c++ -verify %s -o -
// RUN: %clang_cc1 -O1 -triple spirv64 -verify %s -cl-std=CL3.0 -x cl -o -
// RUN: %clang_cc1 -O1 -triple spirv32 -verify %s -cl-std=CL3.0 -x cl -o -
+#ifdef __SYCL_DEVICE_ONLY__
+#define LOCALAS [[clang::sycl_local]]
+#else
+#define LOCALAS __attribute__((opencl_local))
+#endif
+
void test_missing_arguments(int* p) {
__builtin_spirv_generic_cast_to_ptr_explicit(p);
// expected-error at -1 {{too few arguments to function call, expected 2, have 1}}
@@ -14,7 +20,7 @@ void test_wrong_flag_value(int* p) {
// expected-error at -1 {{invalid value for storage class argument}}
}
-void test_wrong_address_space(__attribute__((opencl_local)) int* p) {
+void test_wrong_address_space(int LOCALAS * p) {
__builtin_spirv_generic_cast_to_ptr_explicit(p, 14);
// expected-error at -1 {{expecting a pointer argument to the generic address space}}
}
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 9d209dbe5f8d7..41dec2e926418 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -2,26 +2,25 @@
void bar(int &Data) {}
void bar2(int &Data) {}
-void bar(__attribute__((sycl_private)) int &Data) {}
+void bar(int [[clang::sycl_private]] &Data) {}
void foo(int *Data) {}
void foo2(int *Data) {}
-void foo(__attribute__((sycl_private)) int *Data) {}
-void baz(__attribute__((sycl_private)) int *Data) {} // expected-note {{candidate function not viable: cannot pass pointer to generic address space as a pointer to address space 'sycl_private' in 1st argument}}
+void foo(int [[clang::sycl_private]] *Data) {}
+void baz(int [[clang::sycl_private]] *Data) {} // expected-note {{candidate function not viable: cannot pass pointer to generic address space as a pointer to address space 'sycl_private' in 1st argument}}
template <typename T>
void tmpl(T *t) {}
void usages() {
- __attribute__((sycl_global)) int *GLOB;
- __attribute__((sycl_private)) int *PRIV;
- __attribute__((sycl_local)) int *LOC;
- __attribute__((sycl_constant)) int *ptr1; // expected-warning {{'sycl_constant' address space attribute is deprecated}}
+ int [[clang::sycl_global]] *GLOB;
+ int [[clang::sycl_private]] *PRIV;
+ int [[clang::sycl_local]] *LOC;
int *NoAS;
GLOB = PRIV; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
GLOB = LOC; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
- PRIV = static_cast<__attribute__((sycl_private)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_private int *' is not allowed}}
- PRIV = static_cast<__attribute__((sycl_private)) int *>(LOC); // expected-error {{static_cast from 'sycl_local int *' to 'sycl_private int *' is not allowed}}
+ PRIV = static_cast<int [[clang::sycl_private]] *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_private int *' is not allowed}}
+ PRIV = static_cast<int [[clang::sycl_private]] *>(LOC); // expected-error {{static_cast from 'sycl_local int *' to 'sycl_private int *' is not allowed}}
NoAS = GLOB + PRIV; // expected-error {{invalid operands to binary expression ('sycl_global int *' and 'sycl_private int *')}}
NoAS = GLOB + LOC; // expected-error {{invalid operands to binary expression ('sycl_global int *' and 'sycl_local int *')}}
NoAS += GLOB; // expected-error {{invalid operands to binary expression ('int *' and 'sycl_global int *')}}
@@ -54,10 +53,10 @@ void usages() {
// Implicit casts to named address space are disallowed
baz(NoAS); // expected-error {{no matching function for call to 'baz'}}
- __attribute__((sycl_local)) int *l = NoAS; // expected-error {{cannot initialize a variable of type 'sycl_local int *' with an lvalue of type 'int *'}}
+ int [[clang::sycl_local]] *l = NoAS; // expected-error {{cannot initialize a variable of type 'sycl_local int *' with an lvalue of type 'int *'}}
// Explicit casts between disjoint address spaces are disallowed
- GLOB = (__attribute__((sycl_global)) int *)PRIV; // expected-error {{C-style cast from 'sycl_private int *' to 'sycl_global int *' converts between mismatching address spaces}}
+ GLOB = (int [[clang::sycl_global]] *)PRIV; // expected-error {{C-style cast from 'sycl_private int *' to 'sycl_global int *' converts between mismatching address spaces}}
(void)static_cast<int *>(GLOB);
(void)static_cast<void *>(GLOB);
diff --git a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp b/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
deleted file mode 100644
index 89c4fa4873086..0000000000000
--- a/clang/test/SemaSYCL/address-space-opencl-sycl-compat.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only %s
-
-// Test openCL and SYCL spelling conversions for address space
-// attributes.
-
-void test_incompatible() {
- __attribute__((opencl_global)) int *opencl_global;
- int [[clang::sycl_local]] *sycl_local;
- int [[clang::sycl_private]] *sycl_private;
-
- // Address space attributes are resolved using mode of compilation and not the spelling itself. This results in the SYCL spelling
- // being used in both instances of each diagnostic despite openCL spelling being used.
- opencl_global = sycl_local; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
- opencl_global = sycl_private; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
- sycl_local = opencl_global; // expected-error {{assigning 'sycl_global int *' to 'sycl_local int *' changes address space of pointer}}
-}
-
-void test_to_generic_mixed() {
- __attribute__((opencl_generic)) int *opencl_gen;
- int [[clang::sycl_generic]] *sycl_gen;
-
- __attribute__((opencl_global)) int *opencl_global;
- int [[clang::sycl_local]] *sycl_local;
- int [[clang::sycl_private]] *sycl_private;
-
- opencl_gen = sycl_local;
- opencl_gen = sycl_private;
- sycl_gen = opencl_global;
-
-}
-
-void overload_test(__attribute__((opencl_global)) int *p) { (void)p; } // expected-note {{previous definition is here}}
-void overload_test(__attribute__((sycl_global)) int *p) { (void)p; } // expected-error {{redefinition of 'overload_test'}}
-
>From d0e0728b79a56f2455fd95f0f5da21ac95aab1f4 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 10 Jun 2026 11:35:01 -0700
Subject: [PATCH 07/15] Add sycl_constant LangAS based on review comments.
---
clang/include/clang/Basic/AddressSpaces.h | 1 +
clang/include/clang/Sema/ParsedAttr.h | 2 ++
clang/lib/AST/ItaniumMangle.cpp | 6 +++-
clang/lib/AST/TypePrinter.cpp | 2 ++
clang/lib/Basic/TargetInfo.cpp | 1 +
clang/lib/Basic/Targets/AArch64.h | 1 +
clang/lib/Basic/Targets/AMDGPU.cpp | 2 ++
clang/lib/Basic/Targets/DirectX.h | 1 +
clang/lib/Basic/Targets/NVPTX.h | 1 +
clang/lib/Basic/Targets/SPIR.h | 2 ++
clang/lib/Basic/Targets/SystemZ.h | 1 +
clang/lib/Basic/Targets/TCE.h | 1 +
clang/lib/Basic/Targets/WebAssembly.h | 1 +
clang/lib/Basic/Targets/X86.h | 1 +
clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 2 ++
clang/lib/Sema/SemaType.cpp | 12 ++++----
.../CodeGenSYCL/address-space-mangling.cpp | 14 ++++++++--
.../SemaSYCL/address-space-conversions.cpp | 28 +++++++++++++++++++
.../SemaTemplate/address_space-dependent.cpp | 4 +--
19 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h
index c3654ebbab82c..849770a0237f1 100644
--- a/clang/include/clang/Basic/AddressSpaces.h
+++ b/clang/include/clang/Basic/AddressSpaces.h
@@ -57,6 +57,7 @@ enum class LangAS : unsigned {
sycl_local,
sycl_private,
sycl_generic,
+ sycl_constant,
// Pointer size and extension address spaces.
ptr32_sptr,
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 7dd1290000f7c..93e47622587a9 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -595,6 +595,8 @@ class ParsedAttr final
return LangAS::sycl_private;
case ParsedAttr::AT_SYCLGenericAddressSpace:
return LangAS::sycl_generic;
+ case ParsedAttr::AT_SYCLConstantAddressSpace:
+ return LangAS::sycl_constant;
default:
return LangAS::Default;
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 6be573966781c..a11c8b5d0837e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2822,7 +2822,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
ASString = "CLgeneric";
break;
// <SYCL-addrspace> ::= "SY" [ "global" | "local" | "private" |
- // "generic" | "device" | "host" ]
+ // "generic" | "constant" | "device" | "host"
+ // ]
case LangAS::sycl_global:
ASString = "SYglobal";
break;
@@ -2841,6 +2842,9 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
case LangAS::sycl_generic:
ASString = "SYgeneric";
break;
+ case LangAS::sycl_constant:
+ ASString = "SYconstant";
+ break;
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
case LangAS::cuda_device:
ASString = "CUdevice";
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 1ac5566c31904..9d0f12c23323b 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2697,6 +2697,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "sycl_private";
case LangAS::sycl_generic:
return "sycl_generic";
+ case LangAS::sycl_constant:
+ return "sycl_constant";
case LangAS::cuda_device:
return "__device__";
case LangAS::cuda_constant:
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 1d91bbaee21ef..cf589230812f0 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -45,6 +45,7 @@ static const LangASMap FakeAddrSpaceMap = {
3, // sycl_local
0, // sycl_private
4, // sycl_generic
+ 2, // sycl_constant
10, // ptr32_sptr
11, // ptr32_uptr
12, // ptr64
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 90d8401149c37..8aad44a0964ad 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -42,6 +42,7 @@ static const unsigned ARM64AddrSpaceMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
static_cast<unsigned>(AArch64AddrSpace::ptr32_sptr),
static_cast<unsigned>(AArch64AddrSpace::ptr32_uptr),
static_cast<unsigned>(AArch64AddrSpace::ptr64),
diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp
index 5d102e015790f..5ca444353d34b 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -44,6 +44,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local
llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_generic
+ llvm::AMDGPUAS::CONSTANT_ADDRESS, // sycl_constant
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
@@ -77,6 +78,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private
llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_generic
+ llvm::AMDGPUAS::CONSTANT_ADDRESS, // sycl_constant
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 6eb770f4a960e..e72b2f20f12a6 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -39,6 +39,7 @@ static const unsigned DirectXAddrSpaceMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 62bf6a514d444..53a1a034f916e 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -43,6 +43,7 @@ static const unsigned NVPTXAddrSpaceMap[] = {
3, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 88a9e5841b5a3..49df361832475 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -45,6 +45,7 @@ static const unsigned SPIRDefIsPrivMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
@@ -84,6 +85,7 @@ static const unsigned SPIRDefIsGenMap[] = {
3, // sycl_local
0, // sycl_private
4, // sycl_generic
+ 2, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index bc597fe30165b..da996382ad15b 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -39,6 +39,7 @@ static const unsigned ZOSAddressMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
0, // ptr32_sptr
1, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index d7086b23232c4..ab8a720517d83 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -48,6 +48,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h
index b0ee4505625c2..aca9b9fa15f60 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -39,6 +39,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 31fb984caac51..dfd57f0aa1e60 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -43,6 +43,7 @@ static const unsigned X86AddrSpaceMap[] = {
0, // sycl_local
0, // sycl_private
0, // sycl_generic
+ 0, // sycl_constant
270, // ptr32_sptr
271, // ptr32_uptr
272, // ptr64
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 9f2342254a882..3c14f90e64ed0 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -1042,6 +1042,8 @@ cir::LangAddressSpace cir::toCIRLangAddressSpace(clang::LangAS langAS) {
case LangAS::sycl_global_host:
case LangAS::sycl_local:
case LangAS::sycl_private:
+ case LangAS::sycl_generic:
+ case LangAS::sycl_constant:
case LangAS::ptr32_sptr:
case LangAS::ptr32_uptr:
case LangAS::ptr64:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3c2fcffcde85b..70c6b9b895848 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6684,13 +6684,11 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
if (S.getLangOpts().HLSL)
ASIdx = Attr.asHLSLLangAS();
- if (ASIdx == LangAS::Default) {
- if (Attr.getKind() == ParsedAttr::AT_SYCLConstantAddressSpace) {
- S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
- } else {
- llvm_unreachable("Invalid address space");
- }
- }
+ if (ASIdx == LangAS::sycl_constant)
+ S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
+
+ if (ASIdx == LangAS::Default)
+ llvm_unreachable("Invalid address space");
if (DiagnoseMultipleAddrSpaceAttributes(S, Type.getAddressSpace(), ASIdx,
Attr.getLoc())) {
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index c006905ab82cd..b92c93269026a 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -1,30 +1,40 @@
-// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=SPIR
-// RUN: %clang_cc1 -triple x86_64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=X86
+// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - -Wno-deprecated-attributes | FileCheck %s --check-prefix=SPIR
+// RUN: %clang_cc1 -triple x86_64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - -Wno-deprecated-attributes | FileCheck %s --check-prefix=X86
// REQUIRES: x86-registered-target
void foo(int [[clang::sycl_global]] *);
void foo(int [[clang::sycl_local]] *);
void foo(int [[clang::sycl_private]] *);
+void foo(int [[clang::sycl_generic]] *);
+void foo(int [[clang::sycl_constant]] *);
void foo(int *);
// SPIR: declare spir_func void @_Z3fooPU3AS1i(ptr addrspace(1) noundef) #1
// SPIR: declare spir_func void @_Z3fooPU3AS3i(ptr addrspace(3) noundef) #1
// SPIR: declare spir_func void @_Z3fooPU3AS0i(ptr noundef) #1
+// SPIR: declare spir_func void @_Z3fooPU3AS4i(ptr addrspace(4) noundef) #1
+// SPIR: declare spir_func void @_Z3fooPU3AS2i(ptr addrspace(2) noundef) #1
// SPIR: declare spir_func void @_Z3fooPi(ptr addrspace(4) noundef) #1
// X86: declare void @_Z3fooPU8SYglobali(ptr noundef) #1
// X86: declare void @_Z3fooPU7SYlocali(ptr noundef) #1
// X86: declare void @_Z3fooPU9SYprivatei(ptr noundef) #1
+// X86: declare void @_Z3fooPU9SYgenerici(ptr noundef) #1
+// X86: declare void @_Z3fooPU10SYconstanti(ptr noundef) #1
// X86: declare void @_Z3fooPi(ptr noundef) #1
[[clang::sycl_external]] void test() {
int [[clang::sycl_global]] *glob;
int [[clang::sycl_local]] *loc;
int [[clang::sycl_private]] *priv;
+ int [[clang::sycl_generic]] *gen;
+ int [[clang::sycl_constant]] *cnst;
int *def;
foo(glob);
foo(loc);
foo(priv);
+ foo(gen);
+ foo(cnst);
foo(def);
}
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 41dec2e926418..5afb7748fa434 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -15,6 +15,7 @@ void usages() {
int [[clang::sycl_global]] *GLOB;
int [[clang::sycl_private]] *PRIV;
int [[clang::sycl_local]] *LOC;
+ int [[clang::sycl_constant]] *CONST; // expected-warning {{'sycl_constant' address space attribute is deprecated}}
int *NoAS;
GLOB = PRIV; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
@@ -77,4 +78,31 @@ void usages() {
GLOB = GLOB_DEVICE;
GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
+
+ // Test sycl_constant conversions
+ // constant -> constant: OK
+ int [[clang::sycl_constant]] *c2 = CONST; // expected-warning {{'sycl_constant' address space attribute is deprecated}}
+ (void)c2;
+
+ // constant -> other named: ERROR (disjoint address spaces)
+ GLOB = CONST; // expected-error {{assigning 'sycl_constant int *' to 'sycl_global int *' changes address space of pointer}}
+ PRIV = CONST; // expected-error {{assigning 'sycl_constant int *' to 'sycl_private int *' changes address space of pointer}}
+ LOC = CONST; // expected-error {{assigning 'sycl_constant int *' to 'sycl_local int *' changes address space of pointer}}
+
+ // constant -> generic: ERROR (constant not a subset of generic)
+ NoAS = CONST; // expected-error {{assigning 'sycl_constant int *' to 'int *' changes address space of pointer}}
+
+ // generic -> constant: ERROR (constant not a superset of generic)
+ CONST = NoAS; // expected-error {{assigning 'int *' to 'sycl_constant int *' changes address space of pointer}}
+
+ // other named -> constant: ERROR (disjoint address spaces)
+ CONST = GLOB; // expected-error {{assigning 'sycl_global int *' to 'sycl_constant int *' changes address space of pointer}}
+ CONST = PRIV; // expected-error {{assigning 'sycl_private int *' to 'sycl_constant int *' changes address space of pointer}}
+ CONST = LOC; // expected-error {{assigning 'sycl_local int *' to 'sycl_constant int *' changes address space of pointer}}
+
+ // Explicit casts between constant and other spaces are disallowed
+ GLOB = (int [[clang::sycl_global]] *)CONST; // expected-error {{C-style cast from 'sycl_constant int *' to 'sycl_global int *' converts between mismatching address spaces}}
+ CONST = (int [[clang::sycl_constant]] *)GLOB; // expected-warning {{'sycl_constant' address space attribute is deprecated}} expected-error {{C-style cast from 'sycl_global int *' to 'sycl_constant int *' converts between mismatching address spaces}}
+ PRIV = static_cast<int [[clang::sycl_private]] *>(CONST); // expected-error {{static_cast from 'sycl_constant int *' to 'sycl_private int *' is not allowed}}
+ CONST = static_cast<int [[clang::sycl_constant]] *>(PRIV); // expected-warning {{'sycl_constant' address space attribute is deprecated}} expected-error {{static_cast from 'sycl_private int *' to 'sycl_constant int *' is not allowed}}
}
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index d6f25923b69b5..f4d2af956a324 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 (8388579)}}
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388578)}}
}
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<0x7FFFE3>();
+ correct<0x7FFFE2>();
tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
__attribute__((address_space(1))) char *x;
>From d343f9387db04240eeefce6d0cac480cd33abac0 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Tue, 16 Jun 2026 03:43:11 -0700
Subject: [PATCH 08/15] Apply review comments
---
.../clang/Basic/DiagnosticSemaKinds.td | 3 -
clang/include/clang/Sema/ParsedAttr.h | 5 +-
clang/lib/AST/Type.cpp | 6 +-
clang/lib/AST/TypePrinter.cpp | 13 +-
clang/lib/Basic/Targets/NVPTX.h | 2 +-
clang/lib/Headers/__clang_spirv_builtins.h | 155 +++++++++---------
clang/lib/Sema/SemaType.cpp | 3 -
.../SemaSYCL/address-space-conversions.cpp | 56 +++----
8 files changed, 122 insertions(+), 121 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 45ab89aa9ebc4..4cd4efc55c416 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3597,9 +3597,6 @@ def err_attribute_address_multiple_qualifiers : Error<
def warn_attribute_address_multiple_identical_qualifiers : Warning<
"multiple identical address spaces specified for type">,
InGroup<DuplicateDeclSpecifier>;
-def warn_deprecated_sycl_constant : Warning<
- "'sycl_constant' address space attribute is deprecated">,
- InGroup<DeprecatedAttributes>;
def err_attribute_not_clinkage : Error<
"function type with %0 attribute must have C linkage">;
def err_function_decl_cmse_ns_call : Error<
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 93e47622587a9..529275812a6dc 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -582,8 +582,9 @@ class ParsedAttr final
switch (getParsedKind()) {
case ParsedAttr::AT_SYCLGlobalAddressSpace:
return LangAS::sycl_global;
- // TODO: OpenCLGlobalDeviceAddressSpace and OpenCLGlobalHostAddressSpace
- // will be removed after deprecation.
+ // TODO: OpenCLGlobalDeviceAddressSpace, OpenCLGlobalHostAddressSpace,
+ // sycl_global_device, and sycl_global_host will be removed after
+ // deprecation.
// https://discourse.llvm.org/t/rfc-remove-opencl-global-device-and-opencl-global-host-address-space-attributes/90677
case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
return LangAS::sycl_global_device;
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index f368b75600d58..587e3896fa599 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -89,9 +89,9 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
(B == LangAS::sycl_private || B == LangAS::sycl_local ||
B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
B == LangAS::sycl_global_host)) ||
- // Consider sycl_generic address space to be equivalent to default.
- (A == LangAS::Default && B == LangAS::sycl_generic) ||
- (B == LangAS::Default && A == LangAS::sycl_generic) ||
+ // Consider sycl_generic address space to be equivalent to default.
+ (A == LangAS::Default && B == LangAS::sycl_generic) ||
+ (B == LangAS::Default && A == LangAS::sycl_generic) ||
// In HIP device compilation, any cuda address space is allowed
// to implicitly cast into the default address space.
(A == LangAS::Default &&
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 9d0f12c23323b..e6d19772254d0 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2007,7 +2007,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::SYCLGenericAddressSpace:
// FIXME: Update printAttributedBefore to print these once we generate
// AttributedType nodes for them.
- break;
+ llvm_unreachable("Address space attributes handled separately");
+ ;
case attr::CountedBy:
case attr::CountedByOrNull:
@@ -2690,15 +2691,15 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
case LangAS::sycl_global_host:
return "__global_host";
case LangAS::sycl_global:
- return "sycl_global";
+ return "[[clang::sycl_global]]";
case LangAS::sycl_local:
- return "sycl_local";
+ return "[[clang::sycl_local]]";
case LangAS::sycl_private:
- return "sycl_private";
+ return "[[clang::sycl_private]]";
case LangAS::sycl_generic:
- return "sycl_generic";
+ return "[[clang::sycl_generic]]";
case LangAS::sycl_constant:
- return "sycl_constant";
+ return "[[clang::sycl_constant]]";
case LangAS::cuda_device:
return "__device__";
case LangAS::cuda_constant:
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 53a1a034f916e..1cf6c4024085e 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -43,7 +43,7 @@ static const unsigned NVPTXAddrSpaceMap[] = {
3, // sycl_local
0, // sycl_private
0, // sycl_generic
- 0, // sycl_constant
+ 4, // sycl_constant
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
diff --git a/clang/lib/Headers/__clang_spirv_builtins.h b/clang/lib/Headers/__clang_spirv_builtins.h
index 4a5af96fdf1e0..055f0e8b8402f 100644
--- a/clang/lib/Headers/__clang_spirv_builtins.h
+++ b/clang/lib/Headers/__clang_spirv_builtins.h
@@ -27,15 +27,15 @@
#define __SPIRV_inline __attribute__((always_inline))
#ifdef __SYCL_DEVICE_ONLY__
-#define __GLOBALAS [[clang::sycl_global]]
-#define __LOCALAS [[clang::sycl_local]]
-#define __PRIVATEAS [[clang::sycl_private]]
-#define __GENERICAS [[clang::sycl_generic]]
+#define __SPIRV_GLOBALAS [[clang::sycl_global]]
+#define __SPIRV_LOCALAS [[clang::sycl_local]]
+#define __SPIRV_PRIVATEAS [[clang::sycl_private]]
+#define __SPIRV_GENERICAS [[clang::sycl_generic]]
#else
-#define __GLOBALAS __attribute__((opencl_global))
-#define __LOCALAS __attribute__((opencl_local))
-#define __PRIVATEAS __attribute__((opencl_private))
-#define __GENERICAS __attribute__((opencl_generic))
+#define __SPIRV_GLOBALAS __attribute__((opencl_global))
+#define __SPIRV_LOCALAS __attribute__((opencl_local))
+#define __SPIRV_PRIVATEAS __attribute__((opencl_private))
+#define __SPIRV_GENERICAS __attribute__((opencl_generic))
#endif
// Check if SPIR-V builtins are supported.
@@ -82,112 +82,117 @@ extern __SPIRV_BUILTIN_ALIAS(__builtin_spirv_subgroup_local_invocation_id)
// OpGenericCastToPtrExplicit
extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
- __builtin_spirv_generic_cast_to_ptr_explicit) void __GLOBALAS
- *__spirv_GenericCastToPtrExplicit_ToGlobal(void __GENERICAS *,
+ __builtin_spirv_generic_cast_to_ptr_explicit) void __SPIRV_GLOBALAS
+ *__spirv_GenericCastToPtrExplicit_ToGlobal(void __SPIRV_GENERICAS *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
- void __GLOBALAS *__spirv_GenericCastToPtrExplicit_ToGlobal(
- const void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+ void __SPIRV_GLOBALAS *__spirv_GenericCastToPtrExplicit_ToGlobal(
+ const void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
- __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __GLOBALAS
- *__spirv_GenericCastToPtrExplicit_ToGlobal(volatile void __GENERICAS *,
- int) __SPIRV_NOEXCEPT;
+ __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __SPIRV_GLOBALAS
+ *__spirv_GenericCastToPtrExplicit_ToGlobal(
+ volatile void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
- volatile void __GLOBALAS *__spirv_GenericCastToPtrExplicit_ToGlobal(
- const volatile void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+ volatile void __SPIRV_GLOBALAS *__spirv_GenericCastToPtrExplicit_ToGlobal(
+ const volatile void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
- __builtin_spirv_generic_cast_to_ptr_explicit) void __LOCALAS
- *__spirv_GenericCastToPtrExplicit_ToLocal(void __GENERICAS *,
+ __builtin_spirv_generic_cast_to_ptr_explicit) void __SPIRV_LOCALAS
+ *__spirv_GenericCastToPtrExplicit_ToLocal(void __SPIRV_GENERICAS *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
- void __LOCALAS *__spirv_GenericCastToPtrExplicit_ToLocal(
- const void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+ void __SPIRV_LOCALAS *__spirv_GenericCastToPtrExplicit_ToLocal(
+ const void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
- __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __LOCALAS
- *__spirv_GenericCastToPtrExplicit_ToLocal(volatile void __GENERICAS *,
+ __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __SPIRV_LOCALAS
+ *__spirv_GenericCastToPtrExplicit_ToLocal(volatile void __SPIRV_GENERICAS *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
- volatile void __LOCALAS *__spirv_GenericCastToPtrExplicit_ToLocal(
- const volatile void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+ volatile void __SPIRV_LOCALAS *__spirv_GenericCastToPtrExplicit_ToLocal(
+ const volatile void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
- __builtin_spirv_generic_cast_to_ptr_explicit) void __PRIVATEAS
- *__spirv_GenericCastToPtrExplicit_ToPrivate(void __GENERICAS *,
+ __builtin_spirv_generic_cast_to_ptr_explicit) void __SPIRV_PRIVATEAS
+ *__spirv_GenericCastToPtrExplicit_ToPrivate(void __SPIRV_GENERICAS *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
- void __PRIVATEAS *__spirv_GenericCastToPtrExplicit_ToPrivate(
- const void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+ void __SPIRV_PRIVATEAS *__spirv_GenericCastToPtrExplicit_ToPrivate(
+ const void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable __SPIRV_BUILTIN_ALIAS(
- __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __PRIVATEAS
- *__spirv_GenericCastToPtrExplicit_ToPrivate(volatile void __GENERICAS *,
- int) __SPIRV_NOEXCEPT;
+ __builtin_spirv_generic_cast_to_ptr_explicit) volatile void __SPIRV_PRIVATEAS
+ *__spirv_GenericCastToPtrExplicit_ToPrivate(
+ volatile void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) const
- volatile void __PRIVATEAS *__spirv_GenericCastToPtrExplicit_ToPrivate(
- const volatile void __GENERICAS *, int) __SPIRV_NOEXCEPT;
+ volatile void __SPIRV_PRIVATEAS *__spirv_GenericCastToPtrExplicit_ToPrivate(
+ const volatile void __SPIRV_GENERICAS *, int) __SPIRV_NOEXCEPT;
// OpGenericCastToPtr
-static __SPIRV_overloadable __SPIRV_inline void __GLOBALAS *
-__spirv_GenericCastToPtr_ToGlobal(void __GENERICAS *p, int) __SPIRV_NOEXCEPT {
- return (void __GLOBALAS *)p;
-}
-static __SPIRV_overloadable __SPIRV_inline const void __GLOBALAS *
-__spirv_GenericCastToPtr_ToGlobal(const void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline void __SPIRV_GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (const void __GLOBALAS *)p;
+ return (void __SPIRV_GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline volatile void __GLOBALAS *
-__spirv_GenericCastToPtr_ToGlobal(volatile void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline const void __SPIRV_GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(const void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (volatile void __GLOBALAS *)p;
+ return (const void __SPIRV_GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline const volatile void __GLOBALAS *
-__spirv_GenericCastToPtr_ToGlobal(const volatile void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline volatile void __SPIRV_GLOBALAS *
+__spirv_GenericCastToPtr_ToGlobal(volatile void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (const volatile void __GLOBALAS *)p;
+ return (volatile void __SPIRV_GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline void __LOCALAS *
-__spirv_GenericCastToPtr_ToLocal(void __GENERICAS *p, int) __SPIRV_NOEXCEPT {
- return (void __LOCALAS *)p;
+static __SPIRV_overloadable
+ __SPIRV_inline const volatile void __SPIRV_GLOBALAS *
+ __spirv_GenericCastToPtr_ToGlobal(const volatile void __SPIRV_GENERICAS *p,
+ int) __SPIRV_NOEXCEPT {
+ return (const volatile void __SPIRV_GLOBALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline const void __LOCALAS *
-__spirv_GenericCastToPtr_ToLocal(const void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline void __SPIRV_LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (const void __LOCALAS *)p;
+ return (void __SPIRV_LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline volatile void __LOCALAS *
-__spirv_GenericCastToPtr_ToLocal(volatile void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline const void __SPIRV_LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(const void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (volatile void __LOCALAS *)p;
+ return (const void __SPIRV_LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline const volatile void __LOCALAS *
-__spirv_GenericCastToPtr_ToLocal(const volatile void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline volatile void __SPIRV_LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(volatile void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (const volatile void __LOCALAS *)p;
+ return (volatile void __SPIRV_LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline void __PRIVATEAS *
-__spirv_GenericCastToPtr_ToPrivate(void __GENERICAS *p, int) __SPIRV_NOEXCEPT {
- return (void __PRIVATEAS *)p;
+static __SPIRV_overloadable __SPIRV_inline const volatile void __SPIRV_LOCALAS *
+__spirv_GenericCastToPtr_ToLocal(const volatile void __SPIRV_GENERICAS *p,
+ int) __SPIRV_NOEXCEPT {
+ return (const volatile void __SPIRV_LOCALAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline const void __PRIVATEAS *
-__spirv_GenericCastToPtr_ToPrivate(const void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline void __SPIRV_PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (const void __PRIVATEAS *)p;
+ return (void __SPIRV_PRIVATEAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline volatile void __PRIVATEAS *
-__spirv_GenericCastToPtr_ToPrivate(volatile void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline const void __SPIRV_PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(const void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (volatile void __PRIVATEAS *)p;
+ return (const void __SPIRV_PRIVATEAS *)p;
}
-static __SPIRV_overloadable __SPIRV_inline const volatile void __PRIVATEAS *
-__spirv_GenericCastToPtr_ToPrivate(const volatile void __GENERICAS *p,
+static __SPIRV_overloadable __SPIRV_inline volatile void __SPIRV_PRIVATEAS *
+__spirv_GenericCastToPtr_ToPrivate(volatile void __SPIRV_GENERICAS *p,
int) __SPIRV_NOEXCEPT {
- return (const volatile void __PRIVATEAS *)p;
+ return (volatile void __SPIRV_PRIVATEAS *)p;
+}
+static __SPIRV_overloadable
+ __SPIRV_inline const volatile void __SPIRV_PRIVATEAS *
+ __spirv_GenericCastToPtr_ToPrivate(const volatile void __SPIRV_GENERICAS *p,
+ int) __SPIRV_NOEXCEPT {
+ return (const volatile void __SPIRV_PRIVATEAS *)p;
}
#pragma pop_macro("__size_t")
@@ -198,10 +203,10 @@ __spirv_GenericCastToPtr_ToPrivate(const volatile void __GENERICAS *p,
#undef __SPIRV_convergent
#undef __SPIRV_inline
-#undef __GLOBALAS
-#undef __LOCALAS
-#undef __PRIVATEAS
-#undef __GENERICAS
+#undef __SPIRV_GLOBALAS
+#undef __SPIRV_LOCALAS
+#undef __SPIRV_PRIVATEAS
+#undef __SPIRV_GENERICAS
#undef __SPIRV_BUILTIN_ALIAS
#undef __SPIRV_NOEXCEPT
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 70c6b9b895848..825c375f1a2cb 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6684,9 +6684,6 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
if (S.getLangOpts().HLSL)
ASIdx = Attr.asHLSLLangAS();
- if (ASIdx == LangAS::sycl_constant)
- S.Diag(Attr.getLoc(), diag::warn_deprecated_sycl_constant);
-
if (ASIdx == LangAS::Default)
llvm_unreachable("Invalid address space");
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 5afb7748fa434..4574b1db5550e 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -6,7 +6,7 @@ void bar(int [[clang::sycl_private]] &Data) {}
void foo(int *Data) {}
void foo2(int *Data) {}
void foo(int [[clang::sycl_private]] *Data) {}
-void baz(int [[clang::sycl_private]] *Data) {} // expected-note {{candidate function not viable: cannot pass pointer to generic address space as a pointer to address space 'sycl_private' in 1st argument}}
+void baz(int [[clang::sycl_private]] *Data) {} // expected-note {{candidate function not viable: cannot pass pointer to generic address space as a pointer to address space '[[clang::sycl_private]]' in 1st argument}}
template <typename T>
void tmpl(T *t) {}
@@ -15,16 +15,16 @@ void usages() {
int [[clang::sycl_global]] *GLOB;
int [[clang::sycl_private]] *PRIV;
int [[clang::sycl_local]] *LOC;
- int [[clang::sycl_constant]] *CONST; // expected-warning {{'sycl_constant' address space attribute is deprecated}}
+ int [[clang::sycl_constant]] *CONST;
int *NoAS;
- GLOB = PRIV; // expected-error {{assigning 'sycl_private int *' to 'sycl_global int *' changes address space of pointer}}
- GLOB = LOC; // expected-error {{assigning 'sycl_local int *' to 'sycl_global int *' changes address space of pointer}}
- PRIV = static_cast<int [[clang::sycl_private]] *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to 'sycl_private int *' is not allowed}}
- PRIV = static_cast<int [[clang::sycl_private]] *>(LOC); // expected-error {{static_cast from 'sycl_local int *' to 'sycl_private int *' is not allowed}}
- NoAS = GLOB + PRIV; // expected-error {{invalid operands to binary expression ('sycl_global int *' and 'sycl_private int *')}}
- NoAS = GLOB + LOC; // expected-error {{invalid operands to binary expression ('sycl_global int *' and 'sycl_local int *')}}
- NoAS += GLOB; // expected-error {{invalid operands to binary expression ('int *' and 'sycl_global int *')}}
+ GLOB = PRIV; // expected-error {{assigning '[[clang::sycl_private]] int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
+ GLOB = LOC; // expected-error {{assigning '[[clang::sycl_local]] int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
+ PRIV = static_cast<int [[clang::sycl_private]] *>(GLOB); // expected-error {{static_cast from '[[clang::sycl_global]] int *' to '[[clang::sycl_private]] int *' is not allowed}}
+ PRIV = static_cast<int [[clang::sycl_private]] *>(LOC); // expected-error {{static_cast from '[[clang::sycl_local]] int *' to '[[clang::sycl_private]] int *' is not allowed}}
+ NoAS = GLOB + PRIV; // expected-error {{invalid operands to binary expression ('[[clang::sycl_global]] int *' and '[[clang::sycl_private]] int *')}}
+ NoAS = GLOB + LOC; // expected-error {{invalid operands to binary expression ('[[clang::sycl_global]] int *' and '[[clang::sycl_local]] int *')}}
+ NoAS += GLOB; // expected-error {{invalid operands to binary expression ('int *' and '[[clang::sycl_global]] int *')}}
bar(*GLOB);
bar2(*GLOB);
@@ -54,10 +54,10 @@ void usages() {
// Implicit casts to named address space are disallowed
baz(NoAS); // expected-error {{no matching function for call to 'baz'}}
- int [[clang::sycl_local]] *l = NoAS; // expected-error {{cannot initialize a variable of type 'sycl_local int *' with an lvalue of type 'int *'}}
+ int [[clang::sycl_local]] *l = NoAS; // expected-error {{cannot initialize a variable of type '[[clang::sycl_local]] int *' with an lvalue of type 'int *'}}
// Explicit casts between disjoint address spaces are disallowed
- GLOB = (int [[clang::sycl_global]] *)PRIV; // expected-error {{C-style cast from 'sycl_private int *' to 'sycl_global int *' converts between mismatching address spaces}}
+ GLOB = (int [[clang::sycl_global]] *)PRIV; // expected-error {{C-style cast from '[[clang::sycl_private]] int *' to '[[clang::sycl_global]] int *' converts between mismatching address spaces}}
(void)static_cast<int *>(GLOB);
(void)static_cast<void *>(GLOB);
@@ -70,39 +70,39 @@ void usages() {
bar(*GLOB_HOST);
bar2(*GLOB_HOST);
GLOB = GLOB_HOST;
- GLOB_HOST = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_host int *' changes address space of pointer}}
- GLOB_HOST = static_cast<__attribute__((opencl_global_host)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_host int *' is not allowed}}
+ GLOB_HOST = GLOB; // expected-error {{assigning '[[clang::sycl_global]] int *' to '__global_host int *' changes address space of pointer}}
+ GLOB_HOST = static_cast<__attribute__((opencl_global_host)) int *>(GLOB); // expected-error {{static_cast from '[[clang::sycl_global]] int *' to '__global_host int *' is not allowed}}
__attribute__((opencl_global_device)) int *GLOB_DEVICE;
bar(*GLOB_DEVICE);
bar2(*GLOB_DEVICE);
GLOB = GLOB_DEVICE;
- GLOB_DEVICE = GLOB; // expected-error {{assigning 'sycl_global int *' to '__global_device int *' changes address space of pointer}}
- GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from 'sycl_global int *' to '__global_device int *' is not allowed}}
+ GLOB_DEVICE = GLOB; // expected-error {{assigning '[[clang::sycl_global]] int *' to '__global_device int *' changes address space of pointer}}
+ GLOB_DEVICE = static_cast<__attribute__((opencl_global_device)) int *>(GLOB); // expected-error {{static_cast from '[[clang::sycl_global]] int *' to '__global_device int *' is not allowed}}
// Test sycl_constant conversions
// constant -> constant: OK
- int [[clang::sycl_constant]] *c2 = CONST; // expected-warning {{'sycl_constant' address space attribute is deprecated}}
+ int [[clang::sycl_constant]] *c2 = CONST;
(void)c2;
// constant -> other named: ERROR (disjoint address spaces)
- GLOB = CONST; // expected-error {{assigning 'sycl_constant int *' to 'sycl_global int *' changes address space of pointer}}
- PRIV = CONST; // expected-error {{assigning 'sycl_constant int *' to 'sycl_private int *' changes address space of pointer}}
- LOC = CONST; // expected-error {{assigning 'sycl_constant int *' to 'sycl_local int *' changes address space of pointer}}
+ GLOB = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
+ PRIV = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '[[clang::sycl_private]] int *' changes address space of pointer}}
+ LOC = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '[[clang::sycl_local]] int *' changes address space of pointer}}
// constant -> generic: ERROR (constant not a subset of generic)
- NoAS = CONST; // expected-error {{assigning 'sycl_constant int *' to 'int *' changes address space of pointer}}
+ NoAS = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to 'int *' changes address space of pointer}}
// generic -> constant: ERROR (constant not a superset of generic)
- CONST = NoAS; // expected-error {{assigning 'int *' to 'sycl_constant int *' changes address space of pointer}}
+ CONST = NoAS; // expected-error {{assigning 'int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
// other named -> constant: ERROR (disjoint address spaces)
- CONST = GLOB; // expected-error {{assigning 'sycl_global int *' to 'sycl_constant int *' changes address space of pointer}}
- CONST = PRIV; // expected-error {{assigning 'sycl_private int *' to 'sycl_constant int *' changes address space of pointer}}
- CONST = LOC; // expected-error {{assigning 'sycl_local int *' to 'sycl_constant int *' changes address space of pointer}}
+ CONST = GLOB; // expected-error {{assigning '[[clang::sycl_global]] int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
+ CONST = PRIV; // expected-error {{assigning '[[clang::sycl_private]] int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
+ CONST = LOC; // expected-error {{assigning '[[clang::sycl_local]] int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
// Explicit casts between constant and other spaces are disallowed
- GLOB = (int [[clang::sycl_global]] *)CONST; // expected-error {{C-style cast from 'sycl_constant int *' to 'sycl_global int *' converts between mismatching address spaces}}
- CONST = (int [[clang::sycl_constant]] *)GLOB; // expected-warning {{'sycl_constant' address space attribute is deprecated}} expected-error {{C-style cast from 'sycl_global int *' to 'sycl_constant int *' converts between mismatching address spaces}}
- PRIV = static_cast<int [[clang::sycl_private]] *>(CONST); // expected-error {{static_cast from 'sycl_constant int *' to 'sycl_private int *' is not allowed}}
- CONST = static_cast<int [[clang::sycl_constant]] *>(PRIV); // expected-warning {{'sycl_constant' address space attribute is deprecated}} expected-error {{static_cast from 'sycl_private int *' to 'sycl_constant int *' is not allowed}}
+ GLOB = (int [[clang::sycl_global]] *)CONST; // expected-error {{C-style cast from '[[clang::sycl_constant]] int *' to '[[clang::sycl_global]] int *' converts between mismatching address spaces}}
+ CONST = (int [[clang::sycl_constant]] *)GLOB; // expected-error {{C-style cast from '[[clang::sycl_global]] int *' to '[[clang::sycl_constant]] int *' converts between mismatching address spaces}}
+ PRIV = static_cast<int [[clang::sycl_private]] *>(CONST); // expected-error {{static_cast from '[[clang::sycl_constant]] int *' to '[[clang::sycl_private]] int *' is not allowed}}
+ CONST = static_cast<int [[clang::sycl_constant]] *>(PRIV); // expected-error {{static_cast from '[[clang::sycl_private]] int *' to '[[clang::sycl_constant]] int *' is not allowed}}
}
>From 7c466fbd7248b86353b6a850f27c0b3296d21185 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Tue, 16 Jun 2026 04:04:57 -0700
Subject: [PATCH 09/15] Remove extra semicolon
---
clang/lib/AST/TypePrinter.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 5959c324241b5..13c4bf71d6a94 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2009,8 +2009,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
// FIXME: Update printAttributedBefore to print these once we generate
// AttributedType nodes for them.
llvm_unreachable("Address space attributes handled separately");
- ;
-
case attr::CountedBy:
case attr::CountedByOrNull:
case attr::SizedBy:
>From dbb54d06019c66e0a08c1f9e9373bfcc460337b8 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Thu, 18 Jun 2026 07:56:04 -0700
Subject: [PATCH 10/15] Remove unnecessary flag
---
clang/test/CodeGenSYCL/address-space-mangling.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index 930564e097188..7b26848c9d19d 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - -Wno-deprecated-attributes | FileCheck %s --check-prefix=SPIR
+// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=SPIR
// REQUIRES: x86-registered-target
>From e5cea2cfc2b12fa071d673e8cbc6997580ad1019 Mon Sep 17 00:00:00 2001
From: elizabethandrews <elizabeth.andrews at intel.com>
Date: Wed, 8 Jul 2026 11:08:39 -0400
Subject: [PATCH 11/15] Improve documentation
Co-authored-by: Tom Honermann <tom at honermann.net>
---
clang/include/clang/Basic/AttrDocs.td | 108 ++++++++++++++++++++++----
1 file changed, 93 insertions(+), 15 deletions(-)
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 7321970008e5e..bbdfcc70b838d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -873,24 +873,102 @@ expression.
}];
}
-def SYCLAddressSpaceDocs : Documentation {
- let Category = DocCatType;
- let Heading = "Address space attributes for SYCL";
+def SYCLAddressSpaceDocs : DocumentationCategory<"SYCL Address Spaces"> {
let Content = [{
-The memory model for SYCL devices is derived from the OpenCL memory model. Accordingly
-SYCL defines five address spaces: global, local, private, generic and constant. The
-following attributes correspond to these address spaces:
-
-[[clang::sycl_global]], [[clang::sycl_local]], [[clang::sycl_private]],
-[[clang::sycl_generic]] and [[clang::sycl_constant]] (deprecated)
+.. note::
-These attributes are intended for use in the implementation of SYCL run-time
-libraries. A direct declaration of pointers with address spaces is discouraged. Users
-should use the sycl::multi_ptr class to handle address space boundaries and
-interoperability.
+ These attributes are intended for use in the implementation of SYCL run-time
+ libraries and should not be used in any other context.
+ Programmers writing code intended to conform to the SYCL specification should
+ use the address space facilities specified in the following sections of the
+ SYCL 2020 specification.
+
+ * `4.7.2, "Buffers" <SYCL-2020-4.7.2_>`_
+ * `4.7.6, "Accessors" <SYCL-2020-4.7.6_>`_.
+ * `4.7.7, "Address space classes" <SYCL-2020-4.7.7_>`_.
+ * `F.7, "sycl_khr_static_addrspace_cast" <SYCL-2020-F.7_>`_.
+ * `F.8, "sycl_khr_dynamic_addrspace_cast" <SYCL-2020-F.8_>`_.
+
+The SYCL address space attributes listed below correspond to the five address
+spaces described by
+`SYCL 2020 section 3.8.2, "SYCL device memory model" <SYCL-2020-3.8.2_>`_ and
+`SYCL 2020 section 4.7.7, "Address space classes" <SYCL-2020-4.7.7_>`_.
+
+.. list-table::
+ :header-rows: 1
+
+ * - Address space attribute
+ - SYCL address space
+ - Description
+ * - ``[[clang::sycl_global]]``
+ - global
+ - A memory region accessible by all work-items executing on a device.
+ * - ``[[clang::sycl_local]]``
+ - local
+ - A memory region accessible by all work-items of a single work-group.
+ * - ``[[clang::sycl_private]]``
+ - private
+ - A memory region that is private to a single work-item.
+ * - ``[[clang::sycl_generic]]``
+ - generic
+ - A virtual memory region from which the global, local, and private memory
+ regions may all be accessed.
+ * - ``[[clang::sycl_constant]]``
+ - constant
+ - (*deprecated*) A memory region that holds constant data for an executing
+ kernel.
+
+The SYCL address space attributes are type attributes that may be applied to
+the object type of an object pointer or object reference type.
+A type specifier with a SYCL address space specifies a distinct type from the
+otherwise unattributed type.
+For example, ``int *`` and ``int [[clang::sycl_global]]*`` designate distinct
+pointer types which participate in overload resolution and template
+specialization.
+
+Conversions between SYCL address space attributed types are permitted as
+follows.
-More details can be found in SYCL 2020 Specification, Section 3.8.2
-"SYCL device memory model" and Section 4.7.7, "Address space classes"
+* Types attributed with the global, local, or private address space attributes
+ are implicitly convertible to matching types with the generic address space
+ attribute.
+* Types attributed with the generic address space attribute may be converted
+ to a matching type with the global, local, or private address space attribute
+ by ``static_cast``.
+* All other conversions between matched types with either different address
+ space attributes or where one type lacks an address space attribute may be
+ performed by ``reinterpret_cast``.
+ However, dereference of the result produces undefined behavior if the
+ resulting address is not valid for the address space designated by the target
+ address space attribute.
+
+The mapping of SYCL address spaces to physical address spaces is target
+dependent.
+
+For OpenCL device targets, the SYCL address space attributes are aligned with
+the `OpenCL address space attributes <attr-opencl-addrspace_>`_ such that, e.g.,
+``int [[clang::sycl_global]]*`` and ``int [[clang::opencl_global]]*`` specify
+distinct types both of which map to the same underlying address space.
+Corresponding SYCL and OpenCL address space attributed types are implicitly
+convertible; other conversions are permitted as described above; e.g.,
+``int [[clang::sycl_global]]*`` is implicitly convertible to
+``int [[clang::opencl_generic]]*`` and ``int [[clang::opencl_generic]]*`` is
+explicitly convertible via ``static_cast`` to ``int [[clang::sycl_global]]*``.
+
+.. _attr-opencl-addrspace:
+ https://clang.llvm.org/docs/AttributeReference.html#opencl-address-spaces
+.. _SYCL-2020-3.8.2:
+ https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_sycl_device_memory_model
+.. _SYCL-2020-4.7.2:
+ https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#subsec:buffers
+.. _SYCL-2020-4.7.6:
+ https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#subsec:accessors
+.. _SYCL-2020-4.7.7:
+ https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_address_space_classes
+.. _SYCL-2020-F.7:
+ https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:khr-static-addrspace-cast
+.. _SYCL-2020-F.8:
+ https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:khr-dynamic-addrspace-cast
}];
}
>From 7153dbb441e87eae44444e032ac7c30fa6a15ade Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 15 Jul 2026 11:15:45 -0700
Subject: [PATCH 12/15] Fix Doc build error and allow conversions between
OpenCL and SYCL address spaces when targeting OpenCL.
---
clang/include/clang/Basic/AttrDocs.td | 4 +-
clang/include/clang/Sema/ParsedAttr.h | 8 ++
clang/lib/AST/Type.cpp | 121 ++++++++++++------
clang/lib/Basic/Targets.cpp | 4 +-
clang/lib/Basic/Targets/SPIR.h | 12 +-
.../SemaSYCL/address-space-conversions.cpp | 46 +++++--
6 files changed, 141 insertions(+), 54 deletions(-)
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index bbdfcc70b838d..02770adfbd257 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -873,7 +873,9 @@ expression.
}];
}
-def SYCLAddressSpaceDocs : DocumentationCategory<"SYCL Address Spaces"> {
+def SYCLAddressSpaceDocs : Documentation {
+ let Category = DocCatType;
+ let Heading = "SYCL Address Spaces";
let Content = [{
.. note::
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 529275812a6dc..dd5bd26d64150 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -598,6 +598,14 @@ class ParsedAttr final
return LangAS::sycl_generic;
case ParsedAttr::AT_SYCLConstantAddressSpace:
return LangAS::sycl_constant;
+ // The OpenCL address space attributes are available in SYCL device
+ // mode when targeting the OpenCL execution environment.
+ case ParsedAttr::AT_OpenCLGlobalAddressSpace:
+ case ParsedAttr::AT_OpenCLLocalAddressSpace:
+ case ParsedAttr::AT_OpenCLPrivateAddressSpace:
+ case ParsedAttr::AT_OpenCLGenericAddressSpace:
+ case ParsedAttr::AT_OpenCLConstantAddressSpace:
+ return asOpenCLLangAS();
default:
return LangAS::Default;
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index ef1d5897fa8f3..fc64da8210b2e 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -70,46 +70,91 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
(hasObjCLifetime() && !Other.hasObjCLifetime()));
}
+// When targeting the OpenCL execution environment, corresponding SYCL and
+// OpenCL address spaces designate the same underlying address space and are
+// mutually convertible.
+static bool isConvertibleOpenCLSYCLAddressSpace(LangAS A, LangAS B) {
+ return (A == LangAS::sycl_global && B == LangAS::opencl_global) ||
+ (A == LangAS::opencl_global && B == LangAS::sycl_global) ||
+ (A == LangAS::sycl_global_device &&
+ B == LangAS::opencl_global_device) ||
+ (A == LangAS::opencl_global_device &&
+ B == LangAS::sycl_global_device) ||
+ (A == LangAS::sycl_global_host && B == LangAS::opencl_global_host) ||
+ (A == LangAS::opencl_global_host && B == LangAS::sycl_global_host) ||
+ (A == LangAS::sycl_local && B == LangAS::opencl_local) ||
+ (A == LangAS::opencl_local && B == LangAS::sycl_local) ||
+ (A == LangAS::sycl_private && B == LangAS::opencl_private) ||
+ (A == LangAS::opencl_private && B == LangAS::sycl_private) ||
+ (A == LangAS::sycl_generic && B == LangAS::opencl_generic) ||
+ (A == LangAS::opencl_generic && B == LangAS::sycl_generic) ||
+ (A == LangAS::sycl_constant && B == LangAS::opencl_constant) ||
+ (A == LangAS::opencl_constant && B == LangAS::sycl_constant);
+}
+
bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
const ASTContext &Ctx) {
- // In OpenCLC v2.0 s6.5.5: every address space except for __constant can be
- // used as __generic.
- return (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)) ||
- (A == LangAS::sycl_global &&
- (B == LangAS::sycl_global_device || B == LangAS::sycl_global_host)) ||
- // Consider pointer size address spaces to be equivalent to default.
- ((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
- (isPtrSizeAddressSpace(B) || B == LangAS::Default)) ||
- // Default and sycl_generic are supersets of SYCL address spaces.
- ((A == LangAS::Default || A == LangAS::sycl_generic) &&
- (B == LangAS::sycl_private || B == LangAS::sycl_local ||
- B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
- B == LangAS::sycl_global_host)) ||
- // Consider sycl_generic address space to be equivalent to default.
- (A == LangAS::Default && B == LangAS::sycl_generic) ||
- (B == LangAS::Default && A == LangAS::sycl_generic) ||
- // In HIP device compilation, any cuda address space is allowed
- // to implicitly cast into the default address space.
- (A == LangAS::Default &&
- (B == LangAS::cuda_constant || B == LangAS::cuda_device ||
- B == LangAS::cuda_shared)) ||
- // In HLSL, the this pointer for member functions points to the default
- // address space. This causes a problem if the structure is in
- // a different address space. We want to allow casting from these
- // address spaces to default to work around this problem.
- (A == LangAS::Default && B == LangAS::hlsl_private) ||
- (A == LangAS::Default && B == LangAS::hlsl_device) ||
- (A == LangAS::Default && B == LangAS::hlsl_input) ||
- (A == LangAS::Default && B == LangAS::hlsl_output) ||
- (A == LangAS::Default && B == LangAS::hlsl_push_constant) ||
- // Conversions from target specific address spaces may be legal
- // depending on the target information.
- Ctx.getTargetInfo().isAddressSpaceSupersetOf(A, B);
+ const bool IsOpenCLExecEnv =
+ Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::OpenCL;
+
+ // In OpenCL C v2.0 s6.5.5: every address space except for __constant can be
+ // used as __generic. The OpenCL address space attributes are also available
+ // in SYCL device mode, but there opencl_generic only overlaps other address
+ // spaces when targeting the OpenCL execution environment.
+ if ((Ctx.getLangOpts().OpenCL || IsOpenCLExecEnv) &&
+ A == LangAS::opencl_generic && B != LangAS::opencl_constant)
+ return true;
+
+ // __global is a superset of the global_device and global_host address
+ // spaces, which distinguish global pointers allocated on the host from those
+ // allocated on the device.
+ if (A == LangAS::opencl_global &&
+ (B == LangAS::opencl_global_device || B == LangAS::opencl_global_host))
+ return true;
+ if (A == LangAS::sycl_global &&
+ (B == LangAS::sycl_global_device || B == LangAS::sycl_global_host))
+ return true;
+
+ // Pointer size address spaces are equivalent to the default address space.
+ if ((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
+ (isPtrSizeAddressSpace(B) || B == LangAS::Default))
+ return true;
+
+ // Default and sycl_generic are supersets of the SYCL address spaces.
+ if ((A == LangAS::Default || A == LangAS::sycl_generic) &&
+ (B == LangAS::sycl_private || B == LangAS::sycl_local ||
+ B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
+ B == LangAS::sycl_global_host))
+ return true;
+
+ // Default and sycl_generic are equivalent.
+ if ((A == LangAS::Default && B == LangAS::sycl_generic) ||
+ (B == LangAS::Default && A == LangAS::sycl_generic))
+ return true;
+
+ if (IsOpenCLExecEnv && isConvertibleOpenCLSYCLAddressSpace(A, B))
+ return true;
+
+ // In HIP device compilation, any cuda address space is allowed to implicitly
+ // cast into the default address space.
+ if (A == LangAS::Default &&
+ (B == LangAS::cuda_constant || B == LangAS::cuda_device ||
+ B == LangAS::cuda_shared))
+ return true;
+
+ // In HLSL, the this pointer for member functions points to the default
+ // address space. This causes a problem if the structure is in a different
+ // address space. We want to allow casting from these address spaces to
+ // default to work around this problem.
+ if (A == LangAS::Default &&
+ (B == LangAS::hlsl_private || B == LangAS::hlsl_device ||
+ B == LangAS::hlsl_input || B == LangAS::hlsl_output ||
+ B == LangAS::hlsl_push_constant))
+ return true;
+
+ // Conversions from target specific address spaces may be legal depending on
+ // the target information.
+ return Ctx.getTargetInfo().isAddressSpaceSupersetOf(A, B);
}
const IdentifierInfo *QualType::getBaseTypeIdentifier() const {
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index ed88ae7173bad..40455f54b76d8 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -714,7 +714,7 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
}
case llvm::Triple::spirv32: {
if ((os != llvm::Triple::UnknownOS && os != llvm::Triple::ChipStar &&
- os != llvm::Triple::Vulkan) ||
+ os != llvm::Triple::Vulkan && os != llvm::Triple::OpenCL) ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return nullptr;
return std::make_unique<SPIRV32TargetInfo>(Triple, Opts);
@@ -723,7 +723,7 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
if (os == llvm::Triple::OSType::AMDHSA)
return std::make_unique<SPIRV64AMDGCNTargetInfo>(Triple, Opts);
if ((os != llvm::Triple::UnknownOS && os != llvm::Triple::ChipStar &&
- os != llvm::Triple::Vulkan) ||
+ os != llvm::Triple::Vulkan && os != llvm::Triple::OpenCL) ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return nullptr;
if (Triple.getVendor() == llvm::Triple::Intel)
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 6cd9544904d32..cb928861a9cd3 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -385,8 +385,10 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
"Invalid architecture for 32-bit SPIR-V.");
assert((getTriple().getOS() == llvm::Triple::UnknownOS ||
getTriple().getOS() == llvm::Triple::ChipStar ||
- getTriple().getOS() == llvm::Triple::Vulkan) &&
- "32-bit SPIR-V target must use unknown, chipstar, or vulkan OS");
+ getTriple().getOS() == llvm::Triple::Vulkan ||
+ getTriple().getOS() == llvm::Triple::OpenCL) &&
+ "32-bit SPIR-V target must use unknown, chipstar, vulkan, or "
+ "opencl OS");
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
"32-bit SPIR-V target must use unknown environment type");
PointerWidth = PointerAlign = 32;
@@ -410,8 +412,10 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
"Invalid architecture for 64-bit SPIR-V.");
assert((getTriple().getOS() == llvm::Triple::UnknownOS ||
getTriple().getOS() == llvm::Triple::ChipStar ||
- getTriple().getOS() == llvm::Triple::Vulkan) &&
- "64-bit SPIR-V target must use unknown, chipstar, or vulkan OS");
+ getTriple().getOS() == llvm::Triple::Vulkan ||
+ getTriple().getOS() == llvm::Triple::OpenCL) &&
+ "64-bit SPIR-V target must use unknown, chipstar, vulkan, or "
+ "opencl OS");
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
"64-bit SPIR-V target must use unknown environment type");
PointerWidth = PointerAlign = 64;
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index 4574b1db5550e..fc1c21ed1be46 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only %s
+// RUN: %clang_cc1 -fsycl-is-device -verify=expected,def -fsyntax-only %s
+// RUN: %clang_cc1 -fsycl-is-device -triple spirv64-unknown-opencl-unknown -verify -fsyntax-only %s
void bar(int &Data) {}
void bar2(int &Data) {}
@@ -84,25 +85,52 @@ void usages() {
int [[clang::sycl_constant]] *c2 = CONST;
(void)c2;
- // constant -> other named: ERROR (disjoint address spaces)
GLOB = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
PRIV = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '[[clang::sycl_private]] int *' changes address space of pointer}}
LOC = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '[[clang::sycl_local]] int *' changes address space of pointer}}
-
- // constant -> generic: ERROR (constant not a subset of generic)
NoAS = CONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to 'int *' changes address space of pointer}}
-
- // generic -> constant: ERROR (constant not a superset of generic)
CONST = NoAS; // expected-error {{assigning 'int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
-
- // other named -> constant: ERROR (disjoint address spaces)
CONST = GLOB; // expected-error {{assigning '[[clang::sycl_global]] int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
CONST = PRIV; // expected-error {{assigning '[[clang::sycl_private]] int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
CONST = LOC; // expected-error {{assigning '[[clang::sycl_local]] int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
- // Explicit casts between constant and other spaces are disallowed
GLOB = (int [[clang::sycl_global]] *)CONST; // expected-error {{C-style cast from '[[clang::sycl_constant]] int *' to '[[clang::sycl_global]] int *' converts between mismatching address spaces}}
CONST = (int [[clang::sycl_constant]] *)GLOB; // expected-error {{C-style cast from '[[clang::sycl_global]] int *' to '[[clang::sycl_constant]] int *' converts between mismatching address spaces}}
PRIV = static_cast<int [[clang::sycl_private]] *>(CONST); // expected-error {{static_cast from '[[clang::sycl_constant]] int *' to '[[clang::sycl_private]] int *' is not allowed}}
CONST = static_cast<int [[clang::sycl_constant]] *>(PRIV); // expected-error {{static_cast from '[[clang::sycl_private]] int *' to '[[clang::sycl_constant]] int *' is not allowed}}
}
+
+// When targeting the OpenCL execution environment SYCL and OpenCL address space
+// attributes are aligned. Corresponding address are mutually convertible.
+void opencl_conv() {
+ int [[clang::sycl_global]] *SGLOB;
+ int [[clang::sycl_local]] *SLOC;
+ int [[clang::sycl_private]] *SPRIV;
+ int [[clang::sycl_constant]] *SCONST;
+ int [[clang::sycl_generic]] *SGEN;
+
+ __attribute__((opencl_global)) int *OGLOB;
+ __attribute__((opencl_local)) int *OLOC;
+ __attribute__((opencl_private)) int *OPRIV;
+ __attribute__((opencl_constant)) int *OCONST;
+ __attribute__((opencl_generic)) int *OGEN;
+
+ // Corresponding SYCL/OpenCL address spaces are mutually convertible when
+ // targeting OpenCL. An error is generated when not targeting OpenCL.
+ OGLOB = SGLOB; // def-error {{assigning '[[clang::sycl_global]] int *' to '__global int *' changes address space of pointer}}
+ SGLOB = OGLOB; // def-error {{assigning '__global int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
+ OLOC = SLOC; // def-error {{assigning '[[clang::sycl_local]] int *' to '__local int *' changes address space of pointer}}
+ SLOC = OLOC; // def-error {{assigning '__local int *' to '[[clang::sycl_local]] int *' changes address space of pointer}}
+ OPRIV = SPRIV; // def-error {{assigning '[[clang::sycl_private]] int *' to '__private int *' changes address space of pointer}}
+ SPRIV = OPRIV; // def-error {{assigning '__private int *' to '[[clang::sycl_private]] int *' changes address space of pointer}}
+ OGEN = SGEN; // def-error {{assigning '[[clang::sycl_generic]] int *' to '__generic int *' changes address space of pointer}}
+ SGEN = OGEN; // def-error {{assigning '__generic int *' to '[[clang::sycl_generic]] int *' changes address space of pointer}}
+ OCONST = SCONST; // def-error {{assigning '[[clang::sycl_constant]] int *' to '__constant int *' changes address space of pointer}}
+ SCONST = OCONST; // def-error {{assigning '__constant int *' to '[[clang::sycl_constant]] int *' changes address space of pointer}}
+
+ // Non-corresponding SYCL/OpenCL address spaces remain disjoint and are
+ // diagnosed regardless of the target.
+ OGLOB = SLOC; // expected-error {{assigning '[[clang::sycl_local]] int *' to '__global int *' changes address space of pointer}}
+ SGLOB = OPRIV; // expected-error {{assigning '__private int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
+ OCONST = SGLOB; // expected-error {{assigning '[[clang::sycl_global]] int *' to '__constant int *' changes address space of pointer}}
+}
>From ed104b38a9ebb58e3101ae17e61962eb698fb070 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 15 Jul 2026 12:30:50 -0700
Subject: [PATCH 13/15] Delete unneccessary comment I added before refactoring
---
clang/lib/AST/Type.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index fc64da8210b2e..f651527b3f1c9 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -98,9 +98,7 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::OpenCL;
// In OpenCL C v2.0 s6.5.5: every address space except for __constant can be
- // used as __generic. The OpenCL address space attributes are also available
- // in SYCL device mode, but there opencl_generic only overlaps other address
- // spaces when targeting the OpenCL execution environment.
+ // used as __generic.
if ((Ctx.getLangOpts().OpenCL || IsOpenCLExecEnv) &&
A == LangAS::opencl_generic && B != LangAS::opencl_constant)
return true;
>From 335b38b9a7ce15d6bff32a64dd5bfd8f809d2052 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Tue, 11 Aug 2026 12:19:32 -0700
Subject: [PATCH 14/15] Apply review comments
---
clang/include/clang/Basic/AttrDocs.td | 12 +-
.../clang/Basic/DiagnosticSemaKinds.td | 3 +
clang/lib/AST/MicrosoftMangle.cpp | 26 +-
clang/lib/AST/Type.cpp | 63 +++-
clang/lib/Sema/SemaDecl.cpp | 17 +
clang/lib/Sema/SemaType.cpp | 6 +-
.../CodeGenSYCL/address-space-mangling.cpp | 16 +
.../sycl-address-space-attr-appertainment.cpp | 356 ++++++++++++++++++
8 files changed, 467 insertions(+), 32 deletions(-)
create mode 100644 clang/test/SemaSYCL/sycl-address-space-attr-appertainment.cpp
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 02770adfbd257..5caaf4171b3c6 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -934,15 +934,6 @@ follows.
* Types attributed with the global, local, or private address space attributes
are implicitly convertible to matching types with the generic address space
attribute.
-* Types attributed with the generic address space attribute may be converted
- to a matching type with the global, local, or private address space attribute
- by ``static_cast``.
-* All other conversions between matched types with either different address
- space attributes or where one type lacks an address space attribute may be
- performed by ``reinterpret_cast``.
- However, dereference of the result produces undefined behavior if the
- resulting address is not valid for the address space designated by the target
- address space attribute.
The mapping of SYCL address spaces to physical address spaces is target
dependent.
@@ -954,8 +945,7 @@ distinct types both of which map to the same underlying address space.
Corresponding SYCL and OpenCL address space attributed types are implicitly
convertible; other conversions are permitted as described above; e.g.,
``int [[clang::sycl_global]]*`` is implicitly convertible to
-``int [[clang::opencl_generic]]*`` and ``int [[clang::opencl_generic]]*`` is
-explicitly convertible via ``static_cast`` to ``int [[clang::sycl_global]]*``.
+``int [[clang::opencl_generic]]*``.
.. _attr-opencl-addrspace:
https://clang.llvm.org/docs/AttributeReference.html#opencl-address-spaces
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f84cd8dca6d4c..3a991dc5e81b8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13478,6 +13478,9 @@ def err_sycl_special_type_num_init_method : Error<
"method defined">;
def err_sycl_device_invalid_target : Error<
"%0 is not a supported SYCL device target">;
+def err_sycl_address_space_qualified_object : Error<
+ "'%0' attribute may only be applied to the object type of an object pointer "
+ "or object reference type">;
// SYCL external attribute diagnostics
def err_sycl_external_invalid_linkage : Error<
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index adfe260a0d091..21ef1a76c51ac 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2457,9 +2457,12 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
// In the case of a language specific address space:
// __clang::struct _AS[language_addr_space]<Type>
// where:
- // <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>
+ // <language_addr_space> ::= <OpenCL-addrspace> | <SYCL-addrspace>
+ // | <CUDA-addrspace>
// <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
// "private"| "generic" | "device" | "host" ]
+ // <SYCL-addrspace> ::= "SY" [ "global" | "local" | "private" | "generic" |
+ // "constant" | "device" | "host" ]
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
// Note that the above were chosen to match the Itanium mangling for this.
//
@@ -2501,6 +2504,27 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
case LangAS::opencl_generic:
Extra.mangleSourceName("_ASCLgeneric");
break;
+ case LangAS::sycl_global:
+ Extra.mangleSourceName("_ASSYglobal");
+ break;
+ case LangAS::sycl_global_device:
+ Extra.mangleSourceName("_ASSYdevice");
+ break;
+ case LangAS::sycl_global_host:
+ Extra.mangleSourceName("_ASSYhost");
+ break;
+ case LangAS::sycl_local:
+ Extra.mangleSourceName("_ASSYlocal");
+ break;
+ case LangAS::sycl_private:
+ Extra.mangleSourceName("_ASSYprivate");
+ break;
+ case LangAS::sycl_generic:
+ Extra.mangleSourceName("_ASSYgeneric");
+ break;
+ case LangAS::sycl_constant:
+ Extra.mangleSourceName("_ASSYconstant");
+ break;
case LangAS::cuda_device:
Extra.mangleSourceName("_ASCUdevice");
break;
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index f651527b3f1c9..fbfc929b574c6 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -70,26 +70,53 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
(hasObjCLifetime() && !Other.hasObjCLifetime()));
}
+// The memory region designated by a SYCL or OpenCL address space. Address
+// spaces that are neither SYCL nor OpenCL map to NotOpenCLSYCL.
+enum class MemoryRegion {
+ Global,
+ Local,
+ Private,
+ Generic,
+ Constant,
+ GlobalDevice,
+ GlobalHost,
+ NotOpenCLSYCL,
+};
+
+static MemoryRegion getMemoryRegion(LangAS AS) {
+ switch (AS) {
+ case LangAS::sycl_global:
+ case LangAS::opencl_global:
+ return MemoryRegion::Global;
+ case LangAS::sycl_local:
+ case LangAS::opencl_local:
+ return MemoryRegion::Local;
+ case LangAS::sycl_private:
+ case LangAS::opencl_private:
+ return MemoryRegion::Private;
+ case LangAS::sycl_generic:
+ case LangAS::opencl_generic:
+ return MemoryRegion::Generic;
+ case LangAS::sycl_constant:
+ case LangAS::opencl_constant:
+ return MemoryRegion::Constant;
+ case LangAS::sycl_global_device:
+ case LangAS::opencl_global_device:
+ return MemoryRegion::GlobalDevice;
+ case LangAS::sycl_global_host:
+ case LangAS::opencl_global_host:
+ return MemoryRegion::GlobalHost;
+ default:
+ return MemoryRegion::NotOpenCLSYCL;
+ }
+}
+
// When targeting the OpenCL execution environment, corresponding SYCL and
-// OpenCL address spaces designate the same underlying address space and are
-// mutually convertible.
+// OpenCL address spaces designate are mutually convertible.
static bool isConvertibleOpenCLSYCLAddressSpace(LangAS A, LangAS B) {
- return (A == LangAS::sycl_global && B == LangAS::opencl_global) ||
- (A == LangAS::opencl_global && B == LangAS::sycl_global) ||
- (A == LangAS::sycl_global_device &&
- B == LangAS::opencl_global_device) ||
- (A == LangAS::opencl_global_device &&
- B == LangAS::sycl_global_device) ||
- (A == LangAS::sycl_global_host && B == LangAS::opencl_global_host) ||
- (A == LangAS::opencl_global_host && B == LangAS::sycl_global_host) ||
- (A == LangAS::sycl_local && B == LangAS::opencl_local) ||
- (A == LangAS::opencl_local && B == LangAS::sycl_local) ||
- (A == LangAS::sycl_private && B == LangAS::opencl_private) ||
- (A == LangAS::opencl_private && B == LangAS::sycl_private) ||
- (A == LangAS::sycl_generic && B == LangAS::opencl_generic) ||
- (A == LangAS::opencl_generic && B == LangAS::sycl_generic) ||
- (A == LangAS::sycl_constant && B == LangAS::opencl_constant) ||
- (A == LangAS::opencl_constant && B == LangAS::sycl_constant);
+ MemoryRegion RegionA = getMemoryRegion(A);
+ return RegionA != MemoryRegion::NotOpenCLSYCL &&
+ RegionA == getMemoryRegion(B);
}
bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cddcf3a010279..1af9aa0d6d6f9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8905,6 +8905,11 @@ static bool CheckC23ConstexprVarType(Sema &SemaRef, SourceLocation VarLoc,
return false;
}
+/// \return whether \p AS is one of the SYCL address spaces.
+static bool isSYCLAddressSpace(LangAS AS) {
+ return AS >= LangAS::sycl_global && AS <= LangAS::sycl_constant;
+}
+
void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
// If the decl is already known invalid, don't check it.
if (NewVD->isInvalidDecl())
@@ -8926,6 +8931,18 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
NewVD->setType(T);
}
+ // The SYCL address space attributes may only be applied to the object type
+ // of an object pointer or object reference type.
+ if (getLangOpts().isSYCL()) {
+ LangAS AS = Context.getBaseElementType(T).getAddressSpace();
+ if (isSYCLAddressSpace(AS)) {
+ Diag(NewVD->getLocation(), diag::err_sycl_address_space_qualified_object)
+ << Qualifiers::getAddrSpaceAsString(AS);
+ NewVD->setInvalidDecl();
+ return;
+ }
+ }
+
// Emit an error if an address space was applied to decl with local storage.
// This includes arrays of objects with address space qualifiers, but not
// automatic variables that point to other address spaces.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 46ed0ed1af209..c4deeb48ef77f 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6696,8 +6696,10 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
Attr.setInvalid();
} else {
// The keyword-based type attributes imply which address space to use.
- ASIdx = S.getLangOpts().SYCLIsDevice ? Attr.asSYCLLangAS()
- : Attr.asOpenCLLangAS();
+ // The SYCL address space attributes are available in both SYCL host and
+ // device compilation.
+ ASIdx =
+ S.getLangOpts().isSYCL() ? Attr.asSYCLLangAS() : Attr.asOpenCLLangAS();
if (S.getLangOpts().HLSL)
ASIdx = Attr.asHLSLLangAS();
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index 7b26848c9d19d..23eeb2e10ae8e 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=SPIR
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsycl-is-host -emit-llvm %s -o - | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fsycl-is-host -emit-llvm %s -o - | FileCheck %s --check-prefix=MS
// REQUIRES: x86-registered-target
@@ -16,6 +18,20 @@ void foo(int *);
// SPIR: declare spir_func void @_Z3fooPU3AS2i(ptr addrspace(2) noundef) #1
// SPIR: declare spir_func void @_Z3fooPi(ptr addrspace(4) noundef) #1
+// ITANIUM: declare void @_Z3fooPU8SYglobali(ptr noundef)
+// ITANIUM: declare void @_Z3fooPU7SYlocali(ptr noundef)
+// ITANIUM: declare void @_Z3fooPU9SYprivatei(ptr noundef)
+// ITANIUM: declare void @_Z3fooPU9SYgenerici(ptr noundef)
+// ITANIUM: declare void @_Z3fooPU10SYconstanti(ptr noundef)
+// ITANIUM: declare void @_Z3fooPi(ptr noundef)
+
+// MS: declare dso_local void @"?foo@@YAXPEAU?$_ASSYglobal@$$CAH at __clang@@@Z"
+// MS: declare dso_local void @"?foo@@YAXPEAU?$_ASSYlocal@$$CAH at __clang@@@Z"
+// MS: declare dso_local void @"?foo@@YAXPEAU?$_ASSYprivate@$$CAH at __clang@@@Z"
+// MS: declare dso_local void @"?foo@@YAXPEAU?$_ASSYgeneric@$$CAH at __clang@@@Z"
+// MS: declare dso_local void @"?foo@@YAXPEAU?$_ASSYconstant@$$CAH at __clang@@@Z"
+// MS: declare dso_local void @"?foo@@YAXPEAH at Z"
+
[[clang::sycl_external]] void test() {
int [[clang::sycl_global]] *glob;
int [[clang::sycl_local]] *loc;
diff --git a/clang/test/SemaSYCL/sycl-address-space-attr-appertainment.cpp b/clang/test/SemaSYCL/sycl-address-space-attr-appertainment.cpp
new file mode 100644
index 0000000000000..b247af444ede5
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-address-space-attr-appertainment.cpp
@@ -0,0 +1,356 @@
+// RUN: %clang_cc1 -fsycl-is-host -fsyntax-only -std=c++20 -verify %s
+// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -std=c++20 -verify %s
+
+// The SYCL address space attributes are type attributes that may only appear on
+// the object type of an object pointer or object reference type. This test
+// exercises that appropriate diagnostics are issued for other uses.
+
+//===----------------------------------------------------------------------===//
+// sycl_global
+//===----------------------------------------------------------------------===//
+
+// expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+[[clang::sycl_global]];
+
+// expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+namespace [[clang::sycl_global]] global_ns {}
+
+// expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+struct [[clang::sycl_global]] global_struct {};
+
+// expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+enum [[clang::sycl_global]] global_enum {};
+
+enum {
+ // expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+ global_enumerator [[clang::sycl_global]]
+};
+
+template <typename>
+// expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+concept global_concept [[clang::sycl_global]] = true;
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+[[clang::sycl_global]] int global_ret();
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int global_fn_param(void (fp [[clang::sycl_global]])());
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int global_trailing() [[clang::sycl_global]];
+
+struct global_members {
+ // expected-error at +1{{function type may not be qualified with an address space}}
+ [[clang::sycl_global]] int mf();
+ // expected-error at +2{{field may not be qualified with an address space}}
+ // expected-error at +1{{'clang::sycl_global' attribute cannot be applied to a declaration}}
+ [[clang::sycl_global]] int dm;
+};
+
+// expected-error at +1{{'[[clang::sycl_global]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_global]] global_object;
+
+// expected-error at +1{{'[[clang::sycl_global]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int * [[clang::sycl_global]] global_pointer_object;
+
+// expected-error at +1{{'[[clang::sycl_global]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_global]] global_array[4];
+
+using global_int = int [[clang::sycl_global]];
+// expected-error at +1{{'[[clang::sycl_global]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+global_int global_object_via_typedef;
+
+void global_storage_durations() {
+ // expected-error at +1{{'[[clang::sycl_global]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ int [[clang::sycl_global]] automatic_object;
+ // expected-error at +1{{'[[clang::sycl_global]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ static int [[clang::sycl_global]] static_object;
+}
+
+struct global_S;
+int [[clang::sycl_global]] global_S::*global_member_pointer;
+using global_int_ptr = global_int *;
+global_int_ptr global_pointer_via_typedef;
+int [[clang::sycl_global]] *global_pointer;
+void global_reference(int [[clang::sycl_global]] &r);
+int [[clang::sycl_global]] *global_returns_pointer();
+
+//===----------------------------------------------------------------------===//
+// sycl_local
+//===----------------------------------------------------------------------===//
+
+// expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+[[clang::sycl_local]];
+
+// expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+namespace [[clang::sycl_local]] local_ns {}
+
+// expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+struct [[clang::sycl_local]] local_struct {};
+
+// expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+enum [[clang::sycl_local]] local_enum {};
+
+enum {
+ // expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+ local_enumerator [[clang::sycl_local]]
+};
+
+template <typename>
+// expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+concept local_concept [[clang::sycl_local]] = true;
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+[[clang::sycl_local]] int local_ret();
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int local_fn_param(void (fp [[clang::sycl_local]])());
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int local_trailing() [[clang::sycl_local]];
+
+struct local_members {
+ // expected-error at +1{{function type may not be qualified with an address space}}
+ [[clang::sycl_local]] int mf();
+ // expected-error at +2{{field may not be qualified with an address space}}
+ // expected-error at +1{{'clang::sycl_local' attribute cannot be applied to a declaration}}
+ [[clang::sycl_local]] int dm;
+};
+
+// expected-error at +1{{'[[clang::sycl_local]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_local]] local_object;
+
+// expected-error at +1{{'[[clang::sycl_local]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int * [[clang::sycl_local]] local_pointer_object;
+
+// expected-error at +1{{'[[clang::sycl_local]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_local]] local_array[4];
+
+using local_int = int [[clang::sycl_local]];
+// expected-error at +1{{'[[clang::sycl_local]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+local_int local_object_via_typedef;
+
+void local_storage_durations() {
+ // expected-error at +1{{'[[clang::sycl_local]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ int [[clang::sycl_local]] automatic_object;
+ // expected-error at +1{{'[[clang::sycl_local]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ static int [[clang::sycl_local]] static_object;
+}
+
+struct local_S;
+int [[clang::sycl_local]] local_S::*local_member_pointer;
+using local_int_ptr = local_int *;
+local_int_ptr local_pointer_via_typedef;
+int [[clang::sycl_local]] *local_pointer;
+void local_reference(int [[clang::sycl_local]] &r);
+int [[clang::sycl_local]] *local_returns_pointer();
+
+//===----------------------------------------------------------------------===//
+// sycl_private
+//===----------------------------------------------------------------------===//
+
+// expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+[[clang::sycl_private]];
+
+// expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+namespace [[clang::sycl_private]] private_ns {}
+
+// expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+struct [[clang::sycl_private]] private_struct {};
+
+// expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+enum [[clang::sycl_private]] private_enum {};
+
+enum {
+ // expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+ private_enumerator [[clang::sycl_private]]
+};
+
+template <typename>
+// expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+concept private_concept [[clang::sycl_private]] = true;
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+[[clang::sycl_private]] int private_ret();
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int private_fn_param(void (fp [[clang::sycl_private]])());
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int private_trailing() [[clang::sycl_private]];
+
+struct private_members {
+ // expected-error at +1{{function type may not be qualified with an address space}}
+ [[clang::sycl_private]] int mf();
+ // expected-error at +2{{field may not be qualified with an address space}}
+ // expected-error at +1{{'clang::sycl_private' attribute cannot be applied to a declaration}}
+ [[clang::sycl_private]] int dm;
+};
+
+// expected-error at +1{{'[[clang::sycl_private]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_private]] private_object;
+
+// expected-error at +1{{'[[clang::sycl_private]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int * [[clang::sycl_private]] private_pointer_object;
+
+// expected-error at +1{{'[[clang::sycl_private]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_private]] private_array[4];
+
+using private_int = int [[clang::sycl_private]];
+// expected-error at +1{{'[[clang::sycl_private]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+private_int private_object_via_typedef;
+
+void private_storage_durations() {
+ // expected-error at +1{{'[[clang::sycl_private]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ int [[clang::sycl_private]] automatic_object;
+ // expected-error at +1{{'[[clang::sycl_private]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ static int [[clang::sycl_private]] static_object;
+}
+
+struct private_S;
+int [[clang::sycl_private]] private_S::*private_member_pointer;
+using private_int_ptr = private_int *;
+private_int_ptr private_pointer_via_typedef;
+int [[clang::sycl_private]] *private_pointer;
+void private_reference(int [[clang::sycl_private]] &r);
+int [[clang::sycl_private]] *private_returns_pointer();
+
+//===----------------------------------------------------------------------===//
+// sycl_generic
+//===----------------------------------------------------------------------===//
+
+// expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+[[clang::sycl_generic]];
+
+// expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+namespace [[clang::sycl_generic]] generic_ns {}
+
+// expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+struct [[clang::sycl_generic]] generic_struct {};
+
+// expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+enum [[clang::sycl_generic]] generic_enum {};
+
+enum {
+ // expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+ generic_enumerator [[clang::sycl_generic]]
+};
+
+template <typename>
+// expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+concept generic_concept [[clang::sycl_generic]] = true;
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+[[clang::sycl_generic]] int generic_ret();
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int generic_fn_param(void (fp [[clang::sycl_generic]])());
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int generic_trailing() [[clang::sycl_generic]];
+
+struct generic_members {
+ // expected-error at +1{{function type may not be qualified with an address space}}
+ [[clang::sycl_generic]] int mf();
+ // expected-error at +2{{field may not be qualified with an address space}}
+ // expected-error at +1{{'clang::sycl_generic' attribute cannot be applied to a declaration}}
+ [[clang::sycl_generic]] int dm;
+};
+
+// expected-error at +1{{'[[clang::sycl_generic]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_generic]] generic_object;
+
+// expected-error at +1{{'[[clang::sycl_generic]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int * [[clang::sycl_generic]] generic_pointer_object;
+
+// expected-error at +1{{'[[clang::sycl_generic]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_generic]] generic_array[4];
+
+using generic_int = int [[clang::sycl_generic]];
+// expected-error at +1{{'[[clang::sycl_generic]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+generic_int generic_object_via_typedef;
+
+void generic_storage_durations() {
+ // expected-error at +1{{'[[clang::sycl_generic]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ int [[clang::sycl_generic]] automatic_object;
+ // expected-error at +1{{'[[clang::sycl_generic]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ static int [[clang::sycl_generic]] static_object;
+}
+
+struct generic_S;
+int [[clang::sycl_generic]] generic_S::*generic_member_pointer;
+using generic_int_ptr = generic_int *;
+generic_int_ptr generic_pointer_via_typedef;
+int [[clang::sycl_generic]] *generic_pointer;
+void generic_reference(int [[clang::sycl_generic]] &r);
+int [[clang::sycl_generic]] *generic_returns_pointer();
+
+//===----------------------------------------------------------------------===//
+// sycl_constant
+//===----------------------------------------------------------------------===//
+
+// expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+[[clang::sycl_constant]];
+
+// expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+namespace [[clang::sycl_constant]] constant_ns {}
+
+// expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+struct [[clang::sycl_constant]] constant_struct {};
+
+// expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+enum [[clang::sycl_constant]] constant_enum {};
+
+enum {
+ // expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+ constant_enumerator [[clang::sycl_constant]]
+};
+
+template <typename>
+// expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+concept constant_concept [[clang::sycl_constant]] = true;
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+[[clang::sycl_constant]] int constant_ret();
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int constant_fn_param(void (fp [[clang::sycl_constant]])());
+
+// expected-error at +1{{function type may not be qualified with an address space}}
+int constant_trailing() [[clang::sycl_constant]];
+
+struct constant_members {
+ // expected-error at +1{{function type may not be qualified with an address space}}
+ [[clang::sycl_constant]] int mf();
+ // expected-error at +2{{field may not be qualified with an address space}}
+ // expected-error at +1{{'clang::sycl_constant' attribute cannot be applied to a declaration}}
+ [[clang::sycl_constant]] int dm;
+};
+
+// expected-error at +1{{'[[clang::sycl_constant]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_constant]] constant_object;
+
+// expected-error at +1{{'[[clang::sycl_constant]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int * [[clang::sycl_constant]] constant_pointer_object;
+
+// expected-error at +1{{'[[clang::sycl_constant]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+int [[clang::sycl_constant]] constant_array[4];
+
+using constant_int = int [[clang::sycl_constant]];
+// expected-error at +1{{'[[clang::sycl_constant]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+constant_int constant_object_via_typedef;
+
+void constant_storage_durations() {
+ // expected-error at +1{{'[[clang::sycl_constant]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ int [[clang::sycl_constant]] automatic_object;
+ // expected-error at +1{{'[[clang::sycl_constant]]' attribute may only be applied to the object type of an object pointer or object reference type}}
+ static int [[clang::sycl_constant]] static_object;
+}
+
+struct constant_S;
+int [[clang::sycl_constant]] constant_S::*constant_member_pointer;
+using constant_int_ptr = constant_int *;
+constant_int_ptr constant_pointer_via_typedef;
+int [[clang::sycl_constant]] *constant_pointer;
+void constant_reference(int [[clang::sycl_constant]] &r);
+int [[clang::sycl_constant]] *constant_returns_pointer();
>From bc2364268d2936a4975c97d2bf4cb9e601a98383 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 12 Aug 2026 10:20:58 -0700
Subject: [PATCH 15/15] Fix OpenCL conversions
---
clang/lib/AST/Type.cpp | 26 ++++++++++++-----
.../SemaSYCL/address-space-conversions.cpp | 29 ++++++++++++++++---
2 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index fbfc929b574c6..007d8db1f0355 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -111,12 +111,23 @@ static MemoryRegion getMemoryRegion(LangAS AS) {
}
}
-// When targeting the OpenCL execution environment, corresponding SYCL and
-// OpenCL address spaces designate are mutually convertible.
+// When targeting the OpenCL execution environment, the SYCL and OpenCL address
+// spaces are aligned:
+// - corresponding address spaces (e.g. sycl_global and opencl_global, or
+// sycl_generic and opencl_generic) are equivalent, and
+// - the generic address space is a superset of every other SYCL and OpenCL
+// address space except constant.
static bool isConvertibleOpenCLSYCLAddressSpace(LangAS A, LangAS B) {
MemoryRegion RegionA = getMemoryRegion(A);
- return RegionA != MemoryRegion::NotOpenCLSYCL &&
- RegionA == getMemoryRegion(B);
+ MemoryRegion RegionB = getMemoryRegion(B);
+ if (RegionA == MemoryRegion::NotOpenCLSYCL ||
+ RegionB == MemoryRegion::NotOpenCLSYCL)
+ return false;
+
+ if (RegionA == RegionB)
+ return true;
+
+ return RegionA == MemoryRegion::Generic && RegionB != MemoryRegion::Constant;
}
bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
@@ -125,9 +136,10 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::OpenCL;
// In OpenCL C v2.0 s6.5.5: every address space except for __constant can be
- // used as __generic.
- if ((Ctx.getLangOpts().OpenCL || IsOpenCLExecEnv) &&
- A == LangAS::opencl_generic && B != LangAS::opencl_constant)
+ // used as __generic. When targeting the OpenCL execution environment this is
+ // handled by isConvertibleOpenCLSYCLAddressSpace below.
+ if (Ctx.getLangOpts().OpenCL && A == LangAS::opencl_generic &&
+ B != LangAS::opencl_constant)
return true;
// __global is a superset of the global_device and global_host address
diff --git a/clang/test/SemaSYCL/address-space-conversions.cpp b/clang/test/SemaSYCL/address-space-conversions.cpp
index fc1c21ed1be46..7364a5956c1c0 100644
--- a/clang/test/SemaSYCL/address-space-conversions.cpp
+++ b/clang/test/SemaSYCL/address-space-conversions.cpp
@@ -100,8 +100,6 @@ void usages() {
CONST = static_cast<int [[clang::sycl_constant]] *>(PRIV); // expected-error {{static_cast from '[[clang::sycl_private]] int *' to '[[clang::sycl_constant]] int *' is not allowed}}
}
-// When targeting the OpenCL execution environment SYCL and OpenCL address space
-// attributes are aligned. Corresponding address are mutually convertible.
void opencl_conv() {
int [[clang::sycl_global]] *SGLOB;
int [[clang::sycl_local]] *SLOC;
@@ -115,8 +113,8 @@ void opencl_conv() {
__attribute__((opencl_constant)) int *OCONST;
__attribute__((opencl_generic)) int *OGEN;
- // Corresponding SYCL/OpenCL address spaces are mutually convertible when
- // targeting OpenCL. An error is generated when not targeting OpenCL.
+ // Corresponding address are mutually convertible. An error is generated
+ // when not targeting OpenCL.
OGLOB = SGLOB; // def-error {{assigning '[[clang::sycl_global]] int *' to '__global int *' changes address space of pointer}}
SGLOB = OGLOB; // def-error {{assigning '__global int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
OLOC = SLOC; // def-error {{assigning '[[clang::sycl_local]] int *' to '__local int *' changes address space of pointer}}
@@ -133,4 +131,27 @@ void opencl_conv() {
OGLOB = SLOC; // expected-error {{assigning '[[clang::sycl_local]] int *' to '__global int *' changes address space of pointer}}
SGLOB = OPRIV; // expected-error {{assigning '__private int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
OCONST = SGLOB; // expected-error {{assigning '[[clang::sycl_global]] int *' to '__constant int *' changes address space of pointer}}
+
+ // The generic address space is a superset of the other address spaces, so a
+ // named SYCL or OpenCL pointer is implicitly convertible to either generic
+ // pointer when targeting OpenCL. An error is generated when not targeting OpenCL.
+ OGEN = SGLOB; // def-error {{assigning '[[clang::sycl_global]] int *' to '__generic int *' changes address space of pointer}}
+ OGEN = SLOC; // def-error {{assigning '[[clang::sycl_local]] int *' to '__generic int *' changes address space of pointer}}
+ OGEN = SPRIV; // def-error {{assigning '[[clang::sycl_private]] int *' to '__generic int *' changes address space of pointer}}
+ SGEN = OGLOB; // def-error {{assigning '__global int *' to '[[clang::sycl_generic]] int *' changes address space of pointer}}
+ SGEN = OLOC; // def-error {{assigning '__local int *' to '[[clang::sycl_generic]] int *' changes address space of pointer}}
+ SGEN = OPRIV; // def-error {{assigning '__private int *' to '[[clang::sycl_generic]] int *' changes address space of pointer}}
+
+ // The two generic address spaces are equivalent when targeting OpenCL. An error
+ // is generated when not targeting OpenCL.
+ SGEN = OGEN; // def-error {{assigning '__generic int *' to '[[clang::sycl_generic]] int *' changes address space of pointer}}
+ OGEN = SGEN; // def-error {{assigning '[[clang::sycl_generic]] int *' to '__generic int *' changes address space of pointer}}
+
+ // Conversion from a generic pointer to a named pointer is diagnosed regardless of the target.
+ SGLOB = OGEN; // expected-error {{assigning '__generic int *' to '[[clang::sycl_global]] int *' changes address space of pointer}}
+ OGLOB = SGEN; // expected-error {{assigning '[[clang::sycl_generic]] int *' to '__global int *' changes address space of pointer}}
+
+ // The constant address space does not overlap the generic address space.
+ SGEN = OCONST; // expected-error {{assigning '__constant int *' to '[[clang::sycl_generic]] int *' changes address space of pointer}}
+ OGEN = SCONST; // expected-error {{assigning '[[clang::sycl_constant]] int *' to '__generic int *' changes address space of pointer}}
}
More information about the cfe-commits
mailing list