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
This commit is contained in:
parent
9b9ad3606d
commit
a72b242eac
|
@ -1,3 +1,10 @@
|
|||
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
|
||||
|
|
56
gcc/ira.c
56
gcc/ira.c
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
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
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
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;
|
||||
}
|
Loading…
Reference in New Issue