diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2019-01-30 21:49:23 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2019-01-30 21:49:23 +0000 |
commit | 8eaff6ef97836100801f7b40dc03f77fbebe03ac (patch) | |
tree | 17734a6f63e27573dc11cae1de7a0027c74efc52 /gcc/lra-constraints.c | |
parent | 03bb10aad41b3ef70b72cdb667157ee599f5bc64 (diff) | |
download | gcc-8eaff6ef97836100801f7b40dc03f77fbebe03ac.zip gcc-8eaff6ef97836100801f7b40dc03f77fbebe03ac.tar.gz gcc-8eaff6ef97836100801f7b40dc03f77fbebe03ac.tar.bz2 |
re PR rtl-optimization/87246 (ICE in decompose_normal_address, at rtlanal.c:6379)
2019-01-30 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/87246
* lra-constraints.c (simplify_operand_subreg): Reload memory
in subreg if the address became invalid.
2019-01-30 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/87246
* gcc.target/i386/pr87246.c: New.
From-SVN: r268404
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 0ef1343..d581513 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1497,10 +1497,11 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) alter_subreg (curr_id->operand_loc[nop], false); rtx subst = *curr_id->operand_loc[nop]; lra_assert (MEM_P (subst)); - + const bool addr_is_valid = valid_address_p (GET_MODE (subst), + XEXP (subst, 0), + MEM_ADDR_SPACE (subst)); if (!addr_was_valid - || valid_address_p (GET_MODE (subst), XEXP (subst, 0), - MEM_ADDR_SPACE (subst)) + || addr_is_valid || ((get_constraint_type (lookup_constraint (curr_static_id->operand[nop].constraint)) != CT_SPECIAL_MEMORY) @@ -1529,12 +1530,17 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) 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 (!(maybe_ne (GET_MODE_PRECISION (mode), - GET_MODE_PRECISION (innermode)) - && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD) - && known_le (GET_MODE_SIZE (innermode), UNITS_PER_WORD) - && WORD_REGISTER_OPERATIONS) + a word. + + If valid memory becomes invalid after subreg elimination + we still have to reload memory. + */ + if ((! addr_was_valid || addr_is_valid) + && !(maybe_ne (GET_MODE_PRECISION (mode), + GET_MODE_PRECISION (innermode)) + && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD) + && known_le (GET_MODE_SIZE (innermode), UNITS_PER_WORD) + && WORD_REGISTER_OPERATIONS) && (!(MEM_ALIGN (subst) < GET_MODE_ALIGNMENT (mode) && targetm.slow_unaligned_access (mode, MEM_ALIGN (subst))) || (MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (innermode) @@ -1553,7 +1559,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) enum reg_class rclass = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS); if (get_reload_reg (curr_static_id->operand[nop].type, innermode, - reg, rclass, TRUE, "slow mem", &new_reg)) + reg, rclass, TRUE, "slow/invalid mem", &new_reg)) { bool insert_before, insert_after; bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); @@ -1572,7 +1578,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) rclass = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS); if (get_reload_reg (curr_static_id->operand[nop].type, mode, reg, - rclass, TRUE, "slow mem", &new_reg)) + rclass, TRUE, "slow/invalid mem", &new_reg)) { bool insert_before, insert_after; bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); @@ -1585,7 +1591,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) } *curr_id->operand_loc[nop] = new_reg; lra_process_new_insns (curr_insn, before, after, - "Inserting slow mem reload"); + "Inserting slow/invalid mem reload"); return true; } |