When investigating faulty rendering in GNOME Shell when running under s390x, I eventually discovered that compiling mutter with -O0 made the issue go away. Eventually I narrowed it down to a function that did a memcpy from a local float array to a stack allocated float array in a callee. I could also work around it in three ways: * #pragma GCC optimize ("O0") around the affected function. * Mark the float array copied from as volatile * Switch the memcpy to a for loop With that in mind, I took the relevant code, removed as much as I could while still reproducing. It isn't only the memcpy; e.g. it needs a bit of noise to make it reproduce. Attaching reproducing C file. When running, if it doesn't reproduce, it exits cleanly. If it reproduces it'll print 1.000000 == 0.000000 failed Aborted (core dumped) The three discovered workarounds are included in the C file, hidden behind `#if 0`. Reproducible: Always
Created attachment 2025354 [details] Reproducer
Jonas, could you make also the attachment public? Thanks.
(In reply to Dan Horák from comment #2) > Jonas, could you make also the attachment public? Thanks. Done; sorry about that.
Thanks and for the record it reproduces on z14 with gcc-14.0.1-0.13.fc41.s390x, but not with gcc-13.2.1-4.fc38.s390x
Simplified for -march=z13 -O0: typedef struct { const float *a; int b, c; float *d; } S; __attribute__((noipa)) void bar (void) { } __attribute__((noinline, optimize (2))) static void foo (S *e) { const float *f; float *g; float h[4] = { 0.0, 0.0, 1.0, 1.0 }; if (!e->b) f = h; else f = e->a; g = &e->d[0]; __builtin_memcpy (g, f, sizeof (float) * 4); bar (); if (!e->b) if (g[0] != 0.0 || g[1] != 0.0 || g[2] != 1.0 || g[3] != 1.0) __builtin_abort (); } int main () { float d[4]; S e = { .d = d }; foo (&e); return 0; } Bisecting now.
Bisected to https://gcc.gnu.org/r14-5831