Commit 14d7d4be by Jeff Law Committed by Jeff Law

re PR rtl-optimization/70263 (ICE at -O1 and above in both 32-bit and 64-bit…

re PR rtl-optimization/70263 (ICE at -O1 and above in both 32-bit and 64-bit modes on x86_64-linux-gnu (segmentation fault))

	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.

	PR rtl-optimization/70263
	* gcc.c-torture/compile/pr70263-1.c: New test.
	* gcc.target/i386/pr70263-2.c: New test.

From-SVN: r234344
parent 0249ef0b
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> 2016-03-16 David Wohlferd <dw@LimeGreenSocks.com>
Bernd Schmidt <bschmidt@redhat.com> Bernd Schmidt <bschmidt@redhat.com>
......
...@@ -3225,13 +3225,18 @@ memref_referenced_p (rtx memref, rtx x) ...@@ -3225,13 +3225,18 @@ memref_referenced_p (rtx memref, rtx x)
} }
/* TRUE if some insn in the range (START, END] references a memory location /* 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 static int
memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end) memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end)
{ {
rtx_insn *insn; 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)) insn = NEXT_INSN (insn))
{ {
if (!NONDEBUG_INSN_P (insn)) if (!NONDEBUG_INSN_P (insn))
...@@ -3245,6 +3250,7 @@ memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end) ...@@ -3245,6 +3250,7 @@ memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end)
return 1; return 1;
} }
gcc_assert (insn == NEXT_INSN (end));
return 0; return 0;
} }
...@@ -3337,6 +3343,7 @@ update_equiv_regs (void) ...@@ -3337,6 +3343,7 @@ update_equiv_regs (void)
int loop_depth; int loop_depth;
bitmap cleared_regs; bitmap cleared_regs;
bool *pdx_subregs; bool *pdx_subregs;
bitmap_head seen_insns;
/* Use pdx_subregs to show whether a reg is used in a paradoxical /* Use pdx_subregs to show whether a reg is used in a paradoxical
subreg. */ subreg. */
...@@ -3606,11 +3613,14 @@ update_equiv_regs (void) ...@@ -3606,11 +3613,14 @@ update_equiv_regs (void)
/* A second pass, to gather additional equivalences with memory. This needs /* A second pass, to gather additional equivalences with memory. This needs
to be done after we know which registers we are going to replace. */ 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)) for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{ {
rtx set, src, dest; rtx set, src, dest;
unsigned regno; unsigned regno;
bitmap_set_bit (&seen_insns, INSN_UID (insn));
if (! INSN_P (insn)) if (! INSN_P (insn))
continue; continue;
...@@ -3651,6 +3661,7 @@ update_equiv_regs (void) ...@@ -3651,6 +3661,7 @@ update_equiv_regs (void)
rtx_insn *init_insn = rtx_insn *init_insn =
as_a <rtx_insn *> (XEXP (reg_equiv[regno].init_insns, 0)); as_a <rtx_insn *> (XEXP (reg_equiv[regno].init_insns, 0));
if (validate_equiv_mem (init_insn, src, dest) 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) && ! memref_used_between_p (dest, init_insn, insn)
/* Attaching a REG_EQUIV note will fail if INIT_INSN has /* Attaching a REG_EQUIV note will fail if INIT_INSN has
multiple sets. */ multiple sets. */
...@@ -3661,9 +3672,15 @@ update_equiv_regs (void) ...@@ -3661,9 +3672,15 @@ update_equiv_regs (void)
ira_reg_equiv[regno].init_insns ira_reg_equiv[regno].init_insns
= gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX); = gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
df_notes_rescan (init_insn); 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); cleared_regs = BITMAP_ALLOC (NULL);
/* Now scan all regs killed in an insn to see if any of them are /* Now scan all regs killed in an insn to see if any of them are
......
2016-03-18 Jeff Law <law@redhat.com>
PR rtl-optimization/70263
* gcc.c-torture/compile/pr70263-1.c: New test.
* gcc.target/i386/pr70263-2.c: New test.
2016-03-18 Bernd Schmidt <bschmidt@redhat.com> 2016-03-18 Bernd Schmidt <bschmidt@redhat.com>
PR rtl-optimization/70278 PR rtl-optimization/70278
......
int a[91];
int b, c;
void fn1() {
int n, m;
do {
a[c--];
a[--c] = m;
a[--m] = b;
} while (n);
}
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment