Hi!

As analyzed by Eric, DSE mishandles memset calls if it can't figure out what
the arguments to memset exactly are (it handles only register arguments
right now), or if the second or third arguments are not CONST_INTs.
In that case we don't call record_store, because we don't know what to call
it on; but we need to treat it as a wild store, which is handled by the
clear_rhs_from_active_local_stores () function (which record_store also uses
if it can't figure out what exactly is being overwritten).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2016-02-26  Jakub Jelinek  <ja...@redhat.com>
            Eric Botcazou  <ebotca...@adacore.com>

        PR rtl-optimization/69891
        * dse.c (scan_insn): If we can't figure out memset arguments
        or they are non-constant, call clear_rhs_from_active_local_stores.

        * gcc.target/i386/pr69891.c: New test.

--- gcc/dse.c.jj        2016-01-19 13:32:12.000000000 +0100
+++ gcc/dse.c   2016-02-26 11:03:36.694206088 +0100
@@ -2556,6 +2556,8 @@ scan_insn (bb_info_t bb_info, rtx_insn *
                      active_local_stores = insn_info;
                    }
                }
+             else
+               clear_rhs_from_active_local_stores ();
            }
        }
       else if (SIBLING_CALL_P (insn) && reload_completed)
--- gcc/testsuite/gcc.target/i386/pr69891.c.jj  2016-02-26 11:09:45.492079225 
+0100
+++ gcc/testsuite/gcc.target/i386/pr69891.c     2016-02-26 11:10:58.941058170 
+0100
@@ -0,0 +1,30 @@
+/* PR rtl-optimization/69891 */
+/* { dg-do run } */
+/* { dg-options "-O -fno-tree-fre -mstringop-strategy=libcall -Wno-psabi" } */
+/* { dg-additional-options "-mno-sse" { target ia32 } } */
+
+typedef unsigned short A;
+typedef unsigned short B __attribute__ ((vector_size (32)));
+typedef unsigned int C;
+typedef unsigned int D __attribute__ ((vector_size (32)));
+typedef unsigned long long E;
+typedef unsigned long long F __attribute__ ((vector_size (32)));
+
+__attribute__((noinline, noclone)) unsigned
+foo(D a, B b, D c, F d)
+{
+  b /= (B) {1, -c[0]} | 1;
+  c[0] |= 7;
+  a %= c | 1;
+  c ^= c;
+  return a[0] + b[15] + c[0] + d[3];
+}
+
+int
+main ()
+{
+  unsigned x = foo ((D) {}, (B) {}, (D) {}, (F) {});
+  if (x != 0)
+    __builtin_abort ();
+  return 0;
+}

        Jakub

Reply via email to