Fix LRA subreg calculation for big-endian targets
commit389a265164a64ed40233eaa5671cf7e4de7e63fb
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Jan 2018 09:45:58 +0000 (30 09:45 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Jan 2018 09:45:58 +0000 (30 09:45 +0000)
tree0a08a5f52896b5ecba9f5b1401c322bd854e0891
parent27e361973a71297b923efd1c1a4943e5619009dd
Fix LRA subreg calculation for big-endian targets

LRA was using a subreg offset of 0 whenever constraints matched
two operands with different modes.  That leads to an invalid offset
(and ICE) on big-endian targets if one of the modes is narrower
than a word.  E.g. if a (reg:SI X) is matched to a (reg:QI Y),
the big-endian subreg should be (subreg:QI (reg:SI X) 3) rather
than (subreg:QI (reg:SI X) 0).

But this raises the issue of what the behaviour should be when the
matched operands occupy different numbers of registers.  Should the
register numbers match, or should the locations of the lsbs match?
Although the documentation isn't clear, reload went for the second
interpretation (which seems the most natural to me):

      /* On a REG_WORDS_BIG_ENDIAN machine, point to the last register of a
         multiple hard register group of scalar integer registers, so that
         for example (reg:DI 0) and (reg:SI 1) will be considered the same
         register.  */

So I think this means that we can/must use the lowpart offset
unconditionally, rather than trying to separate out the multi-register
case.  This also matches the LRA handling of constant integers, which
already uses lowpart subregs.

The patch fixes gcc.target/aarch64/sve/extract_[34].c for aarch64_be.

2018-01-30  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* lra-constraints.c (match_reload): Use subreg_lowpart_offset
rather than 0 when creating partial subregs.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@257177 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/lra-constraints.c