+2009-04-24 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * loop-iv.c (replace_single_def_regs): Look for REG_EQUAL notes;
+ follow chains of regs with a single definition, and allow expressions
+ that are function_invariant_p.
+
2009-04-24 Paolo Bonzini <bonzini@gnu.org>
PR middle-end/39867
{
unsigned regno;
df_ref adef;
- rtx set;
+ rtx set, src;
rtx *expr = (rtx *)expr1;
if (!REG_P (*reg))
return 0;
regno = REGNO (*reg);
- adef = DF_REG_DEF_CHAIN (regno);
- if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
- || DF_REF_IS_ARTIFICIAL (adef))
- return -1;
+ for (;;)
+ {
+ rtx note;
+ adef = DF_REG_DEF_CHAIN (regno);
+ if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
+ || DF_REF_IS_ARTIFICIAL (adef))
+ return -1;
+
+ set = single_set (DF_REF_INSN (adef));
+ if (set == NULL || !REG_P (SET_DEST (set))
+ || REGNO (SET_DEST (set)) != regno)
+ return -1;
- set = single_set (DF_REF_INSN (adef));
- if (set == NULL || SET_DEST (set) != *reg || !CONSTANT_P (SET_SRC (set)))
+ note = find_reg_equal_equiv_note (DF_REF_INSN (adef));
+
+ if (note && function_invariant_p (XEXP (note, 0)))
+ {
+ src = XEXP (note, 0);
+ break;
+ }
+ src = SET_SRC (set);
+
+ if (REG_P (src))
+ {
+ regno = REGNO (src);
+ continue;
+ }
+ break;
+ }
+ if (!function_invariant_p (src))
return -1;
- *expr = simplify_replace_rtx (*expr, *reg, SET_SRC (set));
+ *expr = simplify_replace_rtx (*expr, *reg, src);
return 1;
}