Commit a72b242e by Alan Modra Committed by Jeff Law

re PR rtl-optimization/79286 (ira and lra wrong code at -O2 and -Os on i686-linux)

2017-02-16  Alan Modra  <amodra@gmail.com>

	PR rtl-optimization/79286
	* ira.c (def_dominates_uses): New function.
	(update_equiv_regs): Don't create an equivalence for insns that
	may trap where the register def does not dominate the use.

	* gcc.c-torture/execute/pr79286.c: New.

From-SVN: r245521
parent 9b9ad360
2017-02-16 Alan Modra <amodra@gmail.com>
PR rtl-optimization/79286
* ira.c (def_dominates_uses): New function.
(update_equiv_regs): Don't create an equivalence for insns that
may trap where the register def does not dominate the use.
2017-02-16 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/78127
......
......@@ -3300,6 +3300,49 @@ adjust_cleared_regs (rtx loc, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data)
return NULL_RTX;
}
/* Given register REGNO is set only once, return true if the defining
insn dominates all uses. */
static bool
def_dominates_uses (int regno)
{
df_ref def = DF_REG_DEF_CHAIN (regno);
struct df_insn_info *def_info = DF_REF_INSN_INFO (def);
/* If this is an artificial def (eh handler regs, hard frame pointer
for non-local goto, regs defined on function entry) then def_info
is NULL and the reg is always live before any use. We might
reasonably return true in that case, but since the only call
of this function is currently here in ira.c when we are looking
at a defining insn we can't have an artificial def as that would
bump DF_REG_DEF_COUNT. */
gcc_assert (DF_REG_DEF_COUNT (regno) == 1 && def_info != NULL);
rtx_insn *def_insn = DF_REF_INSN (def);
basic_block def_bb = BLOCK_FOR_INSN (def_insn);
for (df_ref use = DF_REG_USE_CHAIN (regno);
use;
use = DF_REF_NEXT_REG (use))
{
struct df_insn_info *use_info = DF_REF_INSN_INFO (use);
/* Only check real uses, not artificial ones. */
if (use_info)
{
rtx_insn *use_insn = DF_REF_INSN (use);
if (!DEBUG_INSN_P (use_insn))
{
basic_block use_bb = BLOCK_FOR_INSN (use_insn);
if (use_bb != def_bb
? !dominated_by_p (CDI_DOMINATORS, use_bb, def_bb)
: DF_INSN_INFO_LUID (use_info) < DF_INSN_INFO_LUID (def_info))
return false;
}
}
}
return true;
}
/* Find registers that are equivalent to a single value throughout the
compilation (either because they can be referenced in memory or are
set once from a single constant). Lower their priority for a
......@@ -3498,9 +3541,18 @@ update_equiv_regs (void)
= gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv[regno].init_insns);
/* If this register is known to be equal to a constant, record that
it is always equivalent to the constant. */
it is always equivalent to the constant.
Note that it is possible to have a register use before
the def in loops (see gcc.c-torture/execute/pr79286.c)
where the reg is undefined on first use. If the def insn
won't trap we can use it as an equivalence, effectively
choosing the "undefined" value for the reg to be the
same as the value set by the def. */
if (DF_REG_DEF_COUNT (regno) == 1
&& note && ! rtx_varies_p (XEXP (note, 0), 0))
&& note
&& !rtx_varies_p (XEXP (note, 0), 0)
&& (!may_trap_p (XEXP (note, 0))
|| def_dominates_uses (regno)))
{
rtx note_value = XEXP (note, 0);
remove_note (insn, note);
......
2017-02-16 Alan Modra <amodra@gmail.com>
* gcc.c-torture/execute/pr79286.c: New.
2017-02-16 Jakub Jelinek <jakub@redhat.com>
PR c++/79512
......
int a = 0, c = 0;
static int d[][8] = {};
int main ()
{
int e;
for (int b = 0; b < 4; b++)
{
__builtin_printf ("%d\n", b, e);
while (a && c++)
e = d[300000000000000000][0];
}
return 0;
}
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