(Resend, since it didn't seem to reach the mailing list the first time)
LLVM's type legalizer is changing the types of BUILD_VECTORs in a way
that seems wrong to me, but I'm not sure if this is a bug or if some
targets may be relying on it.
On a 32-bit target, the default action for legalizing i8 and i16 types
is to promote them. If you then have a BUILD_VECTOR to construct a
legal vector type composed of i8 or i16 values, the type legalizer
will look at the BUILD_VECTOR operands and decide that it needs to
promote them to i32 types. You end up with a BUILD_VECTOR that
constructs a vector of i32 values that are then bitcast to the
original vector type.
This works fine for SSE, where it appears that BUILD_VECTORs are
intentionally canonicalized to use i32 elements for the benefit of
CSE. I'm looking at implementing something where I think I'd like to
keep the original vector types. Is this behavior in the type
legalizer something that should be changed?
another way this could be done is to say that the operands of a
BUILD_VECTOR don't have to have the same type as the element type
of the built vector. Then when the type legalizer sees a
v4i16 = BUILD_VECTOR(i16, i16, i16, i16) it can turn this into a
v4i16 = BUILD_VECTOR(i32, i32, i32, i32) and it will be happy
(all result and operand types are legal). This requires changing
the definition of BUILD_VECTOR slightly. Targets will need to
understand that only the bottom 16 bits of the operands are to
be used, but I doubt that's a problem. Would this solve your
PS: Can you please give a concrete example where the current
behavior causes trouble for you?