Hi! As mentioned in the PR, since r269453 dom can process stmts newly added by fold_stmt. The problem is that at the start of the pass we construct vr_values with the current number of SSA names and size the tables based on that. When we process a stmt which sets on lhs a new SSA_NAME above that number, get_value_range returns for that address of a shared constant VR_VARYING variable, but if we manage to find some smaller range, update_value_range happily updates that shared range to this.
Based on IRC discussion, this is a minimal fix, approved by Richard on IRC. Bootstrapped/regtested on {x86_64,i686,powerpc64le}-linux and bootstrapped on {aarch64,s390x}-linux (profiledbootstrap for all; where aarch64-linux profiledbootstrap would previously fail), committed to trunk. 2019-03-11 Jakub Jelinek <ja...@redhat.com> PR middle-end/89655 PR bootstrap/89656 * vr-values.c (vr_values::update_value_range): If old_vr->varying_p (), don't update it, make new_vr also VARYING and return false. * gcc.c-torture/compile/pr89655.c: New test. --- gcc/vr-values.c.jj 2019-01-24 19:54:20.792500923 +0100 +++ gcc/vr-values.c 2019-03-11 12:46:34.526494064 +0100 @@ -189,8 +189,13 @@ vr_values::update_value_range (const_tre because VR_RANGE and VR_ANTI_RANGE need to be considered the same. We may not have is_new when transitioning to UNDEFINED. If old_vr->type is VARYING, we shouldn't be - called. */ - if (new_vr->undefined_p ()) + called, if we are anyway, keep it VARYING. */ + if (old_vr->varying_p ()) + { + new_vr->set_varying (); + is_new = false; + } + else if (new_vr->undefined_p ()) { old_vr->set_varying (); new_vr->set_varying (); --- gcc/testsuite/gcc.c-torture/compile/pr89655.c.jj 2019-03-11 13:45:27.279823237 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr89655.c 2019-03-11 13:45:10.482097642 +0100 @@ -0,0 +1,15 @@ +/* PR middle-end/89655 */ + +int a, b, d; +char *c; + +void +foo (void) +{ + int f = a; + for (;;) + { + for (f = 0; f < (a > 3 ? : a); f++) + b = c[f] ? c[(f + 2 > a - 1 ? a - 1 : 2) * d] : 0; + } +} Jakub