diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2014-03-28 22:14:36 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2014-03-28 22:14:36 +0000 |
commit | 6e071b1e8f9902b8c65db6ca3349964a39d1651b (patch) | |
tree | fdee9bbb1c36405dbb87776539318c3b64c8c6df /gcc/lra-constraints.c | |
parent | 4bb66ef337cc5b0928b7e71ee38ffb82438a9087 (diff) | |
download | gcc-6e071b1e8f9902b8c65db6ca3349964a39d1651b.zip gcc-6e071b1e8f9902b8c65db6ca3349964a39d1651b.tar.gz gcc-6e071b1e8f9902b8c65db6ca3349964a39d1651b.tar.bz2 |
re PR target/60697 ([aarch64] LRA ICE (Segfault) while building 435.gromacs)
2014-03-28 Vladimir Makarov <vmakarov@redhat.com>
PR target/60697
* lra-constraints.c (index_part_to_reg): New.
(process_address): Use it.
2014-03-28 Vladimir Makarov <vmakarov@redhat.com>
PR target/60697
* gcc.target/aarch64/pr60697.c: New.
From-SVN: r208926
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index ba4d489..cfc3d7e 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2631,6 +2631,20 @@ base_plus_disp_to_reg (struct address_info *ad) return new_reg; } +/* Make reload of index part of address AD. Return the new + pseudo. */ +static rtx +index_part_to_reg (struct address_info *ad) +{ + rtx new_reg; + + new_reg = lra_create_new_reg (GET_MODE (*ad->index), NULL_RTX, + INDEX_REG_CLASS, "index term"); + expand_mult (GET_MODE (*ad->index), *ad->index_term, + GEN_INT (get_index_scale (ad)), new_reg, 1); + return new_reg; +} + /* Return true if we can add a displacement to address AD, even if that makes the address invalid. The fix-up code requires any new address to be the sum of the BASE_TERM, INDEX and DISP_TERM fields. */ @@ -2935,7 +2949,7 @@ process_address (int nop, rtx *before, rtx *after) emit_insn (insns); *ad.inner = new_reg; } - else + else if (ad.disp_term != NULL) { /* base + scale * index + disp => new base + scale * index, case (1) above. */ @@ -2943,6 +2957,18 @@ process_address (int nop, rtx *before, rtx *after) *ad.inner = simplify_gen_binary (PLUS, GET_MODE (new_reg), new_reg, *ad.index); } + else + { + /* base + scale * index => base + new_reg, + case (1) above. + Index part of address may become invalid. For example, we + changed pseudo on the equivalent memory and a subreg of the + pseudo onto the memory of different mode for which the scale is + prohibitted. */ + new_reg = index_part_to_reg (&ad); + *ad.inner = simplify_gen_binary (PLUS, GET_MODE (new_reg), + *ad.base_term, new_reg); + } *before = get_insns (); end_sequence (); return true; |