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);
 

Reply via email to