llvmpipe: use scalar load instead of vectors for small vectors in fs backend
authorRoland Scheidegger <sroland@vmware.com>
Thu, 22 Dec 2016 02:48:05 +0000 (03:48 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Fri, 6 Jan 2017 22:13:34 +0000 (23:13 +0100)
commit53c2d24a24a631a5be0a9c4df88f23dda1e8685c
treeb6ad122861699ab5c9e8f64bae5b3dfddf5207df
parent1472ff35914fb50c8b49a4f8678c76327e7da75c
llvmpipe: use scalar load instead of vectors for small vectors in fs backend

llvm has _huge_ problems trying to load things like <4 x i8> vectors and
stitching such loads together to form 128bit vectors. My understanding
of the problem is that the type legalizer tries to extend that to
really a <4 x i32> vector and not a <16 x i8> vector with the 4 elements
first then followed by padding, so the shuffles for then combining things
together are more or less impossible - you can in fact see the pmovzxd
llvm generates. Pre-4.0 llvm just gives up on it completely and does a 30+
pextrb/pinsrb sequence instead.
It looks like current llvm has fixed this behavior (my guess would be
due to better shuffle combination and load/shuffle folds), but we can
avoid this by just loading as <1 x i32> values, combine that and only
cast at the end. (I suspect it might also work if we'd pad the loaded
vectors immediately before shuffling them together, instead of directly
stitching 2 such vectors together pairwise before combining the pair.
But this _might_ lose the ability to load the values directly into
their right place in the vector with pinsrd.). But using 32bit values
is probably easier for llvm as it will never give it funny ideas how
the vector should look like.
(This is possibly only a problem for 1x8bit formats, since 2x8bit will
end up fetching 64bit hence only two vectors are stitched together,
not 4, but we use the same strategy anyway.)

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/drivers/llvmpipe/lp_state_fs.c