re PR rtl-optimization/64756 (wrong code at -O3 on x86_64-linux-gnu (in 32-bit mode))
authorJakub Jelinek <jakub@redhat.com>
Tue, 3 Feb 2015 20:41:38 +0000 (21:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 3 Feb 2015 20:41:38 +0000 (21:41 +0100)
PR rtl-optimization/64756
* cse.c (invalidate_dest): New function.
(cse_insn): Use it.  If dest != SET_DEST (sets[i].rtl) and
HASH (SET_DEST (sets[i].rtl), mode) computation sets do_not_record,
invalidate and do not record it.

* gcc.c-torture/execute/pr64756.c: New test.

From-SVN: r220377

gcc/ChangeLog
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr64756.c [new file with mode: 0644]

index 98c968ecc20cab51b210a1ee725afa87d5aa26e2..fdea07e8a775eddb4f2a3558669294864eab03df 100644 (file)
@@ -1,3 +1,11 @@
+2015-02-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/64756
+       * cse.c (invalidate_dest): New function.
+       (cse_insn): Use it.  If dest != SET_DEST (sets[i].rtl) and
+       HASH (SET_DEST (sets[i].rtl), mode) computation sets do_not_record,
+       invalidate and do not record it.
+
 2015-02-03  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/64660
index 7edd901189980a650544a9ac7a8d7130f7b7bc38..2a33827a61c9f3d28afde01296c1161b3463805a 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1984,6 +1984,22 @@ invalidate (rtx x, machine_mode full_mode)
       gcc_unreachable ();
     }
 }
+
+/* Invalidate DEST.  Used when DEST is not going to be added
+   into the hash table for some reason, e.g. do_not_record
+   flagged on it.  */
+
+static void
+invalidate_dest (rtx dest)
+{
+  if (REG_P (dest)
+      || GET_CODE (dest) == SUBREG
+      || MEM_P (dest))
+    invalidate (dest, VOIDmode);
+  else if (GET_CODE (dest) == STRICT_LOW_PART
+          || GET_CODE (dest) == ZERO_EXTRACT)
+    invalidate (XEXP (dest, 0), GET_MODE (dest));
+}
 \f
 /* Remove all expressions that refer to register REGNO,
    since they are already invalid, and we are about to
@@ -5510,18 +5526,20 @@ cse_insn (rtx_insn *insn)
 
       else if (do_not_record)
        {
-         if (REG_P (dest) || GET_CODE (dest) == SUBREG)
-           invalidate (dest, VOIDmode);
-         else if (MEM_P (dest))
-           invalidate (dest, VOIDmode);
-         else if (GET_CODE (dest) == STRICT_LOW_PART
-                  || GET_CODE (dest) == ZERO_EXTRACT)
-           invalidate (XEXP (dest, 0), GET_MODE (dest));
+         invalidate_dest (dest);
          sets[i].rtl = 0;
        }
 
       if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
-       sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
+       {
+         do_not_record = 0;
+         sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
+         if (do_not_record)
+           {
+             invalidate_dest (SET_DEST (sets[i].rtl));
+             sets[i].rtl = 0;
+           }
+       }
 
 #ifdef HAVE_cc0
       /* If setting CC0, record what it was set to, or a constant, if it
index 98d72cbc38a3ae23802d83428e5ca8e560223bd3..7b2b03d318213cbbc695956b160d27a7d91daa92 100644 (file)
@@ -1,3 +1,8 @@
+2015-02-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/64756
+       * gcc.c-torture/execute/pr64756.c: New test.
+
 2015-02-03  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/64660
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64756.c b/gcc/testsuite/gcc.c-torture/execute/pr64756.c
new file mode 100644 (file)
index 0000000..b76f278
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR rtl-optimization/64756 */
+
+int a, *tmp, **c = &tmp;
+volatile int d;
+static int *volatile *e = &tmp;
+unsigned int f;
+
+static void
+fn1 (int *p)
+{
+  int g;
+  for (; f < 1; f++)
+    for (g = 1; g >= 0; g--)
+      {
+       d || d;
+       *c = p;
+
+       if (tmp != &a)
+         __builtin_abort ();
+
+       *e = 0;
+      }
+}
+
+int
+main ()
+{
+  fn1 (&a);
+  return 0;
+}