https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70025
Bug ID: 70025 Summary: [6 Regression] Miscompilation of gc-7.4.2 on s390x starting with r227382 Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- typedef char (*F) (unsigned long, void *); typedef union { struct A { char a1, a2, a3, a4; unsigned long a5; F a6; void *a7; } b; char c[1]; } B; struct C { const char *c1; unsigned long c2; }; typedef struct D { unsigned long d1; int d2; const char *d3; unsigned long d4, d5; struct C d6[49]; char d7[8]; } E[1]; __attribute__ ((noinline, noclone)) void foo (register E p) { asm volatile (""::"r" (p):"memory"); } __attribute__ ((noinline, noclone)) void bar (register E p) { register unsigned long k = p[0].d1 + 1; register struct C *l = &((p)[0].d6[(p)[0].d2]); register const char *m = l->c1; p[0].d1 = k; if (*m == '\0') { register struct A *f = &((B *) m)->b; register unsigned long n = l->c2; register unsigned long o = n + f->a5; if (k < o) { register unsigned long i; register unsigned long q = k + 8; register F a6 = f->a6; register void *a7 = f->a7; if (q > o) q = o; for (i = k; i < q; i++) p[0].d7[i - k] = (*a6) (i - n, a7); p[0].d4 = k; p[0].d3 = p[0].d7; p[0].d5 = q; return; } } while (p[0].d2 > 0 && l[0].c2 != l[-1].c2) { p[0].d2--; l--; } if (p[0].d2 == 0) { p[0].d2 = 0x55555555; return; } p[0].d2--; foo (p); } char baz (unsigned long i, void *j) { if (j != 0) __builtin_abort (); return (char) i; } int main () { struct D p; struct A f; __builtin_memset (&f, 0, sizeof (f)); f.a2 = 4; f.a5 = 13; f.a6 = baz; __builtin_memset (&p, 0, sizeof (p)); p.d6[0].c1 = (const char *) &f; bar (&p); if (p.d4 != 1 || p.d5 != 9 || p.d3 != p.d7) __builtin_abort (); return 0; } is miscompiled on s390x-linux, starting with r227382 with -m64 -march=z9-109 -mtune=z10 -O2. In *.ira we have: (insn 97 98 191 10 (parallel [ (set (mem/f:DI (plus:DI (reg/v/f:DI 151 [orig:129 p ] [129]) (const_int 16 [0x10])) [4 p_8(D)->d3+0 S8 A64]) (plus:DI (reg/v/f:DI 151 [orig:129 p ] [129]) (const_int 824 [0x338]))) (clobber (reg:CC 33 %cc)) ]) cordbscs2.c:36 1267 {*adddi3} (expr_list:REG_DEAD (reg/v/f:DI 151 [orig:129 p ] [129]) (expr_list:REG_UNUSED (reg:CC 33 %cc) (nil)))) but LRA incorrectly reloads it as: (insn 97 98 224 10 (parallel [ (set (reg/v/f:DI 1 %r1 [orig:129 p ] [129]) (plus:DI (reg/v/f:DI 1 %r1 [orig:129 p ] [129]) (const_int 824 [0x338]))) (clobber (reg:CC 33 %cc)) ]) cordbscs2.c:36 1267 {*adddi3} (nil)) (insn 224 97 191 10 (set (mem/f:DI (plus:DI (reg/v/f:DI 1 %r1 [orig:129 p ] [129]) (const_int 16 [0x10])) [4 p_8(D)->d3+0 S8 A64]) (reg/v/f:DI 1 %r1 [orig:129 p ] [129])) cordbscs2.c:36 995 {*movdi_64} (nil)) Thus it writes correct value to a wrong address.