https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91789
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2019-09-17 Ever confirmed|0 |1 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- So EVRP sees Visiting controlling predicate if (a_3(D) < 0) Adding assert for a_3(D) from a_3(D) >= 0 Intersecting int [0, +INF] EQUIVALENCES: { a_3(D) } (1 elements) and int [-INF, b_2(D)] EQUIVALENCES: { a_3(D) } (1 elements) to int [0, +INF] EQUIVALENCES: { a_3(D) } (1 elements) Intersecting int [-INF, b_2(D)] and int [0, +INF] to int [-INF, b_2(D)] where the intersection could produce [0, b_2(D)] with the twist that this range might be empty in case b_2(D) < 0. The issue in the intersection routine is that we use predicates like else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1) && (mineq || operand_less_p (*vr0min, vr1min) == 1)) when we mean less-or-equal but for symbolic values with maxeq = vrp_operand_equal_p (*vr0max, vr1max) this isn't the same. compare_values could in theory represent this (but it doesn't). IMHO this has nothing to do with "backward" or "forward" processing but simply with how combination of the predicates/ranges works.