With a configurable vector size, it is not really feasible to represent
every vector register
inside GCC as a collection of lots of imaginary BITS_PER_WORD registers.
So you got your general purpose registers that are BITS_PER_WORD, and
vector registers
that are a bit or a lot larger. To void invalid code being emitted by
reload, you have to define TARGET_CAN_CHANGE_MODE_CLASS to reject the
use of vector registers for values
where certain kinds of SUBREGs are used. In practice, that's most of them.
To avoid register allocation mayhem, the port has to steer the
middle-end away from
the tried-and-true-and-generating-absymal-code path of SUBREGs. There
are a number
of choices for lvalues. vec_select is sort of obvious and works to a
point, but it doesn't
scale well because the access representation changes according to the
content of
vector registers. And it doesn't work at all as an lvalue.
ZERO_EXTRACT has none of these problems. It can describe a bitfield
access independent of
the vector structure (if any) of outer and inner mode, and it is valid
as an lvalue.
Unfortunately, add_predicate_code in gensupport.c didn't get the message.
This patch fixes that.
Bootstrapped and regression tested on x86_64-pc-linux-gnu .
2018-11-10 Joern Rennecke <joern.renne...@riscy-ip.com>
* gensupport.c (add_predicate_code): Properly handle ZERO_EXTRACT
as an lvalue.
Index: gensupport.c
===================================================================
--- gensupport.c (revision 266008)
+++ gensupport.c (working copy)
@@ -2827,6 +2827,7 @@ add_predicate_code (struct pred_data *pr
&& code != CONCAT
&& code != PARALLEL
&& code != STRICT_LOW_PART
+ && code != ZERO_EXTRACT
&& code != SCRATCH)
pred->allows_non_lvalue = true;