http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58387
--- Comment #12 from Zhendong Su <su at cs dot ucdavis.edu> --- (In reply to Jeffrey A. Law from comment #11) > I know what's happening here. It's obscure and quite nasty. > > We have a jump threading opportunity which requires threading through a > joiner block. The jump thread leaving one edge of the joiner eventually > reaches the same block as the joiner's other outgoing edge. > > This is all fine and good as the threading code knows the conditions under > which it's still safe to thread that jump. Specifically it has to look at > the PHI arguments for the two key edges and verify for each PHI that the > values associated with the two key edges are the same. This condition is in > place to make the SSA graph updates easier to deal with. > > At the time we discover and register the jump thread the condition holds and > we're good to go. However a short time later we discover that we can > propagate a constant to one of those PHI arguments and do so. Now the > condition we needed for updating the SSA graph was broken. We update the > SSA graph incorrectly. > > I'm going to have to review the SSA graph updating code a bit tomorrow AM. > In the mean time I'm going to revert the patch. Jeff, I have another related testcase that only fails for the 32-bit mode (also at -Os and above). It is a lot more complex, and the root cause is likely the same as this one. In case it may be of some use to you (at least for testing your fix), I'm including it below. The body of the conditional, which is not executed, has an UB (accessing an initialized value: m[0]), which may explain the difference in -m32 and -m64. Also btw everyone, does this mean that the whole testcase has UB (thus invalid) even if the body of the if isn't executed at runtime at all? I'm a bit unclear on this, so any clarifications would be much appreciated. ---------------------------------- int printf(const char *, ...); int a = -1, b = 1, f, **e; static int c; int *volatile d; static void foo (int p) { int g, h, *i, *j = 0, k = g = a == 0 ? 0 : -a; if (p >= g) { int l, n = 0, s = 0, m[7], o[42]; int ***p = 0, ****q = &p, *r = &l, *v = &h; int **t[3] = { &i, &r, &j }; int *u[3] = { &n, &k, &s }; e = &v; i = &o[0]; d && *q; f = m[0]; b = 0; } } int main () { int x = 0, *y[1] = {&x}; foo (c); printf ("%d\n", b); return 0; }