extern void abort (void); extern void exit (int); struct T { char *t1; char t2[4096]; char **t3; }; int a[5]; int b; char **c; int d; char **e; struct T t; char *f[16]; char *g[] = { "a", "-u", "b", "c" }; __attribute__ ((__noreturn__)) void foo (void) { while (1); } __attribute__ ((noinline)) char * bar (char *x, unsigned int y) { return 0; } static inline char * baz (char *x, unsigned int y) { if (sizeof (t.t2) != (unsigned int) -1 && y > sizeof (t.t2)) foo (); return bar (x, y); } static inline int setup1 (int x) { char *p; int rval; if (!baz (t.t2, sizeof (t.t2))) baz (t.t2, sizeof (t.t2)); if (x & 0x200) { char **h, **i = e; ++d; e = f; if (t.t1 && *t.t1) e[0] = t.t1; else abort (); for (h = e + 1; (*h = *i); ++i, ++h) ; } return 1; } static inline int setup2 (void) { int j = 1; e = c + 1; d = b - 1; while (d > 0 && e[0][0] == '-') { if (e[0][1] != '\0' && e[0][2] != '\0') abort (); switch (e[0][1]) { case 'u': if (!e[1]) abort (); t.t3 = &e[1]; d--; e++; break; case 'P': j |= 0x1000; break; case '-': d--; e++; if (j == 1) j |= 0x600; return j; } d--; e++; } if (d > 0 && !(j & 1)) abort (); return j; } int main (void) { int x; c = g; b = 4; x = setup2 (); t.t1 = "/bin/sh"; setup1 (x); if ((x & 0x400) && !a[4]) abort (); exit (0); } is miscompiled on at least i386, x86_64 and ppc32 at -O2 (but e.g. on ppc64 is not). The bug goes away with -O2 -fno-tree-pre. At *.crited there is still: xD.1586_12 = PHI <1537(10), xD.1586_61(38), xD.1586_2(28), xD.1586_128(27)>; later on used by x.0D.1645_38 = (unsigned intD.3) xD.1586_12; ... D.1589_46 = x.0D.1645_38 >> 10; D.1590_47 = (intD.0) D.1589_46; D.1591_48 = D.1590_47 & 1; if (D.1591_48 != 0) goto <L40>; else goto <L66>; 1537 == 0x601 is one of the possible values for x, if g contained say "--" as second argument, but it is certainly not the only one (x should be 1 with the g array provided in the testcase). Yet PRE decides to use 0x601, so the if ((x & 0x400) && !a[4]) abort (); test aborts.
Confirmed, i have a patch coming. I missed an early exit condition in constification during PRE. This also occurs in 4.1.
Subject: Bug 20601 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: dberlin@gcc.gnu.org 2005-03-23 18:14:13 Modified files: gcc : ChangeLog tree-ssa-pre.c Added files: gcc/testsuite/gcc.dg/tree-ssa: pr20601.c Log message: 2005-03-23 Daniel Berlin <dberlin@dberlin.org> Fix PR tree-optimization/20601 * tree-ssa-pre.c (insert_aux): Add missing condition to constification. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.7592.2.80&r2=2.7592.2.81 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-pre.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.65&r2=2.65.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr20601.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1
Subject: Bug 20601 CVSROOT: /cvs/gcc Module name: gcc Changes by: dberlin@gcc.gnu.org 2005-03-23 18:14:52 Modified files: gcc : ChangeLog tree-ssa-pre.c Added files: gcc/testsuite/gcc.dg/tree-ssa: pr20601.c Log message: 2005-03-23 Daniel Berlin <dberlin@dberlin.org> Fix PR tree-optimization/20601 * tree-ssa-pre.c (insert_aux): Add missing condition to constification. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7977&r2=2.7978 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-pre.c.diff?cvsroot=gcc&r1=2.71&r2=2.72 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr20601.c.diff?cvsroot=gcc&r1=1.1&r2=1.2
El fixed.