aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index edddff7aeca..01ae6ad8787 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1372,6 +1372,7 @@ static rtx rs6000_debug_legitimize_reload_address (rtx, machine_mode, int,
int, int, int *);
static bool rs6000_mode_dependent_address (const_rtx);
static bool rs6000_debug_mode_dependent_address (const_rtx);
+static bool rs6000_offsettable_memref_p (rtx, machine_mode, bool);
static enum reg_class rs6000_secondary_reload_class (enum reg_class,
machine_mode, rtx);
static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
@@ -8564,10 +8565,15 @@ mem_operand_gpr (rtx op, machine_mode mode)
int extra;
rtx addr = XEXP (op, 0);
- /* Don't allow altivec type addresses like (mem (and (plus ...))).
- See PR target/84279. */
+ /* PR85755: Allow PRE_INC and PRE_DEC addresses. */
+ if (TARGET_UPDATE
+ && (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
+ && mode_supports_pre_incdec_p (mode)
+ && legitimate_indirect_address_p (XEXP (addr, 0), false))
+ return true;
- if (GET_CODE (addr) == AND)
+ /* Don't allow non-offsettable addresses. See PRs 83969 and 84279. */
+ if (!rs6000_offsettable_memref_p (op, mode, false))
return false;
op = address_offset (addr);
@@ -10340,7 +10346,7 @@ rs6000_find_base_term (rtx op)
in 32-bit mode, that the recog predicate rejects. */
static bool
-rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode)
+rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode, bool strict)
{
bool worst_case;
@@ -10348,7 +10354,7 @@ rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode)
return false;
/* First mimic offsettable_memref_p. */
- if (offsettable_address_p (true, GET_MODE (op), XEXP (op, 0)))
+ if (offsettable_address_p (strict, GET_MODE (op), XEXP (op, 0)))
return true;
/* offsettable_address_p invokes rs6000_mode_dependent_address, but
@@ -10362,7 +10368,7 @@ rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode)
worst_case = ((TARGET_POWERPC64 && GET_MODE_CLASS (reg_mode) == MODE_INT)
|| GET_MODE_SIZE (reg_mode) == 4);
return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0),
- true, worst_case);
+ strict, worst_case);
}
/* Determine the reassociation width to be used in reassociate_bb.
@@ -23281,7 +23287,7 @@ rs6000_output_move_128bit (rtx operands[])
}
else if (TARGET_ALTIVEC && src_vmx_p
- && altivec_indexed_or_indirect_operand (src, mode))
+ && altivec_indexed_or_indirect_operand (dest, mode))
return "stvx %1,%y0";
else if (TARGET_VSX && src_vsx_p)
@@ -26559,7 +26565,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
emit_insn (gen_add3_insn (breg, breg, delta_rtx));
src = replace_equiv_address (src, breg);
}
- else if (! rs6000_offsettable_memref_p (src, reg_mode))
+ else if (! rs6000_offsettable_memref_p (src, reg_mode, true))
{
if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
{
@@ -26626,7 +26632,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
emit_insn (gen_add3_insn (breg, breg, delta_rtx));
dst = replace_equiv_address (dst, breg);
}
- else if (!rs6000_offsettable_memref_p (dst, reg_mode)
+ else if (!rs6000_offsettable_memref_p (dst, reg_mode, true)
&& GET_CODE (XEXP (dst, 0)) != LO_SUM)
{
if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
@@ -26665,7 +26671,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
}
}
else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
- gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode));
+ gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode, true));
}
for (i = 0; i < nregs; i++)