[Bug tree-optimization/78681] [7 Regressions] ICE in determine_value_range, at tree-ssa-loop-niter.c:413

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Dec 5 18:49:00 GMT 2016


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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Yeah:
--- gcc/ipa-prop.c.jj   2016-11-25 18:11:05.000000000 +0100
+++ gcc/ipa-prop.c      2016-12-05 18:48:48.853882864 +0100
@@ -5709,8 +5709,23 @@ ipcp_update_vr (struct cgraph_node *node
        {
          tree type = TREE_TYPE (ddef);
          unsigned prec = TYPE_PRECISION (type);
+         unsigned mprec = wi::get_precision (vr[i].min);
+         gcc_assert (mprec == wi::get_precision (vr[i].max));
          if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
            {
+             if (prec < mprec)
+               {
+                 /* If there is a disagreement between callers and callee
+                    on the argument type, e.g. when using K&R function
+                    definitions, punt if vr[i].min or vr[i].max are outside
+                    of type's precision.  */
+                 wide_int m = wi::ext (vr[i].min, prec, TYPE_SIGN (type));
+                 if (m != vr[i].min)
+                   continue;
+                 m = wi::ext (vr[i].max, prec, TYPE_SIGN (type));
+                 if (m != vr[i].max)
+                   continue;
+               }
              if (dump_file)
                {
                  fprintf (dump_file, "Setting value range of param %u ", i);
@@ -5729,6 +5744,7 @@ ipcp_update_vr (struct cgraph_node *node
            }
          else if (POINTER_TYPE_P (TREE_TYPE (ddef))
                   && vr[i].type == VR_ANTI_RANGE
+                  && mprec <= prec
                   && wi::eq_p (vr[i].min, 0)
                   && wi::eq_p (vr[i].max, 0))
            {
works for me (i.e. if the callers expect higher precision and the range doesn't
fit into the smaller type, punt).
Not sure if one can construct a testcase where prec == mprec, but the
signedness differ (either vr[i].min/vr[i].max is from signed type and type is
unsigned, or vice versa).  Tried:
static void foo (int, unsigned int);

static int
foo (x, y)
  unsigned int x;
  int y;
{
  return x + y;
}

void
bar (int x, unsigned int y)
{
  if (x < - __INT_MAX__ + 3 || x >= __INT_MAX__ - 19)
    return;
  if (y < 5 || y >= ~19U)
    return;
  x++;
  y++;
  foo (x, y);
  x++;
  y++;
  foo (x, y);
}

but that is rejected.


More information about the Gcc-bugs mailing list