This relands a6ca88e908b5befcd9b0f8c8cb40f53095cc17bc which was originally
reverted due to overflow bugs in e3fa2b1eab60342dc882b7b888658b03c472fa2b.
This patch teaches the compiler to identify a wider variety of
BUILD_VECTORs which form integer arithmetic sequences, and to lower
them to vid.v with modifications for non-unit steps and non-zero
addends.
The sequences handled by this optimization must either be monotonically
increasing or decreasing. Consecutive elements holding the same value
indicate a fractional step which, while simple mathematically,
becomes more complex to handle both in the realm of lossy integer
division and in the presence of undefs.
For example, a common "interleaving" shuffle index will be lowered by
LLVM to both <0,u,1,u,2,...> and <u,0,u,1,u,...> BUILD_VECTOR
nodes. Either of these would ideally be lowered to vid.v shifted right
by 1. Detection of this sequence in presence of general undef values
is more complicated, however: <0,u,u,1,> could match either
<0,0,0,1,> or <0,0,1,1,> depending on later values in the sequence.
Both are possible, so backtracking or multiple passes is inevitable.
Sticking to monotonic sequences keeps the logic simpler as it can be
done in one pass. Fractional steps will likely be a separate
optimization in a future patch.
This may overflow here e.g. 0 - INT64_MIN.