The following testcase is miscompiled e.g. with -O2 -march=zEC12 -mtune=z13 on s390x-linux: __attribute__((noipa)) void bar (char *p) { int i; for (i = 0; i < 6; i++) if (p[i] != "foobar"[i]) __builtin_abort (); for (; i < 32; i++) if (p[i] != '\0') __builtin_abort (); } __attribute__((noipa)) void foo (unsigned int x) { char s[32] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 }; ((unsigned int *) s)[2] = __builtin_bswap32 (x); bar (s); } int main () { foo (0); return 0; } The problem is that since that change we emit a store_by_pieces (8 bytes) followed by clear_storage (24 bytes), but the object we pass to the latter actually has S1, so DSE2 then happily removes it when it sees a further store of 4 bytes to s+8.
Created attachment 46112 [details] gcc9-pr90025.patch Untested fix.
Author: jakub Date: Wed Apr 10 07:28:05 2019 New Revision: 270247 URL: https://gcc.gnu.org/viewcvs?rev=270247&root=gcc&view=rev Log: PR middle-end/90025 * expr.c (store_expr): Set properly size on the MEM passed to clear_storage. * gcc.c-torture/execute/pr90025.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr90025.c Modified: trunk/gcc/ChangeLog trunk/gcc/expr.c trunk/gcc/testsuite/ChangeLog
Fixed.