diff mbox series

[committed] operator_abs::fold_range() returning incorrect result for overflows (pr92506)

Message ID c8696ca0-9f4a-4d2e-cc80-38d309852d5f@redhat.com
State New
Headers show
Series [committed] operator_abs::fold_range() returning incorrect result for overflows (pr92506) | expand

Commit Message

Andrew MacLeod Nov. 14, 2019, 7:03 p.m. UTC
Traced it back to a typo in operator_abs::fold_range() when I did the 
conversion where the wrong line got copied in..

Instead of returning value_range (type) when a overflow happens, it was 
returning the same result of the previous check, which was the case for 
all positives.
This had EVRP setting the range of an ABS to [-MIN, -1] instead of 
varying, which later caused VRP to intersect that with 0 - [-MIN, -1] 
and all heck broke loose. doh.

I also stumbled across a case where we should be starting with undefined 
in the default fold_range() and building with union for each sub-range.  
We previously declared a local value_range to work with, and that 
defaulted to undefined.  When I changed it to a reference parameter, I 
need to explicitly initialize it.

Bootstraps, checked in as revision 278259.

Andrew
diff mbox series

Patch


2019-11-14  Andrew MacLeod  <amacleod@redhat.com>

	* range-op.cc (range_operator::fold_range): Start with range undefined.
	(operator_abs::wi_fold): Fix wrong line copy... With wrapv, abs with
	overflow is varying.

Index: range-op.cc
===================================================================
*** range-op.cc	(revision 277979)
--- range-op.cc	(working copy)
*************** range_operator::fold_range (value_range
*** 146,151 ****
--- 146,152 ----
      return;
  
    value_range tmp;
+   r.set_undefined ();
    for (unsigned x = 0; x < lh.num_pairs (); ++x)
      for (unsigned y = 0; y < rh.num_pairs (); ++y)
        {
*************** operator_abs::wi_fold (value_range &r, t
*** 2359,2365 ****
    wide_int max_value = wi::max_value (prec, sign);
    if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lh_lb, min_value))
      {
!       r = value_range (type, lh_lb, lh_ub);
        return;
      }
  
--- 2360,2366 ----
    wide_int max_value = wi::max_value (prec, sign);
    if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lh_lb, min_value))
      {
!       r = value_range (type);
        return;
      }