[llvm] [SPIR-V][Codegen] Add isPhi bit to MCInstrDesc/MIR definitions (PR #110019)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 04:27:29 PDT 2024
VyacheslavLevytskyy wrote:
> How does PHI end up transforming into an OpPhi? Can you directly consume generic PHI instructions, and only change the final encoding?
@arsenm There is a brief answer and a long one to this very good question.
PHI is transformed into OpPhi after instruction selection, and it's after "InstructionSelect" step that we observe complaints from MachineVerifier. I would expect that it's a right step to generate target-specific machine instructions (https://llvm.org/docs/CodeGenerator.html#instruction-selection-section).
I'd also expect it to be a quite non-trivial task to use generic `phi` to the very end of translation instead of creating them during instruction selection. I can think immediately about result type that `OpPhi` expects to be a part of the instruction and `phi` can't support by itself, and about difference of referring to predecessors:
- It's a requirement of the SPIR-V specification (https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpPhi) that "There must be exactly one Parent i for each parent block of the current block in the CFG.", but
- `phi`-node should have one entry for each predecessor (meaning for each instance of the edge), so that `%retval.0.i = phi i32 [ 0, %sw.default.i ], [ 1, %entry ], [ 1, %entry ]` is equivalent to `%retval_0_i = OpPhi %uint %uint_0 %13 %uint_1 %12` where there is just one record per 2 original %entry predecessors.
I don't say that it's impossible to implement, because it's virtually anything that can be implemented, but it definitely seems unfair to force anyone selecting between being considered invalid and develop something overcomplicated just to avoid such a misjudgment -- and that's actually a part of a longer answer. The point is that GlobalISel has rather poor support for a higher level specification that is SPIR-V. If we narrow things just to MachineVerifier, I can recall one more example, when it's impossible to satisfy MachineVerifier.
In `G_BITCAST` we see `if (SrcTy == DstTy) report("bitcast must change the type", MI);` where SrcTy and DstTy both being LLT pointers just have no means to express the notion of pointer type that is important for SPIR-V where a user may and should use bitcast between pointers with different pointee types (see, https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpBitcast).
I guess this PR is not such a good place for a long reply, but I'd like to provide you with a better context and probably to hear from you an early feedback about the wider problem, even before me and @michalpaszkowski hopefully touch this topic at the 2024 LLVM Developers’ Meeting.
https://github.com/llvm/llvm-project/pull/110019
More information about the llvm-commits
mailing list