+2003-12-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * reload.c (reg_overlap_mentioned_for_reload_p):
+ When looking at a PLUS in X, avoid spuriously returning nonzero
+ when IN is a REG or another simple PLUS, or a MEM containing one.
+
+ * loop.c (loop_invariant_p): Amend comment about where new registers
+ might come from.
+
2003-12-15 Andreas Jaeger <aj@suse.de>
* config/rs6000/rs6000.c (rs6000_output_function_epilogue): Remove
return 0;
/* Out-of-range regs can occur when we are called from unrolling.
- These have always been created by the unroller and are set in
- the loop, hence are never invariant. */
+ These registers created by the unroller are set in the loop,
+ hence are never invariant.
+ Other out-of-range regs can be generated by load_mems; those that
+ are written to in the loop are not invariant, while those that are
+ not written to are invariant. It would be easy for load_mems
+ to set n_times_set correctly for these registers, however, there
+ is no easy way to distinguish them from registers created by the
+ unroller. */
if (REGNO (x) >= (unsigned) regs->num)
return 0;
|| GET_CODE (x) == CC0)
return reg_mentioned_p (x, in);
else if (GET_CODE (x) == PLUS)
- return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
- || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
+ {
+ /* We actually want to know if X is mentioned somewhere inside IN.
+ We must not say that (plus (sp) (const_int 124)) is in
+ (plus (sp) (const_int 64)), since that can lead to incorrect reload
+ allocation when spuriously changing a RELOAD_FOR_OUTPUT_ADDRESS
+ into a RELOAD_OTHER on behalf of another RELOAD_OTHER. */
+ while (GET_CODE (in) == MEM)
+ in = XEXP (in, 0);
+ if (GET_CODE (in) == REG)
+ return 0;
+ else if (GET_CODE (in) == PLUS)
+ return (reg_overlap_mentioned_for_reload_p (x, XEXP (in, 0))
+ || reg_overlap_mentioned_for_reload_p (x, XEXP (in, 1)));
+ else return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
+ || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
+ }
else
abort ();