This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 3/5] Support WORD_REGISTER_OPERATIONS requirements in simplify_operand_subreg
- From: Matthew Fortune <Matthew dot Fortune at imgtec dot com>
- To: "'gcc-patches at gcc dot gnu dot org' (gcc-patches at gcc dot gnu dot org)" <gcc-patches at gcc dot gnu dot org>
- Cc: Vladimir Makarov <vmakarov at redhat dot com>, "Eric Botcazou (ebotcazou at adacore dot com)" <ebotcazou at adacore dot com>, Robert Suchanek <Robert dot Suchanek at imgtec dot com>, "Moore, Catherine (Catherine_Moore at mentor dot com)" <Catherine_Moore at mentor dot com>
- Date: Tue, 7 Feb 2017 14:08:37 +0000
- Subject: [PATCH 3/5] Support WORD_REGISTER_OPERATIONS requirements in simplify_operand_subreg
- Authentication-results: sourceware.org; auth=none
Hi,
This patch is a minimal change to prevent (subreg(mem)) from being
simplified to use the outer mode for WORD_REGISTER_OPERATIONS. There
is high probability of refining and/or re-implementing this for GCC 8
but such a change would be too invasive. This change at least ensures
correctness but may prevent simplification of some acceptable cases.
No testcase here but I will try to make one using the RTL frontend
later. This fix is required for mips64el-linux-gnu bootstrap
to succeed (in conjunction with patch 1 of this series). The specific
file affected by this bug is building gcc/predict.c where a bad reload
is created in predict_paths_for_bb. Register 300 in the following
example is spilled to memory in SImode but reloaded as DImode.
(insn 247 212 389 3 (set (reg:SI 300)
(ne:SI (subreg/s/u:SI (reg/v:DI 231 [ taken ]) 0)
(const_int 0 [0]))) "/home/mfortune/gcc/gcc/predict.c":2904 504 {*sne_zero_sisi}
(nil))
...
(insn 250 256 251 40 (set (reg:DI 6 $6)
(subreg:DI (reg:SI 300) 0)) "/home/mfortune/gcc/gcc/predict.c":2904 310 {*movdi_64bit}
(nil))
Thanks,
Matthew
gcc/
PR target/78660
* lra-constraints.c (simplify_operand_subreg): Handle
WORD_REGISTER_OPERATIONS targets.
---
gcc/lra-constraints.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 66ff2bb..484a70d 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1541,11 +1541,18 @@ 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, never 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. */
+ if (!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;
--
2.2.1