You should look into how this works with clang. Clang allows you to
do things like this, for example:
typedef __attribute__(( ext_vector_type(4) )) float float4;
float2 vec2, vec2_2;
float4 vec4, vec4_2;
float f;
void test2() {
vec2 = vec4.xy; // shorten
f = vec2.x; // extract elt
vec4 = vec4.yyyy; // splat
vec4.zw = vec2; // insert
}
etc. It also offers operators to extract all the even or odd elements
of a vector, do arbitrary two-input-vector shuffles with
__builtin_shuffle etc.
Right, our frontend supports all these things as well. I think it's a pretty small change to shufflevector to be able to support any of these with a single LLVM IR instruction. We'll have a look at how clang handles this.
OK. I'd love to hear more, especially if someone is planning to do
this in the short term.
Most of the extensions you suggest are great ideas, but we need more
than ideas: we need someone to help implement the ideas ;-).
Understood. I didn't mean to imply that I expect someone to do this :). If someone was already working on something like this it would be valuable to know though. I really just want to understand if these are real gaps or there's something I'm missing.
It turns out that having them return vectors of i1 would be somewhat
complicated. For example, a <4 x i1> on an SSE2 target could expand
either to 1 <4 x i32> or 2 <2 x i64>s, and the optimal thing would
be to make the decision based on the comparison that produced them,
but LLVM isn't yet equipped for that.
Can you expand on this a bit? I'm guessing you're referring to
specific mechanics in LLVM's code generation framework making this
difficult to do?
I'm not sure that it really is a matter of what is easy or hard to do
in LLVM. This model more closely matches the model implemented by
common SIMD systems like Altivec, SSE, CellSPU, Alpha, etc. The
design of the system was picked to model the systems that we know of
well, we obviously can't plan to handle systems that we don't know
about.
Those are precisely the architectures I have in mind as well. I was curious to hear more about why "LLVM isn't yet equipped for that".
Take the SPU for example. In the quote above, Dan mentioned it's necessary to make the decision as to what to actually use as the representation for an i1 based on the comparison that generated it. On SSE this is true for vectors of i1. On the SPU, this is true even for scalars, since there's no actual condition register, and booleans must be represented as bitmasks when it comes to selecting from them. Thus this problem must be solved with the IR as it is today to map a regular scalar cmp followed by a scalar select instruction to efficient SPU code.
Of course an option is to make this a problem for the frontend instead of the backend, but in the case of vectors that's difficult to do right now without vector shifts, and there are cases where the backend will be able to make a smarter choice about the representation of booleans (e.g. using bit operations vs CMOV on x86).
vicmp and vfcmp are very much aimed at solving practical problems on
popular architectures without needing significant new infrastructure
They're relatively new, and as you say, they'll be more useful when
combined with vector shifts and friends and we start teaching LLVM
to recognize popular idioms with them.
Can you give me examples of how they are used today at all? I'm having
a really hard time figuring out a good use for them (that doesn't
involve effectively scalarizing them immediately) without these other
instructions.
They can be used with target-specific intrinsics. For example, SSE
provides a broad range of intrinsics to support instructions that LLVM
IR can't express well. See llvm/include/llvm/IntrinsicsX86.td for
more details.
Ah, now that makes sense. I can see how these instructions can be useful if one is also using intrinsics.
If you're interested in helping shape the direction of LLVM vector
support, my advice is that "patches speak louder than words" :). I'd
love to see improved vector support in LLVM, but unless someone is
willing to step forward and implement it, it is all just idle talk.
Absolutely understood. As a past contributor to and maintainer of a number of open source projects, I hear you! I just want to make sure I'm understanding the existing semantics, and the reasons behind them, correctly, before I venture way off course! 