[LLVMdev] Vector instructions

Stefanus Du Toit stefanus.dutoit at rapidmind.com
Thu Jun 26 13:56:50 PDT 2008


I have some questions as to the definition of various vector
instructions. In particular, I believe there are some gaps and
inconsistencies in the vector instructions, and I'm interested in
hearing whether you agree that these should be improved or whether
there are other ways to solve these problems.

1. Shufflevector only accepts vectors of the same type

Shufflevector seems overly restrictive right now in terms of its type
requirements. In particular, it requires (this could be clearer in the
language reference, but is supported by equivalent assertions in the
source code) that the types of the sources and destinations match
exactly. Obviously it makes sense for the element types to match, but
the requirement that the number of elements in each source operand
matches the number of elements in the destination appears overly

I would propose to change the syntax from:

> <result> = shufflevector <n x <ty>> <v1>, <n x <ty>> <v2>, <n x i32>
> <mask> ; yields <n x <ty>>


> <result> = shufflevector <a x <ty>> <v1>, <b x <ty>> <v2>, <d x i32>
> <mask> ; yields <d x <ty>>

With the requirement that the entries in the (still constant) mask are
within the range of [0, a + b - 1].

This allows things like taking a <2 x i32> and duplicating it into a
<4 x i32>.

This is very useful for frontends that provide general vector
functionality. I think this is more consistent with the relaxed rules
on numbers of vector elements.

2. vector select

SIMD-within-a-register ISAs generally provide some form of efficient
vector select capabilities. It would be very convenient to be able to
have a select of the form:

> <result> = select <n x i1> <cond>, <n x <ty>> <val1>, <n x <ty>>
> <val2> ; yields <n x <ty>>

The semantics of this would be to set each element in the result to
the corresponding element in val1 or val2, depending on whether the
corresponding element in cond is set or not.

This would make the vector types more consistent with the regular
types. It's possible to do this with masking, but that requires
building masks of the appropriate size in the IR each time one wants
to do this kind of selection, which is cumbersome and will have to be
matched by codegen to be turned into something like the Cell SPU's
"selb" instruction.

3. vector trunc, sext, zext, fptrunc, fpext

These seem like obvious gaps in the IR. Conversions between integer
and floating point vectors are supported, but conversions from one
integer vector to another  integer vector type (and likewise for
float) are not. Attempting to do this by hand is extremely cumbersome,
and may hurt codegen opportunities as well as optimization

4. vector shl, lshr, ashr

Again, these simply seem to be simply missing (compared to the other
bitwise ops). Not having vector versions of shift right, and not
having vector trunc, makes things like converting bitmasks of various
sizes very difficult. Modern SIMD architectures have good support for
bitshifts of vector types.

There are of course two ways to interpret a shift on a vector type:
within elements and across elements. To us, shifts within elements
(i.e. the equivalent of N scalar shifts) are more important than
shifts (or rotates!) across elements, but the latter could be useful
in some situations as well.

4. vfcmp, vicmp return types

This topic came up recently on llvm-dev (thread "VFCmp failing when
unordered or UnsafeFPMath on x86"). Having vector compares return a
vector of integer elements with bit width equal to the element types
being compared seems unnecessarily inconsistent with the icmp and fcmp
instructions. Since only one bit is well-defined anyways, why not just
return a vector of i1 elements? If after codegen this is expanded into
some other width, that's fine -- the backend can do this since only
one bit of information is exposed at the IR level anyways.

Having these instructions return vector of i1 would also be nicely
consistent with a vector select operation. Vector bit shifts and trunc
would make this easier, but it seems to me that the entire IR would be
far more consistent if these operations simply returned i1 vectors.

I am interested in hearing feedback on whether these ideas make sense,
or if there's some good reason for things being the way they are now
that I'm not seeing. I would also be interested, especially in the
short term, in suggestions as to how to work around the lack of these



Stefanus Du Toit <stefanus.dutoit at rapidmind.com>
   RapidMind Inc.
   phone: +1 519 885 5455 x116 -- fax: +1 519 885 1463

More information about the llvm-dev mailing list