[llvm-dev] Questions about vscale
Kai Wang via llvm-dev
llvm-dev at lists.llvm.org
Mon Apr 13 07:59:25 PDT 2020
Thanks for your explanation. It is very helpful. Now I totally understand
In GCC, it has a similar representation for scalable vector type. It uses a
data structure called poly-int to represent the run-time part. It also
used to represent the relationship(half size, double size, etc.) between
types. It looks similar to (a * X + b) * type. X represents the run-time
value. It is equivalent to LLVM representation using vscale * n * type.
Similarly, there is a target hook to calculate (a * X + b) in GCC, called
TARGET_ESTIMATED_POLY_VALUE. The difference between GCC and LLVM is that
GCC uses whole polynomial expression to calculate the actual run-time
vector length instead of getting the run-time variable only, i.e., X in GCC
and vscale in LLVM. Maybe it is not a good idea to return float for vscale
intrinsic. It should be more reasonable to take the element count into the
intrinsic to calculate the actual run-time length for scalable vector
types. That is,
declare i32 llvm.vscale.i32(i32 ElementCount)
declare i64 llvm.vscale.i64(i32 ElementCount)
Does it make sense?
On Sat, Apr 11, 2020 at 11:32 PM Renato Golin <rengolin at gmail.com> wrote:
> Hi Kai,
> On Sat, 11 Apr 2020 at 15:55, Kai Wang <kai.wang at sifive.com> wrote:
> > IIUC. If I could lower LLVM IR to Asm correctly under my type system
> design, there should be no problem with it.
> It depends on what you mean by "no problem". :)
> The design of the IR is target independent, so that we can represent
> language constructs in a generic way and optimise them with a common
> However, there are three main sources of target-dependence:
> 1. Front-ends may lower different IR depending on different targets,
> for example valid types, call ABI, etc.
> 2. The middle-end takes decisions based on target validity, which
> changes the shape of IR, for example specific sequences of
> instructions on specific types.
> 3. Intrinsic functions. Those can be generated by the front-end or a
> pass optimises code with them, for example, the vectoriser.
> The general trend is that the IR becomes more target-dependent as more
> passes change it, but it also means passes are less and less able to
> recognise patterns and therefore are less useful on your code. That's
> why pass ordering matters.
> A good example is GPU/accelerator code, that if you pass the IR
> through the normal pipeline, it comes out the other way unrecognisable
> and impossible to lower, so they tend to have their own pass
> You don't want to have a special, so you need to make sure your IR is
> as generic as possible, or you won't profit as much, or worse, will
> break apart.
> More specifically, the entirety of vscale design has been assuming
> integral scales, so anything that is not integral will very likely not
> work with existing (and future) standard passes.
> By making your target more special, you have also made it harder to
> optimise. Neither you nor the rest of the community wants to add
> special cases for odd targets in every optimisation pass, so we need
> to find a common ground.
> > Another concern I have is that llvm.vscale intrinsic is designed to
> return integer value. Should we relax it to return float or something else?
> I personally believe that this would open a can of worms we don't want
> to handle. Not right now, at the very least.
> I would strongly oppose to a float value, for all of the problems FP
> representation has and the expectation of existing instructions of
> taking integer values.
> But it could be doable to have a fractional value, like two integers,
> where the numerator doesn't have to be greater than nor a multiple of
> the denominator (with default value as 1).
> Again, I'm not the authority here, I'm just giving some context. Other
> scalable vector developers should chime in with their opinion.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev