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