diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc index eb579ad3ad7..f7aa6a66cdf 100644 --- a/gcc/rtl-ssa/changes.cc +++ b/gcc/rtl-ssa/changes.cc @@ -1106,6 +1106,24 @@ recog_level2 (insn_change &change, add_regno_clobber_fn add_regno_clobber) } } + // Per rtl.texi, registers that are modified using RTX_AUTOINC operations + // cannot also appear outside an address. + vec_rtx_properties properties; + properties.add_pattern (pat); + for (rtx_obj_reference def : properties.refs ()) + if (def.is_pre_post_modify ()) + for (rtx_obj_reference use : properties.refs ()) + if (def.regno == use.regno && !use.in_address ()) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "register %d is both auto-modified" + " and used outside an address:\n", def.regno); + print_rtl_single (dump_file, pat); + } + return false; + } + // check_asm_operands checks the constraints after RA, so we don't // need to do it again. if (reload_completed && !asm_p) diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 86a5e473308..900f53e252a 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -2235,7 +2235,7 @@ rtx_properties::try_to_add_src (const_rtx x, unsigned int flags) { has_pre_post_modify = true; - unsigned int addr_flags = (base_flags + unsigned int addr_flags = (flags | rtx_obj_flags::IS_PRE_POST_MODIFY | rtx_obj_flags::IS_READ); try_to_add_dest (XEXP (x, 0), addr_flags); diff --git a/gcc/testsuite/gcc.dg/torture/pr120347.c b/gcc/testsuite/gcc.dg/torture/pr120347.c new file mode 100644 index 00000000000..a2d187bbc5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120347.c @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-additional-options "-march=armv7-a -mthumb" { target { arm_arch_v7a_ok && arm_thumb2_ok } } } */ + +void *end; +void **start; +void main(void) +{ + for (; end; start++) { + if (*start) + return; + *start = start; + } +}