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;
 

Reply via email to