Skip to content

Commit 23fed07

Browse files
[SYCL] Support *global_[device|host]_space in static_address_cast (#15498)
When these address spaces are used with regular `sycl::detail::spirv::GenericCastToPtr` they are turned into `unreachable`. We don't have a SPIR-V intrinsic yet (or maybe we shouldn't even have it, and will continue to rely on standard LLVM IR's `addrspacecast`), so use C-style cast and rely on the translator/backend to generate proper operation, similarly to `sycl::detail::cast_AS`.
1 parent c956940 commit 23fed07

File tree

3 files changed

+74
-9
lines changed

3 files changed

+74
-9
lines changed

sycl/include/sycl/ext/oneapi/experimental/address_cast.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ inline namespace _V1 {
1616
namespace ext {
1717
namespace oneapi {
1818
namespace experimental {
19+
namespace detail {
20+
using namespace sycl::detail;
21+
}
1922
// Shorthands for address space names
2023
constexpr inline access::address_space global_space = access::address_space::global_space;
2124
constexpr inline access::address_space local_space = access::address_space::local_space;
@@ -32,6 +35,18 @@ static_address_cast(ElementType *Ptr) {
3235
if constexpr (Space == generic_space) {
3336
// Undecorated raw pointer is in generic AS already, no extra casts needed.
3437
return ret_ty(Ptr);
38+
} else if constexpr (Space == access::address_space::
39+
ext_intel_global_device_space ||
40+
Space ==
41+
access::address_space::ext_intel_global_host_space) {
42+
#ifdef __ENABLE_USM_ADDR_SPACE__
43+
// No SPIR-V intrinsic for this yet.
44+
using raw_type = detail::DecoratedType<ElementType, Space>::type *;
45+
auto CastPtr = (raw_type)(Ptr);
46+
#else
47+
auto CastPtr = sycl::detail::spirv::GenericCastToPtr<global_space>(Ptr);
48+
#endif
49+
return ret_ty(CastPtr);
3550
} else {
3651
auto CastPtr = sycl::detail::spirv::GenericCastToPtr<Space>(Ptr);
3752
return ret_ty(CastPtr);
@@ -60,6 +75,20 @@ dynamic_address_cast(ElementType *Ptr) {
6075
"The extension expects undecorated raw pointers only!");
6176
if constexpr (Space == generic_space) {
6277
return ret_ty(Ptr);
78+
} else if constexpr (Space == access::address_space::
79+
ext_intel_global_device_space ||
80+
Space ==
81+
access::address_space::ext_intel_global_host_space) {
82+
#ifdef __ENABLE_USM_ADDR_SPACE__
83+
static_assert(
84+
Space != access::address_space::ext_intel_global_device_space &&
85+
Space != access::address_space::ext_intel_global_host_space,
86+
"Not supported yet!");
87+
return ret_ty(nullptr);
88+
#else
89+
auto CastPtr = sycl::detail::spirv::GenericCastToPtr<global_space>(Ptr);
90+
return ret_ty(CastPtr);
91+
#endif
6392
} else {
6493
auto CastPtr = sycl::detail::spirv::GenericCastToPtrExplicit<Space>(Ptr);
6594
return ret_ty(CastPtr);

sycl/test/check_device_code/extensions/address_cast.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2-
// RUN: %clangxx -O3 -fsycl -fsycl-device-only -fno-discard-value-names -S -emit-llvm -fno-sycl-instrument-device-code -o - %s | FileCheck %s
2+
// RUN: %clangxx -D__ENABLE_USM_ADDR_SPACE__ -O3 -fsycl -fsycl-device-only -fno-discard-value-names -S -emit-llvm -fno-sycl-instrument-device-code -o - %s | FileCheck %s
33

44
// Linux/Windows have minor differences in the generated IR (e.g. TBAA
55
// metadata). Having linux-only checks eases the maintenance without sacrifising
@@ -59,45 +59,67 @@ SYCL_EXTERNAL auto to_generic_decorated(decorated_generic_ptr<int> p) {
5959
SYCL_EXTERNAL auto to_generic_not_decorated(int *p) {
6060
return static_address_cast<access::address_space::generic_space>(p);
6161
}
62+
63+
// CHECK-LABEL: define dso_local spir_func void @_ZN14static_as_cast16to_global_deviceEPi(
64+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.3") align 8 [[AGG_RESULT:%.*]], ptr addrspace(4) noundef [[P:%.*]]) local_unnamed_addr #[[ATTR4]] !srcloc [[META35:![0-9]+]] !sycl_fixed_targets [[META7]] {
65+
// CHECK-NEXT: [[ENTRY:.*:]]
66+
// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(4) [[P]] to ptr addrspace(5)
67+
// CHECK-NEXT: store ptr addrspace(5) [[TMP0]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA36:![0-9]+]], !alias.scope [[META38:![0-9]+]]
68+
// CHECK-NEXT: ret void
69+
//
70+
SYCL_EXTERNAL auto to_global_device(int *p) {
71+
return static_address_cast<access::address_space::ext_intel_global_device_space>(p);
72+
}
73+
74+
// CHECK-LABEL: define dso_local spir_func void @_ZN14static_as_cast14to_global_hostEPi(
75+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.4") align 8 [[AGG_RESULT:%.*]], ptr addrspace(4) noundef [[P:%.*]]) local_unnamed_addr #[[ATTR4]] !srcloc [[META41:![0-9]+]] !sycl_fixed_targets [[META7]] {
76+
// CHECK-NEXT: [[ENTRY:.*:]]
77+
// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(4) [[P]] to ptr addrspace(6)
78+
// CHECK-NEXT: store ptr addrspace(6) [[TMP0]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA42:![0-9]+]], !alias.scope [[META44:![0-9]+]]
79+
// CHECK-NEXT: ret void
80+
//
81+
SYCL_EXTERNAL auto to_global_host(int *p) {
82+
return static_address_cast<access::address_space::ext_intel_global_host_space>(p);
83+
}
6284
} // namespace static_as_cast
6385

6486
namespace dynamic_as_cast {
6587
// CHECK-LABEL: define dso_local spir_func void @_ZN15dynamic_as_cast19to_global_decoratedEN4sycl3_V19multi_ptrIiLNS1_6access13address_spaceE6ELNS3_9decoratedE1EEE(
66-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr") align 8 [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval(%"class.sycl::_V1::multi_ptr.0") align 8 [[P:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META35:![0-9]+]] !sycl_fixed_targets [[META7]] {
88+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr") align 8 [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval(%"class.sycl::_V1::multi_ptr.0") align 8 [[P:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META47:![0-9]+]] !sycl_fixed_targets [[META7]] {
6789
// CHECK-NEXT: [[ENTRY:.*:]]
6890
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[P]], align 8, !tbaa [[TBAA8]]
6991
// CHECK-NEXT: [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to ptr addrspace(4)
7092
// CHECK-NEXT: [[CALL_I_I_I_I:%.*]] = tail call spir_func noundef ptr addrspace(1) @_Z41__spirv_GenericCastToPtrExplicit_ToGlobalPvi(ptr addrspace(4) noundef [[TMP1]], i32 noundef 5) #[[ATTR5]]
71-
// CHECK-NEXT: store ptr addrspace(1) [[CALL_I_I_I_I]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA12]], !alias.scope [[META36:![0-9]+]]
93+
// CHECK-NEXT: store ptr addrspace(1) [[CALL_I_I_I_I]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA12]], !alias.scope [[META48:![0-9]+]]
7294
// CHECK-NEXT: ret void
7395
//
7496
SYCL_EXTERNAL auto to_global_decorated(decorated_generic_ptr<int> p) {
7597
return dynamic_address_cast<access::address_space::global_space>(p);
7698
}
7799
// CHECK-LABEL: define dso_local spir_func void @_ZN15dynamic_as_cast23to_global_not_decoratedEPi(
78-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.1") align 8 [[AGG_RESULT:%.*]], ptr addrspace(4) noundef [[P:%.*]]) local_unnamed_addr #[[ATTR2]] !srcloc [[META41:![0-9]+]] !sycl_fixed_targets [[META7]] {
100+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.1") align 8 [[AGG_RESULT:%.*]], ptr addrspace(4) noundef [[P:%.*]]) local_unnamed_addr #[[ATTR2]] !srcloc [[META53:![0-9]+]] !sycl_fixed_targets [[META7]] {
79101
// CHECK-NEXT: [[ENTRY:.*:]]
80102
// CHECK-NEXT: [[CALL_I_I_I:%.*]] = tail call spir_func noundef ptr addrspace(1) @_Z41__spirv_GenericCastToPtrExplicit_ToGlobalPvi(ptr addrspace(4) noundef [[P]], i32 noundef 5) #[[ATTR5]]
81-
// CHECK-NEXT: store ptr addrspace(1) [[CALL_I_I_I]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA20]], !alias.scope [[META42:![0-9]+]]
103+
// CHECK-NEXT: store ptr addrspace(1) [[CALL_I_I_I]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA20]], !alias.scope [[META54:![0-9]+]]
82104
// CHECK-NEXT: ret void
83105
//
84106
SYCL_EXTERNAL auto to_global_not_decorated(int *p) {
85107
return dynamic_address_cast<access::address_space::global_space>(p);
86108
}
87109
// CHECK-LABEL: define dso_local spir_func void @_ZN15dynamic_as_cast20to_generic_decoratedEN4sycl3_V19multi_ptrIiLNS1_6access13address_spaceE6ELNS3_9decoratedE1EEE(
88-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.0") align 8 [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval(%"class.sycl::_V1::multi_ptr.0") align 8 [[P:%.*]]) local_unnamed_addr #[[ATTR3]] !srcloc [[META45:![0-9]+]] !sycl_fixed_targets [[META7]] {
110+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.0") align 8 [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval(%"class.sycl::_V1::multi_ptr.0") align 8 [[P:%.*]]) local_unnamed_addr #[[ATTR3]] !srcloc [[META57:![0-9]+]] !sycl_fixed_targets [[META7]] {
89111
// CHECK-NEXT: [[ENTRY:.*:]]
90112
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[P]], align 8, !tbaa [[TBAA8]]
91-
// CHECK-NEXT: store i64 [[TMP0]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA8]], !alias.scope [[META46:![0-9]+]]
113+
// CHECK-NEXT: store i64 [[TMP0]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA8]], !alias.scope [[META58:![0-9]+]]
92114
// CHECK-NEXT: ret void
93115
//
94116
SYCL_EXTERNAL auto to_generic_decorated(decorated_generic_ptr<int> p) {
95117
return dynamic_address_cast<access::address_space::generic_space>(p);
96118
}
97119
// CHECK-LABEL: define dso_local spir_func void @_ZN15dynamic_as_cast24to_generic_not_decoratedEPi(
98-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.2") align 8 [[AGG_RESULT:%.*]], ptr addrspace(4) noundef [[P:%.*]]) local_unnamed_addr #[[ATTR4]] !srcloc [[META49:![0-9]+]] !sycl_fixed_targets [[META7]] {
120+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias nocapture writable writeonly sret(%"class.sycl::_V1::multi_ptr.2") align 8 [[AGG_RESULT:%.*]], ptr addrspace(4) noundef [[P:%.*]]) local_unnamed_addr #[[ATTR4]] !srcloc [[META61:![0-9]+]] !sycl_fixed_targets [[META7]] {
99121
// CHECK-NEXT: [[ENTRY:.*:]]
100-
// CHECK-NEXT: store ptr addrspace(4) [[P]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA30]], !alias.scope [[META50:![0-9]+]]
122+
// CHECK-NEXT: store ptr addrspace(4) [[P]], ptr addrspace(4) [[AGG_RESULT]], align 8, !tbaa [[TBAA30]], !alias.scope [[META62:![0-9]+]]
101123
// CHECK-NEXT: ret void
102124
//
103125
SYCL_EXTERNAL auto to_generic_not_decorated(int *p) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clangxx -D__ENABLE_USM_ADDR_SPACE__ -fsycl -fsycl-device-only -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=warning,note %s
2+
3+
#include <sycl/sycl.hpp>
4+
5+
using namespace sycl::ext::oneapi::experimental;
6+
7+
SYCL_EXTERNAL void test(int *p) {
8+
// expected-error-re@sycl/ext/oneapi/experimental/address_cast.hpp:* {{{{.*}}Not supported yet!}}
9+
std::ignore = dynamic_address_cast<
10+
sycl::access::address_space::ext_intel_global_device_space>(p);
11+
// expected-error-re@sycl/ext/oneapi/experimental/address_cast.hpp:* {{{{.*}}Not supported yet!}}
12+
std::ignore = dynamic_address_cast<
13+
sycl::access::address_space::ext_intel_global_host_space>(p);
14+
}

0 commit comments

Comments
 (0)