Skip to content

Commit 9b280f4

Browse files
jcranmer-intelsvenvh
authored andcommitted
Fix some mangling bugs in the Itanium name mangler.
Substitution rules in Itanium mangled names are unfortunately more complex and harder to parse than they should be, and there were two bugs that cropped in the current implementation (as found by running c++filt on the resulting names and discovering that they didn't demangle correctly). The first bug was that unqualified names double-registered the underlying pointer type. A mangled pointer type like PU3AS419__spirv_DeviceEvent should generate three substitutable names: * 19__spirv_DeviceEvent [a user-defined type gets an entry] * U3AS419__spirv_DeviceEvent [qualifiers of a pointer get an entry] * PU3AS419__spirv_DeviceEvent [the pointer as a whole gets an entry] However, if there's no qualifiers--we get a P19__spirv_DeviceEvent instead-- the original code was still adding multiple entries as follows: * 19__spirv_DeviceEvent [a user-defined type gets an entry] * 19__spirv_DeviceEvent [qualifiers of a pointer, but there are none!] * P19__spirv_DeviceEvent [the pointer as a whole gets an entry] The second bug is in the representation of the block pointer type for kernels: this is mangled as U13block_pointerFvvE. This type actually gets two entries: * FvvE [void(void) function type] * U13block_pointerFvvE [block_pointer-qualified function type] We weren't adding any entries for either of these types, causing later type entries to be offset by two. With this patch, these type entries *still* aren't added, so the mangling is incorrect if multiple block types are present in a function declaration. Since such functions don't exist for OpenCL/SPIR-V, it's okay that these cases are not correctly handled.
1 parent 21fee92 commit 9b280f4

File tree

4 files changed

+19
-12
lines changed

4 files changed

+19
-12
lines changed

lib/SPIRV/Mangler/Mangler.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ class MangleVisitor : public TypeVisitor {
118118
Stream << "P" << AttrMangling;
119119
// and the pointee type itself.
120120
Me = P->getPointee()->accept(this);
121-
// The type qualifiers plus a pointee type is a substitutable entity
122-
recordSubstitution(Stream.str().substr(Fpos + 1));
121+
// The type qualifiers plus a pointee type is a substitutable entity, but
122+
// only when there are qualifiers in the first place.
123+
if (!AttrMangling.empty())
124+
recordSubstitution(Stream.str().substr(Fpos + 1));
123125
// The complete pointer type is substitutable as well
124126
recordSubstitution(Stream.str().substr(Fpos));
125127
}
@@ -167,6 +169,11 @@ class MangleVisitor : public TypeVisitor {
167169
}
168170
}
169171
Stream << "E";
172+
// "Add" the function type (FvvE) and U13block_pointerFvvE to the
173+
// substitution table. We don't actually substitute this if it's present,
174+
// but since the block type only occurs at most once in any function we care
175+
// about, this should be sufficient.
176+
SeqId += 2;
170177
return MANGLE_SUCCESS;
171178
}
172179

test/transcoding/BuildNDRange_2.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
; CHECK-LLVM: call spir_func void @_Z10ndrange_3DPKmS0_S0_(%struct.ndrange_t* sret(%struct.ndrange_t)
6161

6262
; CHECK-LLVM-SPV-LABEL: @test_ndrange_2D3D
63-
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_2DPlS0_S0_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[A-Z,a-z,0-9]+}}, [2 x i64] %{{[0-9]+}}, [2 x i64] zeroinitializer, [2 x i64] zeroinitializer)
64-
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_3DPlS0_S0_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[A-Z,a-z,0-9]+}}, [3 x i64] %{{[0-9]+}}, [3 x i64] zeroinitializer, [3 x i64] zeroinitializer)
63+
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_2DPlS_S_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[A-Z,a-z,0-9]+}}, [2 x i64] %{{[0-9]+}}, [2 x i64] zeroinitializer, [2 x i64] zeroinitializer)
64+
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_3DPlS_S_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[A-Z,a-z,0-9]+}}, [3 x i64] %{{[0-9]+}}, [3 x i64] zeroinitializer, [3 x i64] zeroinitializer)
6565
; CHECK-LLVM-SPV-LABEL: @test_ndrange_const_2D3D
66-
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_2DPlS0_S0_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[a-z,a-z,0-9]+}}, [2 x i64] %{{[0-9]+}}, [2 x i64] zeroinitializer, [2 x i64] zeroinitializer)
66+
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_2DPlS_S_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[a-z,a-z,0-9]+}}, [2 x i64] %{{[0-9]+}}, [2 x i64] zeroinitializer, [2 x i64] zeroinitializer)
6767

68-
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_3DPlS0_S0_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[a-z,a-z,0-9]+}}, [3 x i64] %{{[0-9]+}}, [3 x i64] zeroinitializer, [3 x i64] zeroinitializer)
68+
; CHECK-LLVM-SPV: call spir_func void @_Z23__spirv_BuildNDRange_3DPlS_S_(%struct.ndrange_t* sret(%struct.ndrange_t) %{{[a-z,a-z,0-9]+}}, [3 x i64] %{{[0-9]+}}, [3 x i64] zeroinitializer, [3 x i64] zeroinitializer)
6969

7070

7171
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"

test/transcoding/enqueue_kernel.cl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
6767
// CHECK-LLVM: [[Block2Ptr:%[0-9]+]] = addrspacecast i8* [[InterCast2]] to i8 addrspace(4)*
6868
// CHECK-LLVM: [[BlockInv2:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_kernel to i8 addrspace(4)*
6969
// CHECK-LLVM: call spir_func i32 @__enqueue_kernel_basic(%opencl.queue_t* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i8 addrspace(4)* [[BlockInv2]], i8 addrspace(4)* [[Block2Ptr]])
70-
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS7_U13block_pointerFvvEPU3AS4cii(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %spirv.DeviceEvent* addrspace(4)* null, %spirv.DeviceEvent* addrspace(4)* null, void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}})
70+
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS5_U13block_pointerFvvEPU3AS4cii(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %spirv.DeviceEvent* addrspace(4)* null, %spirv.DeviceEvent* addrspace(4)* null, void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}})
7171
enqueue_kernel(default_queue, flags, ndrange,
7272
^(void) {
7373
a[i] = c0;
@@ -88,7 +88,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
8888
// CHECK-LLVM: [[Block3Ptr:%[0-9]+]] = addrspacecast i8* [[InterCast3]] to i8 addrspace(4)
8989
// CHECK-LLVM: [[BlockInv3:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_2_kernel to i8 addrspace(4)*
9090
// CHECK-LLVM: call spir_func i32 @__enqueue_kernel_basic_events(%opencl.queue_t* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t* addrspace(4)* {{.*}}, %opencl.clk_event_t* addrspace(4)* {{.*}}, i8 addrspace(4)* [[BlockInv3]], i8 addrspace(4)* [[Block3Ptr]])
91-
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS7_U13block_pointerFvvEPU3AS4cii(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 2, %spirv.DeviceEvent* addrspace(4)* {{.*}}, %spirv.DeviceEvent* addrspace(4)* {{.*}}, void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_2_kernel, i8 addrspace(4)* %{{.*}}, i32 {{.*}}, i32 {{.*}})
91+
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS5_U13block_pointerFvvEPU3AS4cii(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 2, %spirv.DeviceEvent* addrspace(4)* {{.*}}, %spirv.DeviceEvent* addrspace(4)* {{.*}}, void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_2_kernel, i8 addrspace(4)* %{{.*}}, i32 {{.*}}, i32 {{.*}})
9292
enqueue_kernel(default_queue, flags, ndrange, 2, &event_wait_list, &clk_event,
9393
^(void) {
9494
a[i] = b[i];
@@ -109,7 +109,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
109109
// CHECK-LLVM: [[Block0:%[0-9]+]] = addrspacecast i8 addrspace(1)* [[Block0Tmp]] to i8 addrspace(4)*
110110
// CHECK-LLVM: [[BlockInv0:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*, i8 addrspace(3)*)* @__device_side_enqueue_block_invoke_3_kernel to i8 addrspace(4)*
111111
// CHECK-LLVM: call spir_func i32 @__enqueue_kernel_events_varargs(%opencl.queue_t* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t* addrspace(4)* {{.*}}, %opencl.clk_event_t* addrspace(4)* {{.*}}, i8 addrspace(4)* [[BlockInv0]], i8 addrspace(4)* [[Block0]], i32 1, i32* {{.*}})
112-
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS7_U13block_pointerFvvEPU3AS4ciiPi(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 2, %spirv.DeviceEvent* addrspace(4)* {{.*}}, %spirv.DeviceEvent* addrspace(4)* {{.*}}, void (i8 addrspace(4)*, i8 addrspace(3)*)* @__device_side_enqueue_block_invoke_3_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}}, i32* {{.*}})
112+
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS5_U13block_pointerFvvEPU3AS4ciiPi(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 2, %spirv.DeviceEvent* addrspace(4)* {{.*}}, %spirv.DeviceEvent* addrspace(4)* {{.*}}, void (i8 addrspace(4)*, i8 addrspace(3)*)* @__device_side_enqueue_block_invoke_3_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}}, i32* {{.*}})
113113
enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event,
114114
^(local void *p) {
115115
return;
@@ -132,7 +132,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
132132
// CHECK-LLVM: [[Block1:%[0-9]+]] = addrspacecast i8 addrspace(1)* [[Block1Tmp]] to i8 addrspace(4)*
133133
// CHECK-LLVM: [[BlockInv1:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*, i8 addrspace(3)*, i8 addrspace(3)*, i8 addrspace(3)*)* @__device_side_enqueue_block_invoke_4_kernel to i8 addrspace(4)*
134134
// CHECK-LLVM: call spir_func i32 @__enqueue_kernel_varargs(%opencl.queue_t* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i8 addrspace(4)* [[BlockInv1]], i8 addrspace(4)* [[Block1]], i32 3, i32* {{.*}})
135-
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS7_U13block_pointerFvvEPU3AS4ciiPiSB_SB_(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %spirv.DeviceEvent* addrspace(4)* null, %spirv.DeviceEvent* addrspace(4)* null, void (i8 addrspace(4)*, i8 addrspace(3)*, i8 addrspace(3)*, i8 addrspace(3)*)* @__device_side_enqueue_block_invoke_4_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}}, i32* {{.*}}, i32* {{.*}}, i32* {{.*}})
135+
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS5_U13block_pointerFvvEPU3AS4ciiPiSA_SA_(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %spirv.DeviceEvent* addrspace(4)* null, %spirv.DeviceEvent* addrspace(4)* null, void (i8 addrspace(4)*, i8 addrspace(3)*, i8 addrspace(3)*, i8 addrspace(3)*)* @__device_side_enqueue_block_invoke_4_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}}, i32* {{.*}}, i32* {{.*}}, i32* {{.*}})
136136
enqueue_kernel(default_queue, flags, ndrange,
137137
^(local void *p1, local void *p2, local void *p3) {
138138
return;
@@ -153,7 +153,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
153153
// CHECK-LLVM: [[Block5Ptr:%[0-9]+]] = addrspacecast i8* [[InterCast5]] to i8 addrspace(4)
154154
// CHECK-LLVM: [[BlockInv5:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_5_kernel to i8 addrspace(4)*
155155
// CHECK-LLVM: call spir_func i32 @__enqueue_kernel_basic_events(%opencl.queue_t* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %opencl.clk_event_t* addrspace(4)* null, %opencl.clk_event_t* addrspace(4)* {{.*}}, i8 addrspace(4)* [[BlockInv5]], i8 addrspace(4)* [[Block5Ptr]])
156-
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS7_U13block_pointerFvvEPU3AS4cii(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %spirv.DeviceEvent* addrspace(4)* null, %spirv.DeviceEvent* addrspace(4)* {{.*}}, void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_5_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}})
156+
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueKernelP13__spirv_Queuei9ndrange_tiPU3AS4P19__spirv_DeviceEventS5_U13block_pointerFvvEPU3AS4cii(%spirv.Queue* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i32 0, %spirv.DeviceEvent* addrspace(4)* null, %spirv.DeviceEvent* addrspace(4)* {{.*}}, void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_5_kernel, i8 addrspace(4)* {{.*}}, i32 {{.*}}, i32 {{.*}})
157157
enqueue_kernel(default_queue, flags, ndrange, 0, NULL, &clk_event,
158158
^(void) {
159159
a[i] = b[i];

test/transcoding/enqueue_marker.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ kernel void test_enqueue_marker(global int *out) {
2020
// CHECK-SPIRV: EnqueueMarker
2121
// CHECK-LLVM: _Z14enqueue_marker9ocl_queuejPU3AS4K12ocl_clkeventPU3AS4S0_
2222
// CHECK-SPV-IR: call spir_func %spirv.Queue* @_Z23__spirv_GetDefaultQueuev()
23-
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueMarkerP13__spirv_QueuejPU3AS4P19__spirv_DeviceEventS6_(%spirv.Queue* %0, i32 1, %spirv.DeviceEvent* addrspace(4)* %waitlist.ascast, %spirv.DeviceEvent* addrspace(4)* %evt.ascast)
23+
// CHECK-SPV-IR: call spir_func i32 @_Z21__spirv_EnqueueMarkerP13__spirv_QueuejPU3AS4P19__spirv_DeviceEventS4_(%spirv.Queue* %0, i32 1, %spirv.DeviceEvent* addrspace(4)* %waitlist.ascast, %spirv.DeviceEvent* addrspace(4)* %evt.ascast)
2424
*out = enqueue_marker(queue, 1, &waitlist, &evt);
2525
}

0 commit comments

Comments
 (0)