[Bug tree-optimization/88301] [8/9 Regression] Optimization regression with undefined unsigned overflow

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Dec 3 09:38:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88301

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
           Keywords|                            |missed-optimization
   Last reconfirmed|                            |2018-12-03
          Component|middle-end                  |tree-optimization
                 CC|                            |rguenth at gcc dot gnu.org
     Ever confirmed|0                           |1
            Summary|Optimization regression     |[8/9 Regression]
                   |with undefined unsigned     |Optimization regression
                   |overflow                    |with undefined unsigned
                   |                            |overflow
   Target Milestone|---                         |8.3

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
This would be

void
evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
{
...
              if (is_fallthru
                  && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt))
                {
                  set_ssa_range_info (vrs[i].first, vrs[i].second);
                  maybe_set_nonzero_bits (pred_e, vrs[i].first);
                }

looks like we do not manage to find a new range for the assert for _2.
Hmm, for _2 we get

  _2 <= 4294967294

that's of course not too useful.  Looks like we are not factoring in
SSA range info when we register asserts for _3 != 0.  It's of course
somewhat of a special case...

The code we currently add the assert from is

      /* Add asserts for NAME cmp CST and NAME being defined as
         NAME = NAME2 & CST2.

         Extract CST2 from the and.

         Also handle
         NAME = (unsigned) NAME2;
         casts where NAME's type is unsigned and has smaller precision
         than NAME2's type as if it was NAME = NAME2 & MASK.  */
      names[0] = NULL_TREE;
      names[1] = NULL_TREE;
      cst2 = NULL_TREE;
      if (rhs_code == BIT_AND_EXPR

what we'd like to add is a case where we can look through a non-value-changing
conversion identifying that using SSA range-info.  Like

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c      (revision 266733)
+++ gcc/tree-vrp.c      (working copy)
@@ -2966,6 +2966,20 @@ register_edge_assert_for_2 (tree name, e
            add_assert_info (asserts, name2, tmp, new_comp_code, new_val);
        }

+      wide_int rmin, rmax;
+      tree rhs1 = gimple_assign_rhs1 (def_stmt);
+      if (CONVERT_EXPR_CODE_P (rhs_code)
+         && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+         && int_fits_type_p (val, TREE_TYPE (rhs1))
+         && (TYPE_PRECISION (TREE_TYPE (name)) > TYPE_PRECISION (TREE_TYPE
(rhs1))
+             || (get_range_info (rhs1, &rmin, &rmax) == VR_RANGE
+                 && (wi::min_precision (rmin, TYPE_SIGN (TREE_TYPE (rhs1)))
+                     <= TYPE_PRECISION (TREE_TYPE (name)))
+                 && (wi::min_precision (rmax, TYPE_SIGN (TREE_TYPE (rhs1)))
+                     <= TYPE_PRECISION (TREE_TYPE (name))))))
+       add_assert_info (asserts, rhs1, rhs1,
+                        comp_code, fold_convert (TREE_TYPE (rhs1), val));
+
       /* Add asserts for NAME cmp CST and NAME being defined as
         NAME = NAME2 & CST2.


but struggling with the range-fits-type idiom (we must have several copies
of that now...).  Maybe it should be instead

                  && wi::le_p (wi::to_widest (wi::min_value (TYPE_PRECISION
(TREE_TYPE (name)),
                                                             TYPE_SIGN
(name))),
                               wi::to_widest (rmin), SIGNED)
                  && wi::ge_p (wi::to_widest (wi::max_value (TYPE_PRECISION
(TREE_TYPE (name)),
                                                             TYPE_SIGN
(name))),
                               wi::to_widest (rmax), SIGNED)


More information about the Gcc-bugs mailing list