[llvm] [SPIR-V][Codegen] Represent the property of the target to declare and use typed pointers and update MachineVerifier to use it (PR #110270)

Vyacheslav Levytskyy via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 1 07:01:16 PDT 2024


VyacheslavLevytskyy wrote:

> > SPIR-V uses typed pointers, so in case of SPIR-V G_BITCAST between two pointers does convey an information about the pointee.
> 
> But it does not. G_BITCAST does not carry additional information about the pointee type. Your OpBitcast is carrying more information than G_BITCAST, so it's not the same thing. If we were to allow G_BITCAST to have identical types, it would still be a legal transformation to just replace G_BITCAST with COPY. Your operator here is not the same as bitcast, and requires introducing something else.
> 
> > The relevant part is
> > ```
> >          %r1 = OpFunctionCall %_ptr_Function_uchar %f1
> >          %16 = OpFunctionCall %_ptr_Function_uint %f2
> >          %r2 = OpBitcast %_ptr_Function_uchar %16
> >         %ret = OpPhi %_ptr_Function_uchar %r1 %24 %r2 %25
> > ```
> 
> I don't understand how the system is supposed to work as a whole. The pointee types do not exist in the LLVM IR, so how are you supposed to just introduce them out of nowhere? You have to just treat everything as uchar*? At what point are these OpBitcasts getting produced?
> 
> > From LLVM IR, having definitions of `f1()` and `f2()`, we must assign `%r1` to be a pointer to uchar and `%r2` a pointer to uint.
> 
> Based on what? This information is not in the original IR

We are just getting deeper into implementation details of SPIRV Backend and shifting the discussion from G_BITCAST to a much more complicated and wider topic of how SPIRV Backend is getting along with GISel without actually being supported by GISel in the part of typed pointers (and others). I'm not sure that it's absolutely relevant to this particular PR, although I'd be happy to provide you with any details of implementation.

> But it does not. G_BITCAST does not carry additional information about the pointee type. Your OpBitcast is carrying more information than G_BITCAST.

It's a good point and you are absolutely right in that. G_BITCAST doesn't pass this info on its own, but only with the help of additional data structures. That's why you see in this PR implementation as an `if` based on target-specific lowering properties. G_BITCAST on its own has no place to store anything related to typed pointers and so to reason about them, so this current implementation of the PR in fact proposes to G_BITCAST just to believe that the target knows what it's doing when inserting G_BITCAST with two pointers. On GISel level there is no way to check if this operation makes sense and is not a no-op, that's why a new method in target lowering that can be overridden by a target.

> > From LLVM IR, having definitions of `f1()` and `f2()`, we must assign `%r1` to be a pointer to uchar and `%r2` a pointer to uint.
> 
> Based on what? This information is not in the original IR

Inferring types from `store i32 32, ptr %p`. We clearly see that `%p` is `i32*` in this case. Unfortunately SPIRV spec requires us to know (and so to deduce) this.

> At what point are these OpBitcasts getting produced?

During instruction selection step.

GISel doesn't keep track of how newly created virtual registers are related to original LLVM IR. SPIRV Backend needs to do it however, to conform with the requirement to track pointee types. LLVM IR doesn't provide direct info about pointee types, but it's possible to infer it. Both points are not directly related to this PR though. The focus point of this PR is that G_BITCAST restricts `bitcast` from using pointer to pointer conversion, because the notion of typed pointers is removed from LLVM IR, but not from SPIRV. It looks like an imperfection that we have a chance to fix.




https://github.com/llvm/llvm-project/pull/110270


More information about the llvm-commits mailing list