re PR rtl-optimization/70467 (Useless "and [esp],-1" emitted on AND with uint64_t...
authorJakub Jelinek <jakub@redhat.com>
Mon, 2 May 2016 16:46:10 +0000 (18:46 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 2 May 2016 16:46:10 +0000 (18:46 +0200)
PR rtl-optimization/70467
* cse.c (cse_insn): Handle no-op MEM moves after folding.

* gcc.target/i386/pr70467-1.c: New test.

From-SVN: r235765

gcc/ChangeLog
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr70467-1.c [new file with mode: 0644]

index 5bf2ffa7c35e954170b953c890f3a2bed4984eef..a5339da2527fd73008aa4205c208ccd791894ce2 100644 (file)
@@ -1,5 +1,8 @@
 2016-05-02  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/70467
+       * cse.c (cse_insn): Handle no-op MEM moves after folding.
+
        PR rtl-optimization/70467
        * ipa-pure-const.c (check_call): Handle internal calls even in
        ipa mode like in local mode.
index 2665d9a2733cad7286b41a88753acfcf79be83f1..7456e84c3294c31f25bfa5464e352cbb056ca1e1 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4575,6 +4575,7 @@ cse_insn (rtx_insn *insn)
   for (i = 0; i < n_sets; i++)
     {
       bool repeat = false;
+      bool mem_noop_insn = false;
       rtx src, dest;
       rtx src_folded;
       struct table_elt *elt = 0, *p;
@@ -5166,7 +5167,7 @@ cse_insn (rtx_insn *insn)
            }
 
          /* Avoid creation of overlapping memory moves.  */
-         if (MEM_P (trial) && MEM_P (SET_DEST (sets[i].rtl)))
+         if (MEM_P (trial) && MEM_P (dest) && !rtx_equal_p (trial, dest))
            {
              rtx src, dest;
 
@@ -5277,6 +5278,21 @@ cse_insn (rtx_insn *insn)
              break;
            }
 
+         /* Similarly, lots of targets don't allow no-op
+            (set (mem x) (mem x)) moves.  */
+         else if (n_sets == 1
+                  && MEM_P (trial)
+                  && MEM_P (dest)
+                  && rtx_equal_p (trial, dest)
+                  && !side_effects_p (dest)
+                  && (cfun->can_delete_dead_exceptions
+                      || insn_nothrow_p (insn)))
+           {
+             SET_SRC (sets[i].rtl) = trial;
+             mem_noop_insn = true;
+             break;
+           }
+
          /* Reject certain invalid forms of CONST that we create.  */
          else if (CONSTANT_P (trial)
                   && GET_CODE (trial) == CONST
@@ -5495,6 +5511,16 @@ cse_insn (rtx_insn *insn)
          sets[i].rtl = 0;
        }
 
+      /* Similarly for no-op MEM moves.  */
+      else if (mem_noop_insn)
+       {
+         if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
+           cse_cfg_altered = true;
+         delete_insn_and_edges (insn);
+         /* No more processing for this set.  */
+         sets[i].rtl = 0;
+       }
+
       /* If this SET is now setting PC to a label, we know it used to
         be a conditional or computed branch.  */
       else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
index 7d7dae4dcf9d06084536662b4e470e893d7a7bd1..328a9a5f056052a5a9e7fc10c7be46a7d3f1bd1a 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/70467
+       * gcc.target/i386/pr70467-1.c: New test.
+
 2016-05-02  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        * gcc.dg/spec-options.c: Run the test on all targets.
diff --git a/gcc/testsuite/gcc.target/i386/pr70467-1.c b/gcc/testsuite/gcc.target/i386/pr70467-1.c
new file mode 100644 (file)
index 0000000..4e112c8
--- /dev/null
@@ -0,0 +1,55 @@
+/* PR rtl-optimization/70467 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-sse" } */
+
+void foo (unsigned long long *);
+
+void
+bar (void)
+{
+  unsigned long long a;
+  foo (&a);
+  a &= 0x7fffffffffffffffULL;
+  foo (&a);
+  a &= 0xffffffff7fffffffULL;
+  foo (&a);
+  a &= 0x7fffffff00000000ULL;
+  foo (&a);
+  a &= 0x000000007fffffffULL;
+  foo (&a);
+  a &= 0x00000000ffffffffULL;
+  foo (&a);
+  a &= 0xffffffff00000000ULL;
+  foo (&a);
+  a |= 0x7fffffffffffffffULL;
+  foo (&a);
+  a |= 0xffffffff7fffffffULL;
+  foo (&a);
+  a |= 0x7fffffff00000000ULL;
+  foo (&a);
+  a |= 0x000000007fffffffULL;
+  foo (&a);
+  a |= 0x00000000ffffffffULL;
+  foo (&a);
+  a |= 0xffffffff00000000ULL;
+  foo (&a);
+  a ^= 0x7fffffffffffffffULL;
+  foo (&a);
+  a ^= 0xffffffff7fffffffULL;
+  foo (&a);
+  a ^= 0x7fffffff00000000ULL;
+  foo (&a);
+  a ^= 0x000000007fffffffULL;
+  foo (&a);
+  a ^= 0x00000000ffffffffULL;
+  foo (&a);
+  a ^= 0xffffffff00000000ULL;
+  foo (&a);
+}
+
+/* { dg-final { scan-assembler-not "andl\[ \t\]*.-1," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "andl\[ \t\]*.0," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "orl\[ \t\]*.-1," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "orl\[ \t\]*.0," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "xorl\[ \t\]*.-1," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "xorl\[ \t\]*.0," { target ia32 } } } */