On Wed, Mar 02, 2016 at 07:30:12AM +0100, Jakub Jelinek wrote: > On Tue, Mar 01, 2016 at 08:43:21PM -0500, Vladimir Makarov wrote: > > The following patch should fix PR > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70025 > > > > The patch was successfully bootstrapped and tested on x86/x86-64. > > > > Committed as rev. 233876. > > Thanks. > > > I'll work on the test tomorrow -- I have no access to s390x right now. > > I'll take care of it.
Here is what I've committed to trunk, turns out the bug used to be reproduceable even with the least common -m64 s390x denominator (-march=z900) up to newer ones. 2016-03-02 Jakub Jelinek <ja...@redhat.com> PR middle-end/70025 * gcc.dg/torture/pr70025.c: New test. --- gcc/testsuite/gcc.dg/torture/pr70025.c.jj 2016-03-02 07:47:18.672709500 +0100 +++ gcc/testsuite/gcc.dg/torture/pr70025.c 2016-03-02 07:52:17.659557439 +0100 @@ -0,0 +1,81 @@ +/* PR middle-end/70025 */ +/* { dg-do run } */ +/* { dg-additional-options "-mtune=z10" { target s390*-*-* } } */ + +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; +} Jakub