-
Notifications
You must be signed in to change notification settings - Fork 818
Description
Generated Image Sample/Fetch SPIR-V is invalid
DPC++ emits OpImageSample* (or other related sampling ops) with a result type that is not a 4-component vector, which violates SPIR-V validity rules for sampling instructions. For example, the spec for OpImageSampleExplicitLod states
Result Type must be a vector of four components of floating-point type or integer type
Compile any bindless sampled image test which uses non-4-component vector returns, such as sampling_1D.cpp and run the generated SPIR-V through the spirv validator:
> spirv-val.exe sycl_spir64.spv
error: line 156: Expected Result Type to be int or float vector type
%call1_i_i_i = OpImageSampleExplicitLod %float %call_i_i %div_i_i Lod %float_0This can be fixed in DPC++ pretty simply and I have a patch for this which I can post a PR for soon.
Spec/model mismatch
SPIR-V allows OpImageRead / non-sampling reads to return either a scalar or a vector of various widths. In contrast, OpenCL's built-in image read functions always return 4-component vectors. This is not necessarily invalid SPIR-V by itself, however, when targeting the OpenCL execution environment, additional constraints may demand the enforcement of OpenCL-style vector widths.
It would be helpful to clarify whether DPC++ intends to strictly follow OpenCL's image semantics in its SPIR-V lowering, or whether narrower result types are considered acceptable under the OpenCL execution environment.
Example: SPIRV-LLVM-Translator behavior under OpenCL semantics
For an example of the trade-off between strictly following the SPIR-V specification and targeting OpenCL image semantics, we can examine the behavior of the upstream SPIRV-LLVM-Translator. When provided with the SPIR-V module generated by the read_write_unsampled.cpp test using the command-line invocation:
llvm-spirv --spirv-target-env CL2.0 -r read_write_unsampled.spv -o read_write_unsampled.bc the resulting LLVM bitcode is malformed.
This occurs due to an implicit assumption in the SPIR-V–to–OpenCL translation that OpImageRead always returns a four-component vector. When this assumption is violated, name mangling and signature mismatches occur, resulting in function definitions being incorrectly overwritten in the generated LLVM IR.
Thanks to @AdamBrouwersHarries for pointing the above out!
Tagging @bashbaug for his opinion👋, thanks!
Environment
- OS: N/A
- Target device and vendor: N/A
- DPC++ version: clang version 21.0.0
- Dependencies version: N/A
Additional context
No response