+2016-03-18 Jeff Law <law@redhat.com>
+
+ PR rtl-optimization/70263
+ * ira.c (memref_used_between_p): Assert we found END in the insn chain.
+ (update_equiv_regs): When trying to move a store to after the insn
+ that sets the source of the store, make sure the store occurs after
+ the insn that sets the source of the store. When successful note
+ the REG_EQUIV note created in the dump file.
+
2016-03-16 David Wohlferd <dw@LimeGreenSocks.com>
Bernd Schmidt <bschmidt@redhat.com>
}
/* TRUE if some insn in the range (START, END] references a memory location
- that would be affected by a store to MEMREF. */
+ that would be affected by a store to MEMREF.
+
+ Callers should not call this routine if START is after END in the
+ RTL chain. */
+
static int
memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end)
{
rtx_insn *insn;
- for (insn = NEXT_INSN (start); insn != NEXT_INSN (end);
+ for (insn = NEXT_INSN (start);
+ insn && insn != NEXT_INSN (end);
insn = NEXT_INSN (insn))
{
if (!NONDEBUG_INSN_P (insn))
return 1;
}
+ gcc_assert (insn == NEXT_INSN (end));
return 0;
}
int loop_depth;
bitmap cleared_regs;
bool *pdx_subregs;
+ bitmap_head seen_insns;
/* Use pdx_subregs to show whether a reg is used in a paradoxical
subreg. */
/* A second pass, to gather additional equivalences with memory. This needs
to be done after we know which registers we are going to replace. */
+ bitmap_initialize (&seen_insns, NULL);
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
rtx set, src, dest;
unsigned regno;
+ bitmap_set_bit (&seen_insns, INSN_UID (insn));
+
if (! INSN_P (insn))
continue;
rtx_insn *init_insn =
as_a <rtx_insn *> (XEXP (reg_equiv[regno].init_insns, 0));
if (validate_equiv_mem (init_insn, src, dest)
+ && bitmap_bit_p (&seen_insns, INSN_UID (init_insn))
&& ! memref_used_between_p (dest, init_insn, insn)
/* Attaching a REG_EQUIV note will fail if INIT_INSN has
multiple sets. */
ira_reg_equiv[regno].init_insns
= gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
df_notes_rescan (init_insn);
+ if (dump_file)
+ fprintf (dump_file,
+ "Adding REG_EQUIV to insn %d for source of insn %d\n",
+ INSN_UID (init_insn),
+ INSN_UID (insn));
}
}
}
+ bitmap_clear (&seen_insns);
cleared_regs = BITMAP_ALLOC (NULL);
/* Now scan all regs killed in an insn to see if any of them are
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-ira" } */
+
+/* { dg-final { scan-rtl-dump "Adding REG_EQUIV to insn \[0-9\]+ for source of insn \[0-9\]+" "ira" } } */
+
+typedef float XFtype __attribute__ ((mode (XF)));
+typedef _Complex float XCtype __attribute__ ((mode (XC)));
+XCtype
+__mulxc3 (XFtype a, XFtype b, XFtype c, XFtype d)
+{
+ XFtype ac, bd, ad, bc, x, y;
+ ac = a * c;
+__asm__ ("": "=m" (ac):"m" (ac));
+ if (x != x)
+ {
+ _Bool recalc = 0;
+ if (((!(!(((ac) - (ac)) != ((ac) - (ac)))))))
+ recalc = 1;
+ if (recalc)
+ x = __builtin_huge_vall () * (a * c - b * d);
+ }
+ return x;
+}