Skip to content

Invalid SPIR-V for image sampling ops and spec/model mismatch for non-sampled reads #21366

@Seanst98

Description

@Seanst98

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_0

This 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions