This is kind of a weird edge case, but in LLVM IR, you can have multiple entries for the same predecessor block in a phi node if a switch or branch has duplicate destinations. This was reduced from a real failure in the OpenCL.jl test suite when running with the translator backend.
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spir64-unknown-unknown"
define spir_kernel void @f() {
entry:
br i1 undef, label %L815, label %L815
L815: ; preds = %entry, %entry
%v = phi i64 [ 0, %entry ], [ 0, %entry ]
ret void
}
SPIRV-LLVM-Translator translates this verbatim:
; SPIR-V
; Version: 1.0
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 12
; Schema: 0
OpCapability Addresses
OpCapability Kernel
OpCapability Int64
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %4 "f"
OpSource Unknown 0
OpName %entry "entry"
OpName %L815 "L815"
OpName %v "v"
%ulong = OpTypeInt 64 0
%ulong_0 = OpConstant %ulong 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%bool = OpTypeBool
%8 = OpUndef %bool
%4 = OpFunction %void None %3
%entry = OpLabel
OpBranchConditional %8 %L815 %L815
%L815 = OpLabel
%v = OpPhi %ulong %ulong_0 %entry %ulong_0 %entry
OpReturn
OpFunctionEnd
which then fails validation with:
> spirv-val test.spv
error: line 21: OpPhi's number of incoming blocks (2) does not match block's predecessor count (2).
%v = OpPhi %ulong %ulong_0 %entry %ulong_0 %entry
I am not 100% sure whether this is just a bug in spirv-val, but the LLVM backend at least produces %v = OpPhi %ulong %ulong_0 %entry in line 21 here (I actually had to make %v the return and pass -O0 for llc to not just optimize away the phi node)
This is kind of a weird edge case, but in LLVM IR, you can have multiple entries for the same predecessor block in a phi node if a switch or branch has duplicate destinations. This was reduced from a real failure in the OpenCL.jl test suite when running with the translator backend.
SPIRV-LLVM-Translator translates this verbatim:
which then fails validation with:
I am not 100% sure whether this is just a bug in spirv-val, but the LLVM backend at least produces
%v = OpPhi %ulong %ulong_0 %entryin line 21 here (I actually had to make%vthe return and pass-O0forllcto not just optimize away the phi node)