Skip to content

Commit 7bf4a6d

Browse files
authored
[SYCL] Enable basic support for 2020 specialization constants in sycl-post-link (#3353)
SYCL 2020 specialization constants implementation will use new intrinsic in DPC++ headers to provide required markup for the compiler. By doing this change, SpecConstantsPass starts to support new interface for specialization constants. It doesn't implement handling of new arguments, which would be done in further PRs (for now new arguments are just ignored).
1 parent 86716c5 commit 7bf4a6d

File tree

4 files changed

+82
-9
lines changed

4 files changed

+82
-9
lines changed

llvm/test/tools/sycl-post-link/composite-spec-constant.ll

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: sycl-post-link -spec-const=rt --ir-output-only %s -S -o - \
2-
; RUN: | FileCheck %s --implicit-check-not __sycl_getCompositeSpecConstantValue
2+
; RUN: | FileCheck %s --implicit-check-not __sycl_getCompositeSpecConstantValue --implicit-check-not __sycl_getComposite2020SpecConstantValue
33
;
44
; This test is intended to check that sycl-post-link tool is capable of handling
55
; composite specialization constants by lowering them into a set of SPIR-V
@@ -22,8 +22,6 @@
2222
;
2323
; CHECK: %[[#POD:]] = call %struct._ZTS3POD.POD @"_Z29__spirv_SpecConstantCompositeAstruct._ZTS1A.Aclass._ZTSN2cl4sycl3vecIiLi2EEE.cl::sycl::vec"([2 x %struct._ZTS1A.A] %[[#NA]], %"class._ZTSN2cl4sycl3vecIiLi2EEE.cl::sycl::vec" %[[#B]]), !SYCL_SPEC_CONST_SYM_ID ![[#MD:]]
2424
; CHECK: store %struct._ZTS3POD.POD %[[#POD]]
25-
;
26-
; CHECK: ![[#MD]] = !{!"_ZTS3POD", i32 [[#ID]], i32 [[#ID + 1]], i32 [[#ID + 2]], i32 [[#ID + 3]], i32 [[#ID + 4]], i32 [[#ID + 5]]}
2725

2826
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
2927
target triple = "spir64-unknown-unknown-sycldevice"
@@ -36,8 +34,10 @@ target triple = "spir64-unknown-unknown-sycldevice"
3634
%"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id" = type { %"class._ZTSN2cl4sycl6detail5arrayILi1EEE.cl::sycl::detail::array" }
3735

3836
$_ZTS4Test = comdat any
37+
$_ZTS17SpecializedKernel = comdat any
3938

4039
@__builtin_unique_stable_name._ZNK2cl4sycl6ONEAPI12experimental13spec_constantI3PODS4_E3getIS4_EENSt9enable_ifIXsr3std6is_podIT_EE5valueES8_E4typeEv = private unnamed_addr addrspace(1) constant [9 x i8] c"_ZTS3POD\00", align 1
40+
@__builtin_unique_stable_name._ZNK2cl4sycl6ONEAPI12experimental13spec_constantI13MyComposConstE3getIS4_EENSt9enable_ifIXaasr3std8is_classIT_EE5valuesr3std6is_podIS9_EE5valueES9_E4typeEv = private unnamed_addr addrspace(1) constant [20 x i8] c"_ZTS13MyComposConst\00", align 1
4141

4242
; Function Attrs: convergent norecurse uwtable
4343
define weak_odr dso_local spir_kernel void @_ZTS4Test(%struct._ZTS3POD.POD addrspace(1)* %_arg_, %"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range"* byval(%"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range") align 8 %_arg_1, %"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range"* byval(%"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range") align 8 %_arg_2, %"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id"* byval(%"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id") align 8 %_arg_3) local_unnamed_addr #0 comdat !kernel_arg_buffer_location !4 {
@@ -57,6 +57,34 @@ entry:
5757
ret void
5858
}
5959

60+
; Function Attrs: convergent norecurse
61+
define weak_odr dso_local spir_kernel void @_ZTS17SpecializedKernel(float addrspace(1)* %_arg_, %"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range"* byval(%"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range") align 8 %_arg_1, %"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range"* byval(%"class._ZTSN2cl4sycl5rangeILi1EEE.cl::sycl::range") align 8 %_arg_2, %"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id"* byval(%"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id") align 8 %_arg_3) local_unnamed_addr #0 comdat !kernel_arg_buffer_location !4 {
62+
entry:
63+
%c.i = alloca %struct._ZTS1A.A, align 4
64+
%0 = getelementptr inbounds %"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id", %"class._ZTSN2cl4sycl2idILi1EEE.cl::sycl::id"* %_arg_3, i64 0, i32 0, i32 0, i64 0
65+
%1 = addrspacecast i64* %0 to i64 addrspace(4)*
66+
%2 = load i64, i64 addrspace(4)* %1, align 8
67+
%add.ptr.i = getelementptr inbounds float, float addrspace(1)* %_arg_, i64 %2
68+
%c.ascast.i = addrspacecast %struct._ZTS1A.A* %c.i to %struct._ZTS1A.A addrspace(4)*
69+
%3 = bitcast %struct._ZTS1A.A* %c.i to i8*
70+
call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %3) #3
71+
call spir_func void @_Z40__sycl_getComposite2020SpecConstantValueI13MyComposConstET_PKcPvS4_(%struct._ZTS1A.A addrspace(4)* sret(%struct._ZTS1A.A) align 4 %c.ascast.i, i8 addrspace(4)* getelementptr inbounds ([20 x i8], [20 x i8] addrspace(4)* addrspacecast ([20 x i8] addrspace(1)* @__builtin_unique_stable_name._ZNK2cl4sycl6ONEAPI12experimental13spec_constantI13MyComposConstE3getIS4_EENSt9enable_ifIXaasr3std8is_classIT_EE5valuesr3std6is_podIS9_EE5valueES9_E4typeEv to [20 x i8] addrspace(4)*), i64 0, i64 0), i8 addrspace(4)* null, i8 addrspace(4)* null) #4
72+
; CHECK: %[[#N0:]] = call i32 @_Z20__spirv_SpecConstantii(i32 [[#ID + 6]], i32
73+
; CHECK: %[[#N1:]] = call float @_Z20__spirv_SpecConstantif(i32 [[#ID + 7]], float
74+
; CHECK: %[[#CONST:]] = call %struct._ZTS1A.A @_Z29__spirv_SpecConstantCompositeif(i32 %[[#N0]], float %[[#N1]]), !SYCL_SPEC_CONST_SYM_ID ![[#MD1:]]
75+
; CHECK: %struct._ZTS1A.A %[[#CONST]]
76+
%a.i = getelementptr inbounds %struct._ZTS1A.A, %struct._ZTS1A.A addrspace(4)* %c.ascast.i, i64 0, i32 0
77+
%4 = load i32, i32 addrspace(4)* %a.i, align 4
78+
%conv.i = sitofp i32 %4 to float
79+
%b.i = getelementptr inbounds %struct._ZTS1A.A, %struct._ZTS1A.A addrspace(4)* %c.ascast.i, i64 0, i32 1
80+
%5 = load float, float addrspace(4)* %b.i, align 4
81+
%add.i = fadd float %5, %conv.i
82+
%ptridx.ascast.i.i = addrspacecast float addrspace(1)* %add.ptr.i to float addrspace(4)*
83+
store float %add.i, float addrspace(4)* %ptridx.ascast.i.i, align 4, !tbaa !11
84+
call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %3) #3
85+
ret void
86+
}
87+
6088
; Function Attrs: argmemonly nounwind willreturn
6189
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
6290

@@ -69,6 +97,9 @@ declare void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* noalias nocapture write
6997
; Function Attrs: convergent
7098
declare dso_local spir_func void @_Z36__sycl_getCompositeSpecConstantValueI3PODET_PKc(%struct._ZTS3POD.POD addrspace(4)* sret(%struct._ZTS3POD.POD) align 8, i8 addrspace(4)*) local_unnamed_addr #2
7199

100+
; Function Attrs: convergent
101+
declare dso_local spir_func void @_Z40__sycl_getComposite2020SpecConstantValueI13MyComposConstET_PKcPvS4_(%struct._ZTS1A.A addrspace(4)* sret(%struct._ZTS1A.A) align 4, i8 addrspace(4)*, i8 addrspace(4)*, i8 addrspace(4)*) local_unnamed_addr #2
102+
72103
attributes #0 = { convergent norecurse uwtable "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="../sycl/test/spec_const/composite.cpp" "tune-cpu"="generic" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" }
73104
attributes #1 = { argmemonly nounwind willreturn }
74105
attributes #2 = { convergent "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
@@ -80,6 +111,8 @@ attributes #4 = { convergent }
80111
!spirv.Source = !{!2}
81112
!llvm.ident = !{!3}
82113

114+
; CHECK: ![[#MD]] = !{!"_ZTS3POD", i32 [[#ID]], i32 [[#ID + 1]], i32 [[#ID + 2]], i32 [[#ID + 3]], i32 [[#ID + 4]], i32 [[#ID + 5]]}
115+
; CHECK: ![[#MD1]] = !{!"_ZTS13MyComposConst", i32 [[#ID + 6]], i32 [[#ID + 7]]}
83116
!0 = !{i32 1, !"wchar_size", i32 4}
84117
!1 = !{i32 1, i32 2}
85118
!2 = !{i32 4, i32 100000}
@@ -89,3 +122,6 @@ attributes #4 = { convergent }
89122
!6 = !{!7, !7, i64 0}
90123
!7 = !{!"omnipotent char", !8, i64 0}
91124
!8 = !{!"Simple C++ TBAA"}
125+
!9 = !{!"int", !7, i64 0}
126+
!10 = !{!"float", !7, i64 0}
127+
!11 = !{!10, !10, i64 0}

llvm/test/tools/sycl-post-link/spec_const_O2.ll

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ $_ZTS17SpecializedKernel = comdat any
3939
; CHECK-NOT: @__unique_stable_name.SC_If12MyFloatConstE3getEv
4040
@__unique_stable_name.SC_Id13MyDoubleConstE3getEv = private unnamed_addr constant [20 x i8] c"_ZTS13MyDoubleConst\00", align 1
4141
; CHECK-NOT: @__unique_stable_name.SC_Id13MyDoubleConstE3getEv
42+
@__unique_stable_name.SC_Id14MyDoubleConst2E3getEv = private unnamed_addr constant [21 x i8] c"_ZTS14MyDoubleConst2\00", align 1
43+
; CHECK-NOT: @__unique_stable_name.SC_Id14MyDoubleConst2E3getEv
4244

4345
; Function Attrs: norecurse
4446
define weak_odr dso_local spir_kernel void @_ZTS17SpecializedKernel(float addrspace(1)* %0, %"cl::sycl::range"* byval(%"cl::sycl::range") align 8 %1, %"cl::sycl::range"* byval(%"cl::sycl::range") align 8 %2, %"cl::sycl::id"* byval(%"cl::sycl::id") align 8 %3) local_unnamed_addr #0 comdat !kernel_arg_addr_space !4 !kernel_arg_access_qual !5 !kernel_arg_type !6 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 {
@@ -111,10 +113,14 @@ define weak_odr dso_local spir_kernel void @_ZTS17SpecializedKernel(float addrsp
111113
; CHECK-RT: %{{[0-9]+}} = call double @_Z20__spirv_SpecConstantid(i32 10, double 0.000000e+00), !SYCL_SPEC_CONST_SYM_ID ![[ID10:[0-9]+]]
112114
%36 = fadd double %35, %34
113115
; CHECK-DEF: %[[SUM9:[0-9]+]] = fadd double 0.000000e+00, %[[VAL7]]
114-
%37 = fptrunc double %36 to float
115-
; CHECK-DEF: %[[VAL8:[0-9]+]] = fptrunc double %[[SUM9]] to float
116-
%38 = addrspacecast float addrspace(1)* %7 to float addrspace(4)*
117-
store float %37, float addrspace(4)* %38, align 4, !tbaa !8
116+
%37 = tail call spir_func double @_Z37__sycl_getScalar2020SpecConstantValueIdET_PKcPvS3_(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([21 x i8], [21 x i8]* @__unique_stable_name.SC_Id14MyDoubleConst2E3getEv, i64 0, i64 0) to i8 addrspace(4)*), i8 addrspace(4)* null, i8 addrspace(4)* null)
117+
; CHECK-RT: %{{[0-9]+}} = call double @_Z20__spirv_SpecConstantid(i32 11, double 0.000000e+00), !SYCL_SPEC_CONST_SYM_ID ![[ID11:[0-9]+]]
118+
%38 = fadd double %37, %36
119+
; CHECK-DEF: %[[SUM10:[0-9]+]] = fadd double 0.000000e+00, %[[SUM9]]
120+
%39 = fptrunc double %38 to float
121+
; CHECK-DEF: %[[VAL8:[0-9]+]] = fptrunc double %[[SUM10]] to float
122+
%40 = addrspacecast float addrspace(1)* %7 to float addrspace(4)*
123+
store float %39, float addrspace(4)* %40, align 4, !tbaa !8
118124
ret void
119125
}
120126

@@ -140,6 +146,8 @@ declare dso_local spir_func float @_Z27__sycl_getSpecConstantValueIfET_PKc(i8 ad
140146

141147
declare dso_local spir_func double @_Z27__sycl_getSpecConstantValueIdET_PKc(i8 addrspace(4)*) local_unnamed_addr #1
142148

149+
declare dso_local spir_func double @_Z37__sycl_getScalar2020SpecConstantValueIdET_PKcPvS3_(i8 addrspace(4)*, i8 addrspace(4)*, i8 addrspace(4)*) local_unnamed_addr #1
150+
143151
attributes #0 = { norecurse "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "sycl-module-id"="/iusers/kbobrovs/ws/kbobrovs_llvm/sycl/test/spec_const/spec_const_types.cpp" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" }
144152
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
145153

@@ -172,3 +180,4 @@ attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-
172180
; CHECK-RT: ![[ID8]] = !{!"_ZTS13MyUInt64Const", i32 8}
173181
; CHECK-RT: ![[ID9]] = !{!"_ZTS12MyFloatConst", i32 9}
174182
; CHECK-RT: ![[ID10]] = !{!"_ZTS13MyDoubleConst", i32 10}
183+
; CHECK-RT: ![[ID11]] = !{!"_ZTS14MyDoubleConst2", i32 11}

llvm/tools/sycl-post-link/SpecConstants.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ namespace {
2828
constexpr char SYCL_GET_SPEC_CONST_VAL[] = "_Z27__sycl_getSpecConstantValue";
2929
constexpr char SYCL_GET_COMPOSITE_SPEC_CONST_VAL[] =
3030
"_Z36__sycl_getCompositeSpecConstantValue";
31+
constexpr char SYCL_GET_SCALAR_2020_SPEC_CONST_VAL[] =
32+
"_Z37__sycl_getScalar2020SpecConstantValue";
33+
constexpr char SYCL_GET_COMPOSITE_2020_SPEC_CONST_VAL[] =
34+
"_Z40__sycl_getComposite2020SpecConstantValue";
3135

3236
// Unmangled base name of all __spirv_SpecConstant intrinsics which differ by
3337
// the value type.
@@ -426,7 +430,9 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
426430
continue;
427431

428432
if (!F.getName().startswith(SYCL_GET_SPEC_CONST_VAL) &&
429-
!F.getName().startswith(SYCL_GET_COMPOSITE_SPEC_CONST_VAL))
433+
!F.getName().startswith(SYCL_GET_COMPOSITE_SPEC_CONST_VAL) &&
434+
!F.getName().startswith(SYCL_GET_SCALAR_2020_SPEC_CONST_VAL) &&
435+
!F.getName().startswith(SYCL_GET_COMPOSITE_2020_SPEC_CONST_VAL))
430436
continue;
431437

432438
SmallVector<CallInst *, 32> SCIntrCalls;
@@ -443,7 +449,8 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
443449
// literals are passed to it in the SYCL RT source code, and application
444450
// code can't use this intrinsic directly.
445451
bool IsComposite =
446-
F.getName().startswith(SYCL_GET_COMPOSITE_SPEC_CONST_VAL);
452+
F.getName().startswith(SYCL_GET_COMPOSITE_SPEC_CONST_VAL) ||
453+
F.getName().startswith(SYCL_GET_COMPOSITE_2020_SPEC_CONST_VAL);
447454

448455
SmallVector<Instruction *, 3> DelInsts;
449456
DelInsts.push_back(CI);

sycl/include/CL/sycl/detail/sycl_fe_intrins.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,25 @@ SYCL_EXTERNAL T __sycl_getSpecConstantValue(const char *ID);
2121
template <typename T>
2222
SYCL_EXTERNAL T __sycl_getCompositeSpecConstantValue(const char *ID);
2323

24+
// The intrinsics below are used to implement support SYCL2020 specialization
25+
// constants. SYCL2020 version requires more parameters compared to the initial
26+
// version.
27+
28+
// Get the value of the specialization constant with given symbolic ID.
29+
// `SymbolicID` is a unique string ID of a specialization constant.
30+
// `DefaultValue` contains a pointer to a global variable with the initializer,
31+
// which should be used as the default value of the specialization constants.
32+
// `RTBuffer` is a pointer to a runtime buffer, which holds values of all
33+
// specialization constant and should be used if native specialization constants
34+
// are not available.
35+
template <typename T>
36+
SYCL_EXTERNAL T __sycl_getScalar2020SpecConstantValue(const char *SymbolicID,
37+
void *DefaultValue,
38+
void *RTBuffer);
39+
40+
template <typename T>
41+
SYCL_EXTERNAL T __sycl_getComposite2020SpecConstantValue(const char *SymbolicID,
42+
void *DefaultValue,
43+
void *RTBuffer);
44+
2445
#endif

0 commit comments

Comments
 (0)