Skip to content

Commit 0b6f8aa

Browse files
Fznamznonvmaksimo
authored andcommitted
Fix production of OpPtrCastToGeneric instruction (intel#1163)
In LLVM it is valid if addrspace cast result pointer has not only other address space, but also other element type. However spec states that for Storage Class changing instructions Result Type and Pointer must point to the same type. So, this patch adds a regularization step that adds an additional bitcast in case address space cast changes pointer element type as well and then everything can be easily translated to valid SPIR-V that is accepted by spirv-val. Original commit: KhronosGroup/SPIRV-LLVM-Translator@0161b32
1 parent 025829e commit 0b6f8aa

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

llvm-spirv/lib/SPIRV/SPIRVRegularizeLLVM.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,25 @@ bool SPIRVRegularizeLLVMBase::regularize() {
359359
II.setMetadata(MDName, nullptr);
360360
}
361361
}
362+
// Add an additional bitcast in case address space cast also changes
363+
// pointer element type.
364+
if (auto *ASCast = dyn_cast<AddrSpaceCastInst>(&II)) {
365+
Type *DestTy = ASCast->getDestTy();
366+
Type *SrcTy = ASCast->getSrcTy();
367+
if (DestTy->getPointerElementType() !=
368+
SrcTy->getPointerElementType()) {
369+
PointerType *InterTy =
370+
PointerType::get(DestTy->getPointerElementType(),
371+
SrcTy->getPointerAddressSpace());
372+
BitCastInst *NewBCast = new BitCastInst(
373+
ASCast->getPointerOperand(), InterTy, /*NameStr=*/"", ASCast);
374+
AddrSpaceCastInst *NewASCast =
375+
new AddrSpaceCastInst(NewBCast, DestTy, /*NameStr=*/"", ASCast);
376+
ToErase.push_back(ASCast);
377+
ASCast->dropAllReferences();
378+
ASCast->replaceAllUsesWith(NewASCast);
379+
}
380+
}
362381
if (auto Cmpxchg = dyn_cast<AtomicCmpXchgInst>(&II)) {
363382
// Transform:
364383
// %1 = cmpxchg i32* %ptr, i32 %comparator, i32 %0 seq_cst acquire

llvm-spirv/test/transcoding/enqueue_kernel.cl

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// RUN: llvm-spirv %t.bc -spirv-text -o %t.spv.txt
33
// RUN: FileCheck < %t.spv.txt %s --check-prefix=CHECK-SPIRV
44
// RUN: llvm-spirv %t.bc -o %t.spv
5+
// RUN: spirv-val %t.spv
56
// RUN: llvm-spirv -r %t.spv -o %t.rev.bc
67
// RUN: llvm-dis %t.rev.bc
78
// RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
@@ -60,7 +61,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
6061
// [[BlockKer1]] [[BlockLit1]] [[ConstInt17]] [[ConstInt8]]
6162

6263
// CHECK-LLVM: [[Block2:%[0-9]+]] = bitcast [[BlockTy2]]* %block to %struct.__opencl_block_literal_generic*
63-
// CHECK-LLVM: [[Block2Ptr:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[Block2]] to i8 addrspace(4)*
64+
// CHECK-LLVM: [[InterCast2:%[0-9]+]] = bitcast %struct.__opencl_block_literal_generic* [[Block2]] to i8
65+
// CHECK-LLVM: [[Block2Ptr:%[0-9]+]] = addrspacecast i8* [[InterCast2]] to i8 addrspace(4)*
6466
// CHECK-LLVM: [[BlockInv2:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_kernel to i8 addrspace(4)*
6567
// CHECK-LLVM: call i32 @__enqueue_kernel_basic(%opencl.queue_t* {{.*}}, i32 {{.*}}, %struct.ndrange_t* {{.*}}, i8 addrspace(4)* [[BlockInv2]], i8 addrspace(4)* [[Block2Ptr]])
6668
enqueue_kernel(default_queue, flags, ndrange,
@@ -79,7 +81,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
7981
// [[BlockKer2]] [[BlockLit2]] [[ConstInt20]] [[ConstInt8]]
8082

8183
// CHECK-LLVM: [[Block3:%[0-9]+]] = bitcast [[BlockTy3]]* %block4 to %struct.__opencl_block_literal_generic*
82-
// CHECK-LLVM: [[Block3Ptr:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[Block3]] to i8 addrspace(4)
84+
// CHECK-LLVM: [[InterCast3:%[0-9]+]] = bitcast %struct.__opencl_block_literal_generic* [[Block3]] to i8
85+
// CHECK-LLVM: [[Block3Ptr:%[0-9]+]] = addrspacecast i8* [[InterCast3]] to i8 addrspace(4)
8386
// CHECK-LLVM: [[BlockInv3:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_2_kernel to i8 addrspace(4)*
8487
// CHECK-LLVM: call 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]])
8588
enqueue_kernel(default_queue, flags, ndrange, 2, &event_wait_list, &clk_event,
@@ -140,7 +143,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i, char c0) {
140143
// [[BlockKer5]] [[BlockLit5]] [[ConstInt20]] [[ConstInt8]]
141144

142145
// CHECK-LLVM: [[Block5:%[0-9]+]] = bitcast [[BlockTy3]]* %block15 to %struct.__opencl_block_literal_generic*
143-
// CHECK-LLVM: [[Block5Ptr:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[Block5]] to i8 addrspace(4)
146+
// CHECK-LLVM: [[InterCast5:%[0-9]+]] = bitcast %struct.__opencl_block_literal_generic* [[Block5]] to i8
147+
// CHECK-LLVM: [[Block5Ptr:%[0-9]+]] = addrspacecast i8* [[InterCast5]] to i8 addrspace(4)
144148
// CHECK-LLVM: [[BlockInv5:%[0-9]+]] = addrspacecast void (i8 addrspace(4)*)* @__device_side_enqueue_block_invoke_5_kernel to i8 addrspace(4)*
145149
// CHECK-LLVM: call 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]])
146150
enqueue_kernel(default_queue, flags, ndrange, 0, NULL, &clk_event,

0 commit comments

Comments
 (0)