SPIR-V generator is crashed on a simple device execution kernel.
Closed this issue · 6 comments
SPRI-V converter hits the following assert during conversion from the attached LLVM IR to SPIR-V
Assertion `HasVariWC && WC >= WordCount && "Invalid word count"' failed.
To reproduce:
$ llvm-as enqueue.ll.txt -o enqueue.bc && llvm-spirv enqueue.bc
Call stack enqueue.bt.txt
The problematic LLVM IL enqueue.ll.txt is compiled from the following OpenCL C 2.0 source code
void __kernel one(__global float * inout) {
_inout = cos(_inout);
}
void __kernel two(__global float * inout) {
enqueue_kernel(get_default_queue(), CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange_1D(1), ^{one(inout);});
}
This test is invalid. The LLVM/SPIR-V translator expects arguments of enqueue_kernel follows the SPIR 2.0 format. The attached LLVM IR does not conform to SPIR 2.0.
Guys, I've uploaded OpenCL front-end compiler to https://github.com/KhronosGroup/SPIR - 'spirv-1.0' branch. It supports both versions of OpenCL languages - 1.x and 2.0, but I didn't modify blocks implementation for two reasons:
- It's not necessary for SPIR-V translation. It was only required for SPIR-2.0 specification.
- I'd like to contribute https://github.com/KhronosGroup/SPIR - 'spirv-1.0' branch patches to clang repository (http://llvm.org/svn/llvm-project/cfe/trunk). Modifying blocks for OpenCL doesn't make sense since it's not much different from existing implementation, so I assumed it will be rejected.
I tested this new front-end with conformance tests for 1.2 and 2.0. Everything should be fine, except blocks.
I'm going to write a short readme file with instructions how to generate SPIR-V file from OpenCL using this new front-end compiler and after that I'm going to fix this bug.
Sam, are you OK with switching from SPIR 1.2 ang SPIR 2.0 generators to new clang?
I think we'd better find a way to support blocks in OpenCL.
Since OpenCL does not support function pointer, blocks need to be represented in a way facilitating extraction of invoke function. Also OCL runtime needs to pass kernel arguments to the kernels, there need a way to represent the context pointer, size and alignment.
The SPIR 2.0 blocks do that.
The clang representation has two issues:
- stores invoke function and context pointer in stack var, which make them difficult to extract
- no context size and alignment info
For now we may temporarily use clang representation of blocks. I want to take a look if it is possible to translate that to SPIR-V. We may revisit this issue later.
Reproduced on LLVM BC compiled from the same OpenCL C with SPIR 2.0 generator (i.e. with spir 2.0 blocks).
spir20.blocks.bc.zip
Seems there is a bug in SPIR 2.0 generator (branch spir_20_provisional). It produces invalid IR for device execution. I'll leave this issue open because of SPIR2.0/Apple blocks discussion.
Just in case attaching correct BC
correct.spir20.blocks.bc.zip
I've implemented SPIR 2.0 blocks in spirv-1.0 branch, so now your OpenCL source successfully compiles with 49a8b4a rev.
I suggest closing this issue.