aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index a68f2efa661..d8b41363d36 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1360,8 +1360,18 @@ push_reload (in, out, inloc, outloc, class,
are identical in content, there might be duplicate address
reloads. Remove the extra set now, so that if we later find
that we can inherit this reload, we can get rid of the
- address reloads altogether. */
- if (reload_in[i] != in && rtx_equal_p (in, reload_in[i]))
+ address reloads altogether.
+
+ Do not do this if both reloads are optional since the result
+ would be an optional reload which could potentially leave
+ unresolved address replacements.
+
+ It is not sufficient to call transfer_replacements since
+ choose_reload_regs will remove the replacements for address
+ reloads of inherited reloads which results in the same
+ problem. */
+ if (reload_in[i] != in && rtx_equal_p (in, reload_in[i])
+ && ! (reload_optional[i] && optional))
{
/* We must keep the address reload with the lower operand
number alive. */
@@ -3793,11 +3803,16 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
(insn_code_number < 0 ? 0
: insn_operand_strict_low[insn_code_number][i]),
1, i, operand_type[i]);
- /* If a memory reference remains, yet we can't make an optional
+ /* If a memory reference remains (either as a MEM or a pseudo that
+ did not get a hard register), yet we can't make an optional
reload, check if this is actually a pseudo register reference;
we then need to emit a USE and/or a CLOBBER so that reload
inheritance will do the right thing. */
- else if (replace && GET_CODE (operand) == MEM)
+ else if (replace
+ && (GET_CODE (operand) == MEM
+ || (GET_CODE (operand) == REG
+ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber [REGNO (operand)] < 0)))
{
operand = *recog_operand_loc[i];