re PR target/69442 (wrong code with -Og and 64bit modulo @ armv7a)
authorJakub Jelinek <jakub@redhat.com>
Tue, 26 Jan 2016 11:12:03 +0000 (12:12 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 26 Jan 2016 11:12:03 +0000 (12:12 +0100)
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

gcc/ChangeLog
gcc/combine.c
gcc/doc/rtl.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr69442.c [new file with mode: 0644]

index 70e5fd61f3bfafadfa8fb0d16a3a601246959003..17f9b2b8217e720b65176947dab04cfffe200617 100644 (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>
 
        PR target/67896
index 2f913dd8ea973acdedfe77d03ab252000c5547a6..858552ddc3f8fbbd0fb68b7bc4533a20b6c791d4 100644 (file)
@@ -1454,15 +1454,21 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
                  && ! unmentioned_reg_p (note, SET_SRC (set))
                  && (GET_MODE (note) == VOIDmode
                      ? 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
                     contents of the REG_EQUAL note.  The insn will
                     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;
                  i2mod = temp;
-                 i2mod_old_rhs = copy_rtx (orig);
+                 i2mod_old_rhs = copy_rtx (orig_src);
                  i2mod_new_rhs = copy_rtx (note);
                  next = try_combine (insn, i2mod, NULL, NULL,
                                      &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);
                      goto retry;
                    }
-                 SET_SRC (set) = orig;
+                 SET_SRC (set) = orig_src;
+                 SET_DEST (set) = orig_dest;
                }
            }
 
index e44ef53d8511f65406bebcf4aa1707859228f66e..1b3f47e35736cda0092bcbe8248558651b80d96b 100644 (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
 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
-output of the single @code{set} is a @code{strict_low_part} expression,
-the note refers to the register that is contained in @code{SUBREG_REG}
-of the @code{subreg} expression.
+output of the single @code{set} is a @code{strict_low_part} or
+@code{zero_extract} expression, the note refers to the register that
+is contained in its first operand.
 
 For @code{REG_EQUIV}, the register is equivalent to @var{op} throughout
 the entire function, and could validly be replaced in all its
index ae150baa578ddcea948254b7962af8551a903334..67bc4e4cf5764a8a0b327c2391eab0c8b220d17d 100644 (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>
 
        PR target/67896
diff --git a/gcc/testsuite/gcc.dg/pr69442.c b/gcc/testsuite/gcc.dg/pr69442.c
new file mode 100644 (file)
index 0000000..ee75f92
--- /dev/null
@@ -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;
+}