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:
Jakub Jelinek 2016-01-26 12:12:03 +01:00 committed by Jakub Jelinek
parent b96824c484
commit 6c06e0e822
5 changed files with 51 additions and 7 deletions

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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;
}