re PR tree-optimization/59747 (wrong code at -Os and above on x86_64-linux-gnu in 64-bit mode)
PR tree-optimization/59747 * ree.c (find_and_remove_re): Properly handle case where a second eliminated extension requires widening a copy created for elimination of a prior extension. (combine_set_extension): Ensure that the number of hard regs needed for a destination register does not change when we widen it. PR tree-optimization/59747 * gcc.c-torture/execute/pr59747.c: New test. From-SVN: r206638
This commit is contained in:
parent
aefe4056bb
commit
a6a2d67b0a
|
@ -1,3 +1,12 @@
|
|||
2014-01-15 Jeff Law <law@redhat.com>
|
||||
|
||||
PR tree-optimization/59747
|
||||
* ree.c (find_and_remove_re): Properly handle case where a second
|
||||
eliminated extension requires widening a copy created for elimination
|
||||
of a prior extension.
|
||||
(combine_set_extension): Ensure that the number of hard regs needed
|
||||
for a destination register does not change when we widen it.
|
||||
|
||||
2014-01-15 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* config.gcc (*-*-rtems*): Add t-rtems to tmake_file.
|
||||
|
|
21
gcc/ree.c
21
gcc/ree.c
|
@ -297,6 +297,12 @@ combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set)
|
|||
else
|
||||
new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (*orig_set)));
|
||||
|
||||
/* We're going to be widening the result of DEF_INSN, ensure that doing so
|
||||
doesn't change the number of hard registers needed for the result. */
|
||||
if (HARD_REGNO_NREGS (REGNO (new_reg), cand->mode)
|
||||
!= HARD_REGNO_NREGS (REGNO (orig_src), GET_MODE (SET_DEST (*orig_set))))
|
||||
return false;
|
||||
|
||||
/* Merge constants by directly moving the constant into the register under
|
||||
some conditions. Recall that RTL constants are sign-extended. */
|
||||
if (GET_CODE (orig_src) == CONST_INT
|
||||
|
@ -1017,11 +1023,20 @@ find_and_remove_re (void)
|
|||
for (unsigned int i = 0; i < reinsn_copy_list.length (); i += 2)
|
||||
{
|
||||
rtx curr_insn = reinsn_copy_list[i];
|
||||
rtx def_insn = reinsn_copy_list[i + 1];
|
||||
|
||||
/* Use the mode of the destination of the defining insn
|
||||
for the mode of the copy. This is necessary if the
|
||||
defining insn was used to eliminate a second extension
|
||||
that was wider than the first. */
|
||||
rtx sub_rtx = *get_sub_rtx (def_insn);
|
||||
rtx pat = PATTERN (curr_insn);
|
||||
rtx new_reg = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
|
||||
rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
|
||||
REGNO (XEXP (SET_SRC (pat), 0)));
|
||||
rtx set = gen_rtx_SET (VOIDmode, new_reg, SET_DEST (pat));
|
||||
emit_insn_after (set, reinsn_copy_list[i + 1]);
|
||||
rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
|
||||
REGNO (SET_DEST (pat)));
|
||||
rtx set = gen_rtx_SET (VOIDmode, new_dst, new_src);
|
||||
emit_insn_after (set, def_insn);
|
||||
}
|
||||
|
||||
/* Delete all useless extensions here in one sweep. */
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2014-01-15 Jeff Law <law@redhat.com>
|
||||
|
||||
PR tree-optimization/59747
|
||||
* gcc.c-torture/execute/pr59747.c: New test.
|
||||
|
||||
2014-01-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/59794
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
int a[6], b, c = 1, d;
|
||||
short e;
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
fn1 (int p)
|
||||
{
|
||||
b = a[p];
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof (long long) != 8)
|
||||
exit (0);
|
||||
|
||||
a[0] = 1;
|
||||
if (c)
|
||||
e--;
|
||||
d = e;
|
||||
long long f = e;
|
||||
if (fn1 ((f >> 56) & 1) != 0)
|
||||
abort ();
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue