re PR target/69442 (wrong code with -Og and 64bit modulo @ armv7a)
PR target/69442 * combine.c (combine_instructions): For REG_EQUAL note with SET_DEST being ZERO_EXTRACT, also temporarily set SET_DEST to the underlying register. * doc/rtl.texi (REG_EQUAL): Document the behavior of REG_EQUAL/REG_EQUIV notes if SET_DEST is ZERO_EXTRACT. * gcc.dg/pr69442.c: New test. From-SVN: r232819
This commit is contained in:
parent
b96824c484
commit
6c06e0e822
|
@ -1,3 +1,12 @@
|
||||||
|
2016-01-26 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR target/69442
|
||||||
|
* combine.c (combine_instructions): For REG_EQUAL note with
|
||||||
|
SET_DEST being ZERO_EXTRACT, also temporarily set SET_DEST
|
||||||
|
to the underlying register.
|
||||||
|
* doc/rtl.texi (REG_EQUAL): Document the behavior of
|
||||||
|
REG_EQUAL/REG_EQUIV notes if SET_DEST is ZERO_EXTRACT.
|
||||||
|
|
||||||
2016-01-26 Roger Ferrer Ibáñez <rofirrim@gmail.com>
|
2016-01-26 Roger Ferrer Ibáñez <rofirrim@gmail.com>
|
||||||
|
|
||||||
PR target/67896
|
PR target/67896
|
||||||
|
|
|
@ -1454,15 +1454,21 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
|
||||||
&& ! unmentioned_reg_p (note, SET_SRC (set))
|
&& ! unmentioned_reg_p (note, SET_SRC (set))
|
||||||
&& (GET_MODE (note) == VOIDmode
|
&& (GET_MODE (note) == VOIDmode
|
||||||
? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
|
? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
|
||||||
: GET_MODE (SET_DEST (set)) == GET_MODE (note)))
|
: (GET_MODE (SET_DEST (set)) == GET_MODE (note)
|
||||||
|
&& (GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
|
||||||
|
|| (GET_MODE (XEXP (SET_DEST (set), 0))
|
||||||
|
== GET_MODE (note))))))
|
||||||
{
|
{
|
||||||
/* Temporarily replace the set's source with the
|
/* Temporarily replace the set's source with the
|
||||||
contents of the REG_EQUAL note. The insn will
|
contents of the REG_EQUAL note. The insn will
|
||||||
be deleted or recognized by try_combine. */
|
be deleted or recognized by try_combine. */
|
||||||
rtx orig = SET_SRC (set);
|
rtx orig_src = SET_SRC (set);
|
||||||
|
rtx orig_dest = SET_DEST (set);
|
||||||
|
if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT)
|
||||||
|
SET_DEST (set) = XEXP (SET_DEST (set), 0);
|
||||||
SET_SRC (set) = note;
|
SET_SRC (set) = note;
|
||||||
i2mod = temp;
|
i2mod = temp;
|
||||||
i2mod_old_rhs = copy_rtx (orig);
|
i2mod_old_rhs = copy_rtx (orig_src);
|
||||||
i2mod_new_rhs = copy_rtx (note);
|
i2mod_new_rhs = copy_rtx (note);
|
||||||
next = try_combine (insn, i2mod, NULL, NULL,
|
next = try_combine (insn, i2mod, NULL, NULL,
|
||||||
&new_direct_jump_p,
|
&new_direct_jump_p,
|
||||||
|
@ -1473,7 +1479,8 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
|
||||||
statistics_counter_event (cfun, "insn-with-note combine", 1);
|
statistics_counter_event (cfun, "insn-with-note combine", 1);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
SET_SRC (set) = orig;
|
SET_SRC (set) = orig_src;
|
||||||
|
SET_DEST (set) = orig_dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3915,9 +3915,9 @@ indicates that that register will be equal to @var{op} at run time; the
|
||||||
scope of this equivalence differs between the two types of notes. The
|
scope of this equivalence differs between the two types of notes. The
|
||||||
value which the insn explicitly copies into the register may look
|
value which the insn explicitly copies into the register may look
|
||||||
different from @var{op}, but they will be equal at run time. If the
|
different from @var{op}, but they will be equal at run time. If the
|
||||||
output of the single @code{set} is a @code{strict_low_part} expression,
|
output of the single @code{set} is a @code{strict_low_part} or
|
||||||
the note refers to the register that is contained in @code{SUBREG_REG}
|
@code{zero_extract} expression, the note refers to the register that
|
||||||
of the @code{subreg} expression.
|
is contained in its first operand.
|
||||||
|
|
||||||
For @code{REG_EQUIV}, the register is equivalent to @var{op} throughout
|
For @code{REG_EQUIV}, the register is equivalent to @var{op} throughout
|
||||||
the entire function, and could validly be replaced in all its
|
the entire function, and could validly be replaced in all its
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2016-01-26 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR target/69442
|
||||||
|
* gcc.dg/pr69442.c: New test.
|
||||||
|
|
||||||
2016-01-26 Roger Ferrer Ibáñez <rofirrim@gmail.com>
|
2016-01-26 Roger Ferrer Ibáñez <rofirrim@gmail.com>
|
||||||
|
|
||||||
PR target/67896
|
PR target/67896
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* PR target/69442 */
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-Og" } */
|
||||||
|
|
||||||
|
unsigned long long __attribute__ ((noinline, noclone))
|
||||||
|
foo (unsigned int x, unsigned long long y)
|
||||||
|
{
|
||||||
|
x |= 0xffff;
|
||||||
|
y -= 0xffULL;
|
||||||
|
y %= 0xffff0000ffffffe7ULL;
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (sizeof (unsigned long long) * __CHAR_BIT__ != 64)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (foo (0, 0) != 0xffff0000ff19ULL)
|
||||||
|
__builtin_abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue