diff options
author | Matthew Fortune <matthew.fortune@imgtec.com> | 2017-02-22 17:20:14 +0000 |
---|---|---|
committer | Matthew Fortune <mpf@gcc.gnu.org> | 2017-02-22 17:20:14 +0000 |
commit | 198075e1c94ef8f9ecc31c9d4698b0761aab7d8c (patch) | |
tree | cd03ff69a35e2ae583bc804da4db724ce66b8fe2 | |
parent | 888c705092d00dc3101d00701367f7c9a2c449cd (diff) | |
download | gcc-198075e1c94ef8f9ecc31c9d4698b0761aab7d8c.zip gcc-198075e1c94ef8f9ecc31c9d4698b0761aab7d8c.tar.gz gcc-198075e1c94ef8f9ecc31c9d4698b0761aab7d8c.tar.bz2 |
Support WORD_REGISTER_OPERATIONS requirements in simplify_operand_subreg
gcc/
PR target/78660
* lra-constraints.c (simplify_operand_subreg): Handle
WORD_REGISTER_OPERATIONS targets.
From-SVN: r245655
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 21 |
2 files changed, 22 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7585f37..40a1d1f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-02-22 Matthew Fortune <matthew.fortune@imgtec.com> + + PR target/78660 + * lra-constraints.c (simplify_operand_subreg): Handle + WORD_REGISTER_OPERATIONS targets. + 2017-02-22 Jakub Jelinek <jakub@redhat.com> PR target/70465 diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 35539a9..224a956 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1541,11 +1541,22 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) subregs as we don't substitute such equiv memory (see processing equivalences in function lra_constraints) and because for spilled pseudos we allocate stack memory enough for the biggest - corresponding paradoxical subreg. */ - if (!(MEM_ALIGN (subst) < GET_MODE_ALIGNMENT (mode) - && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (subst))) - || (MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (innermode) - && SLOW_UNALIGNED_ACCESS (innermode, MEM_ALIGN (reg)))) + corresponding paradoxical subreg. + + However, do not blindly simplify a (subreg (mem ...)) for + WORD_REGISTER_OPERATIONS targets as this may lead to loading junk + data into a register when the inner is narrower than outer or + missing important data from memory when the inner is wider than + outer. This rule only applies to modes that are no wider than + a word. */ + if (!(GET_MODE_PRECISION (mode) != GET_MODE_PRECISION (innermode) + && GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && GET_MODE_SIZE (innermode) <= UNITS_PER_WORD + && WORD_REGISTER_OPERATIONS) + && (!(MEM_ALIGN (subst) < GET_MODE_ALIGNMENT (mode) + && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (subst))) + || (MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (innermode) + && SLOW_UNALIGNED_ACCESS (innermode, MEM_ALIGN (reg))))) return true; *curr_id->operand_loc[nop] = operand; |