<div dir="ltr">Hi Renato,<div><br></div><div>Thanks for your explanation. It is very helpful. Now I totally understand your concern.</div><div><br></div><div>In GCC, it has a similar representation for scalable vector type. It uses a data structure called poly-int[1] 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.<br><br>Similarly, there is a target hook to calculate (a * X + b) in GCC, called TARGET_ESTIMATED_POLY_VALUE[2]. 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,<br><br>declare i32 llvm.vscale.i32(i32 ElementCount)<br>declare i64 llvm.vscale.i64(i32 ElementCount)<br><br>Does it make sense?<br><br>[1] <a href="https://gcc.gnu.org/onlinedocs/gccint/Overview-of-poly_005fint.html#Overview-of-poly_005fint">https://gcc.gnu.org/onlinedocs/gccint/Overview-of-poly_005fint.html#Overview-of-poly_005fint</a><br>[2] <a href="https://github.com/gcc-mirror/gcc/blob/master/gcc/targhooks.c#L1703">https://github.com/gcc-mirror/gcc/blob/master/gcc/targhooks.c#L1703</a><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 11, 2020 at 11:32 PM Renato Golin <<a href="mailto:rengolin@gmail.com">rengolin@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Kai,<br>
<br>
On Sat, 11 Apr 2020 at 15:55, Kai Wang <<a href="mailto:kai.wang@sifive.com" target="_blank">kai.wang@sifive.com</a>> wrote:<br>
> IIUC. If I could lower LLVM IR to Asm correctly under my type system design, there should be no problem with it.<br>
<br>
It depends on what you mean by "no problem". :)<br>
<br>
The design of the IR is target independent, so that we can represent<br>
language constructs in a generic way and optimise them with a common<br>
infrastructure.<br>
<br>
However, there are three main sources of target-dependence:<br>
<br>
1. Front-ends may lower different IR depending on different targets,<br>
for example valid types, call ABI, etc.<br>
2. The middle-end takes decisions based on target validity, which<br>
changes the shape of IR, for example specific sequences of<br>
instructions on specific types.<br>
3. Intrinsic functions. Those can be generated by the front-end or a<br>
pass optimises code with them, for example, the vectoriser.<br>
<br>
The general trend is that the IR becomes more target-dependent as more<br>
passes change it, but it also means passes are less and less able to<br>
recognise patterns and therefore are less useful on your code. That's<br>
why pass ordering matters.<br>
<br>
A good example is GPU/accelerator code, that if you pass the IR<br>
through the normal pipeline, it comes out the other way unrecognisable<br>
and impossible to lower, so they tend to have their own pass<br>
pipelines.<br>
<br>
You don't want to have a special, so you need to make sure your IR is<br>
as generic as possible, or you won't profit as much, or worse, will<br>
break apart.<br>
<br>
More specifically, the entirety of vscale design has been assuming<br>
integral scales, so anything that is not integral will very likely not<br>
work with existing (and future) standard passes.<br>
<br>
By making your target more special, you have also made it harder to<br>
optimise. Neither you nor the rest of the community wants to add<br>
special cases for odd targets in every optimisation pass, so we need<br>
to find a common ground.<br>
<br>
> 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?<br>
<br>
I personally believe that this would open a can of worms we don't want<br>
to handle. Not right now, at the very least.<br>
<br>
I would strongly oppose to a float value, for all of the problems FP<br>
representation has and the expectation of existing instructions of<br>
taking integer values.<br>
<br>
But it could be doable to have a fractional value, like two integers,<br>
where the numerator doesn't have to be greater than nor a multiple of<br>
the denominator (with default value as 1).<br>
<br>
Again, I'm not the authority here, I'm just giving some context. Other<br>
scalable vector developers should chime in with their opinion.<br>
<br>
cheers,<br>
--renato<br>
</blockquote></div>