KhronosGroup / KhronosGroup/SPIRV-LLVM-Translator

Reverse translating a translated SPIR-V crashes the tool

Open
#2,008 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
LLVM
Stars
625
Forks
279
Avg merge
3d 5h
Merged PRs (30d)
34

Description

Translation of the following bitcode with an image function call:

```llvm
; ModuleID = 'image.bc'
source_filename = "image.cl"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spirv64"

; Function Attrs: convergent mustprogress nofree norecurse nounwind willreturn memory(read)
define spir_func <4 x float> @test(ptr addrspace(1) readonly %i, ptr addrspace(2) readonly %s, <2 x float> noundef %c) local_unnamed_addr #0 {
entry:
%call = tail call spir_func <4 x float> @_Z11read_imagef14ocl_image2d_ro11ocl_samplerDv2_f(ptr addrspace(1) %i, ptr addrspace(2) %s, <2 x float> noundef %c) #2
ret <4 x float> %call
}

; Function Attrs: convergent mustprogress nofree nounwind willreturn memory(read)
declare spir_func <4 x float> @_Z11read_imagef14ocl_image2d_ro11ocl_samplerDv2_f(ptr addrspace(1), ptr addrspace(2), <2 x float> noundef) local_unnamed_addr #1

attributes #0 = { convergent mustprogress nofree norecurse nounwind willreturn memory(read) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { convergent mustprogress nofree nounwind willreturn memory(read) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #2 = { convergent nounwind willreturn memory(read) }

!llvm.module.flags = !{!0, !1}
!opencl.ocl.version = !{!2}
!llvm.ident = !{!3}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"frame-pointer", i32 2}
!2 = !{i32 2, i32 0}
!3 = !{!"clang version 16.0.4 (https://github.com/llvm/llvm-project.git b44bb302d38c06ad0088150966c8f7d19ec853b8)"}
```

To SPIR-V with llvm-spirv-16 succeeds but reverse translating the result crashes the tool:

```
$ lvm-spirv -r image.spv -o /dev/null
llvm-spirv: /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/include/llvm/Support/Casting.h:579: decltype(auto) llvm::cast(From*) [with To = llvm::CallInst; From = llvm::Value]: Assertion `isa(Val) && "cast() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: ../install/bin/llvm-spirv -r image.spv -o /dev/null
#0 0x00007ff0fcc3083f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/lib/Support/Unix/Signals.inc:567:22
#1 0x00007ff0fcc2e9a4 llvm::sys::RunSignalHandlers() /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/lib/Support/Signals.cpp:104:20
#2 0x00007ff0fcc2eb46 SignalHandler(int) /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/lib/Support/Unix/Signals.inc:412:1
#3 0x00007ff0fb948520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#4 0x00007ff0fb99ca7c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#5 0x00007ff0fb99ca7c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
#6 0x00007ff0fb99ca7c pthread_kill ./nptl/pthread_kill.c:89:10
#7 0x00007ff0fb948476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
#8 0x00007ff0fb92e7f3 abort ./stdlib/abort.c:81:7
#9 0x00007ff0fb92e71b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007ff0fb93fe96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x00005639b80558f5 (../install/bin/llvm-spirv+0x11c8f5)
#12 0x00005639b805e74a decltype(auto) llvm::cast(llvm::Value*) /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/include/llvm/IR/Instructions.h:1703:32
#13 0x00005639b805e74a SPIRV::SPIRVToOCLBase::visitCallSPIRVImageSampleExplicitLodBuiltIn(llvm::CallInst*, spv::Op) /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/projects/SPIRV-LLVM-Translator/lib/SPIRV/SPIRVToOCL.cpp:744:44
#14 0x00005639b80626ed SPIRV::SPIRVToOCLBase::visitCallInst(llvm::CallInst&) /mnt/md0/linehill/ws-chip-spv-3/llvm-project/llvm/projects/SPIRV-LLVM-Translator/lib/SPIRV/SPIRVToOCL.cpp:176:5
...
```

llvms-spirv-15 also crashes and probably the older versions crash too.

I spotted the SPIR-V binary has an odd bitcast between the OpSampleImage and OpImageSampleExplicitLod instruction:

```
; SPIR-V
; Version: 1.0
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 19
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
OpCapability ImageBasic
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical64 OpenCL
OpSource OpenCL_C 200000
OpName %test "test"
OpName %i "i"
OpName %s "s"
OpName %c "c"
OpName %entry "entry"
OpName %TempSampledImage "TempSampledImage"
OpName %call "call"
OpDecorate %test LinkageAttributes "test" Export
OpDecorate %i FuncParamAttr NoWrite
OpDecorate %s FuncParamAttr NoWrite
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%void = OpTypeVoid
%5 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
%6 = OpTypeSampler
%v2float = OpTypeVector %float 2
%8 = OpTypeFunction %v4float %5 %6 %v2float
%14 = OpTypeSampledImage %5
%float_0 = OpConstant %float 0
%test = OpFunction %v4float None %8
%i = OpFunctionParameter %5
%s = OpFunctionParameter %6
%c = OpFunctionParameter %v2float
%entry = OpLabel
%TempSampledImage = OpSampledImage %14 %i %s
%16 = OpBitcast %14 %TempSampledImage
%call = OpImageSampleExplicitLod %v4float %16 %c Lod %float_0
OpReturnValue %call
OpFunctionEnd
```
And the bitcast upsets the validator:
```
$ spirv-val image.spv
error: line 32: Result from OpSampledImage instruction must not appear as operand for OpBitcast, since it is not specified as taking an OpTypeSampledImage. Found result '15[%TempSampledImage]' as an operand of '16[%16]'.
%TempSampledImage = OpSampledImage %14 %i %s
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the failure by translating the provided LLVM IR and reverse translating image.spv, then inspect SPIRVToOCL.cpp around visitCallSPIRVImageSampleExplicitLodBuiltIn at line 744. Compare the generated OpSampledImage, OpBitcast, and OpImageSampleExplicitLod sequence with the validator error. Done means the image case reverse-translates without crashing and the generated SPIR-V no longer contains the invalid bitcast.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.