The following addresses value_range::union_ranges which ends up doing quite some redundant work for the PR91257 testcase via PHI argument processing. compare_values isn't really much slower once you may end up needing more than a single operand_less_p - in fact for non-constant ranges it often ends up dispatching there.
Bootstrap / regtest running on x86_64-unknown-linux-gnu. Richard. 2019-07-30 Richard Biener <rguent...@suse.de> PR tree-optimization/91257 * tree-vrp.c (union_ranges): Unify equality and less tests by using compare_values. Re-order cheap tests first. Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 273795) +++ gcc/tree-vrp.c (working copy) @@ -5468,8 +5474,10 @@ union_ranges (enum value_range_kind *vr0 enum value_range_kind vr1type, tree vr1min, tree vr1max) { - bool mineq = vrp_operand_equal_p (*vr0min, vr1min); - bool maxeq = vrp_operand_equal_p (*vr0max, vr1max); + int cmpmin = compare_values (*vr0min, vr1min); + int cmpmax = compare_values (*vr0max, vr1max); + bool mineq = cmpmin == 0; + bool maxeq = cmpmax == 0; /* [] is vr0, () is vr1 in the following classification comments. */ if (mineq && maxeq) @@ -5569,8 +5577,8 @@ union_ranges (enum value_range_kind *vr0 else gcc_unreachable (); } - else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1) - && (mineq || operand_less_p (*vr0min, vr1min) == 1)) + else if ((maxeq || cmpmax == 1) + && (mineq || cmpmin == -1)) { /* [ ( ) ] or [( ) ] or [ ( )] */ if (*vr0type == VR_RANGE @@ -5603,8 +5611,8 @@ union_ranges (enum value_range_kind *vr0 else gcc_unreachable (); } - else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1) - && (mineq || operand_less_p (vr1min, *vr0min) == 1)) + else if ((maxeq || cmpmax == -1) + && (mineq || cmpmin == 1)) { /* ( [ ] ) or ([ ] ) or ( [ ]) */ if (*vr0type == VR_RANGE @@ -5643,10 +5651,10 @@ union_ranges (enum value_range_kind *vr0 else gcc_unreachable (); } - else if ((operand_less_p (vr1min, *vr0max) == 1 - || operand_equal_p (vr1min, *vr0max, 0)) - && operand_less_p (*vr0min, vr1min) == 1 - && operand_less_p (*vr0max, vr1max) == 1) + else if (cmpmin == -1 + && cmpmax == -1 + && (operand_less_p (vr1min, *vr0max) == 1 + || operand_equal_p (vr1min, *vr0max, 0))) { /* [ ( ] ) or [ ]( ) */ if (*vr0type == VR_RANGE @@ -5680,10 +5688,10 @@ union_ranges (enum value_range_kind *vr0 else gcc_unreachable (); } - else if ((operand_less_p (*vr0min, vr1max) == 1 - || operand_equal_p (*vr0min, vr1max, 0)) - && operand_less_p (vr1min, *vr0min) == 1 - && operand_less_p (vr1max, *vr0max) == 1) + else if (cmpmin == 1 + && cmpmax == 1 + && (operand_less_p (*vr0min, vr1max) == 1 + || operand_equal_p (*vr0min, vr1max, 0))) { /* ( [ ) ] or ( )[ ] */ if (*vr0type == VR_RANGE