The following fixes a bug in VRP where on removal of asserts it ended up propagating a constant in place of abnormal SSA uses. That doesn't work when the use is in an abnormal PHI thus instead replace the assert with a copy in that case.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2017-09-19 Richard Biener <rguent...@suse.de> PR tree-optimization/82244 * tree-vrp.c (remove_range_assertions): Do not propagate a constant to abnormals but replace the assert with a copy. * gcc.dg/torture/pr82244.c: New testcase. Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 252968) +++ gcc/tree-vrp.c (working copy) @@ -7039,6 +7039,14 @@ remove_range_assertions (void) FOR_EACH_IMM_USE_ON_STMT (use_p, iter) SET_USE (use_p, var); } + /* But do not propagate constants as that is invalid. */ + else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) + { + gassign *ass = gimple_build_assign (lhs, var); + gsi_replace (&si, ass, true); + gsi_next (&si); + continue; + } else replace_uses_by (lhs, var); Index: gcc/testsuite/gcc.dg/torture/pr82244.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr82244.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr82244.c (working copy) @@ -0,0 +1,31 @@ +/* { dg-do compile } */ + +typedef struct a { + struct a *b; +} a; + +extern int d(void); +extern int g(void); +extern int h(void); +extern int _setjmp(void *); + +int c(void) +{ + 1 ? d() : 0; + + a *e; + while (e) { + e = (e == (a *) c) ? 0 : e->b; + while (e) { + int f = 0; + g(); + if (_setjmp(0)) { + if (f & 6) { + ; + } else if (f & 2) { + h(); + } + } + } + } +}