diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-02-03 17:58:34 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-02-03 17:58:34 +0000 |
commit | 401bd0c8106b6f815d997fc74634c38f9a4a87f2 (patch) | |
tree | 1f5494807f8318b08e22017de985210f062be336 /gcc/lra-constraints.c | |
parent | 277d9d1d4961b301b63029c7c7cbc61e7868a6e0 (diff) | |
download | gcc-401bd0c8106b6f815d997fc74634c38f9a4a87f2.tar.gz |
2016-02-03 Vladimir Makarov <vmakarov@redhat.com>
Alexandre Oliva <aoliva@redhat.com>
PR target/69461
* lra-constraints.c (simplify_operand_subreg): Check additionally
address validity after potential reloading.
(process_address_1): Check insns validity. In case of failure do
nothing.
2016-02-03 Vladimir Makarov <vmakarov@redhat.com>
Alexandre Oliva <aoliva@redhat.com>
PR target/69461
* gcc.target/powerpc/pr69461.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233107 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 9a7121fb6af..08cf0aa6c42 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1411,6 +1411,21 @@ simplify_operand_subreg (int nop, machine_mode reg_mode) || valid_address_p (GET_MODE (subst), XEXP (subst, 0), MEM_ADDR_SPACE (subst))) return true; + else if ((get_constraint_type (lookup_constraint + (curr_static_id->operand[nop].constraint)) + != CT_SPECIAL_MEMORY) + /* We still can reload address and if the address is + valid, we can remove subreg without reloading its + inner memory. */ + && valid_address_p (GET_MODE (subst), + regno_reg_rtx + [ira_class_hard_regs + [base_reg_class (GET_MODE (subst), + MEM_ADDR_SPACE (subst), + ADDRESS, SCRATCH)][0]], + MEM_ADDR_SPACE (subst))) + return true; + /* If the address was valid and became invalid, prefer to reload the memory. Typical case is when the index scale should correspond the memory. */ @@ -2958,6 +2973,8 @@ process_address_1 (int nop, bool check_only_p, { if (ad.index == NULL) { + rtx_insn *insn; + rtx_insn *last = get_last_insn (); int code = -1; enum reg_class cl = base_reg_class (ad.mode, ad.as, SCRATCH, SCRATCH); @@ -2966,9 +2983,6 @@ process_address_1 (int nop, bool check_only_p, new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, "addr"); if (HAVE_lo_sum) { - rtx_insn *insn; - rtx_insn *last = get_last_insn (); - /* addr => lo_sum (new_base, addr), case (2) above. */ insn = emit_insn (gen_rtx_SET (new_reg, @@ -3004,6 +3018,20 @@ process_address_1 (int nop, bool check_only_p, { /* addr => new_base, case (2) above. */ lra_emit_move (new_reg, addr); + + for (insn = last == NULL_RTX ? get_insns () : NEXT_INSN (last); + insn != NULL_RTX; + insn = NEXT_INSN (insn)) + if (recog_memoized (insn) < 0) + break; + if (insn != NULL_RTX) + { + /* Do nothing if we cannot generate right insns. + This is analogous to reload pass behaviour. */ + delete_insns_since (last); + end_sequence (); + return false; + } *ad.inner = new_reg; } } |