As we touched on in IRC, the EVRP analyzer was doing something stupid which caused it to not merge in existing range information under certain circumstances.
Consider this fragment: x_1 = foo () if (x_1 > 2) __builtin_unreachable (); if (x_1 < 0) __builtin_unreachable (); Obviously the range for x_1 is [0,2] and we compute that range in the EVRP optimization pass as well as VRP. If a pass (say VRP) were to delete the __builtin_unreachable calls we'll be left with: x_1 = foo () Any subsequent EVRP analysis won't be able to generate range information for that statement -- ie, it looks like VR_VARYING. Due to a dumb bug in the EVRP analysis we allowed that VR_VARYING to override any range that had been computed by an earlier VRP or EVRP pass. Fixing is trivial. Always call update_value_range, even if the currently discovered range is VR_VARYING. Bootstrapped and regression tested, both in isolation and as part of this 3 part kit. OK for the trunk? Jeff
* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::extract_range_from_stmt): Always use vr_values::update_value_range so preexisting range info is medged with new range info, even if the new range is VR_VARYING. diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index 551b1d6..fb3d329 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -271,8 +271,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) edge taken_edge; value_range vr = VR_INITIALIZER; vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr); - if (output - && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)) + if (output) { vr_values->update_value_range (output, &vr);