https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93908
Bug ID: 93908 Summary: [8/9/10 Regression] git miscompilation on s390x-linux with -O2 -march=zEC12 -mtune=z13 starting with r8-1288 Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- The following testcase manually reduced from git's diff.c is miscompiled on s390x-linux with -O2 -march=zEC12 -mtune=z13 starting with r8-1288-ge701e0b9e8c74e5e93764556a447ea334e4e9389 . git itself started to be miscompiled with r10-4651-gafeb887562af17ea235fbec650ff6d16c412682a (r10-4650 fails to build), but that was just (apparently quite significant) change in inlining behavior (Martin L., was that intended?). struct T { int b; int c; unsigned short d; unsigned e:1, f:1, g:1, h:2, i:1, j:1; signed int k:2; }; struct S { struct T s; char c[64]; } buf[2]; __attribute__ ((noinline, noclone, noipa)) void * baz (void) { static int cnt; return (void *) &buf[cnt++]; } static inline __attribute__ ((always_inline)) struct T * bar (const char *a) { struct T *s; s = baz (); s->b = 1; s->k = -1; return s; } __attribute__ ((noinline, noclone, noipa)) void foo (const char *x, struct T **y) { struct T *l = bar (x); struct T *m = bar (x); y[0] = l; y[1] = m; } int main () { struct T *r[2]; foo ("foo", r); if (r[0]->e || r[0]->f || r[0]->g || r[0]->h || r[0]->i || r[0]->j || r[0]->k != -1) __builtin_abort (); if (r[1]->e || r[1]->f || r[1]->g || r[1]->h || r[1]->i || r[1]->j || r[1]->k != -1) __builtin_abort (); return 0; } The first s->k = -1; bitfield store is always done through: (insn 14 13 15 2 (parallel [ (set (mem/j:HI (plus:DI (reg/v/f:DI 61 [ s ]) (const_int 10 [0xa])) [0 +0 S2 A16]) (ior:HI (mem/j:HI (plus:DI (reg/v/f:DI 61 [ s ]) (const_int 10 [0xa])) [0 +0 S2 A16]) (const_int 384 [0x180]))) (clobber (reg:CC 33 %cc)) ]) "diff2.i":29 1733 {*iorhi3_zarch} (expr_list:REG_UNUSED (reg:CC 33 %cc) (nil))) but the second one changed like: (insn 22 21 23 2 (parallel [ (set (mem/j:HI (plus:DI (reg/v/f:DI 60 [ s ]) (const_int 10 [0xa])) [0 +0 S2 A16]) (ior:HI (mem/j:HI (plus:DI (reg/v/f:DI 60 [ s ]) (const_int 10 [0xa])) [0 +0 S2 A16]) - (const_int 384 [0x180]))) + (const_int -128 [0xffffffffffffff80]))) (clobber (reg:CC 33 %cc)) ]) "diff2.i":29 1733 {*iorhi3_zarch} (expr_list:REG_UNUSED (reg:CC 33 %cc) (nil))) which means it sets to all ones various other bitfields.