On May 19, 2016 5:14:24 PM GMT+02:00, Marek Polacek <pola...@redhat.com> wrote:
>On Thu, May 19, 2016 at 03:54:05PM +0200, Richard Biener wrote:
>> On Thu, 19 May 2016, Marek Polacek wrote:
>> 
>> > Since Bin's changes to the niter analysis in r231097, we find
>ourselves in
>> > a situation where extract_range_from_binary_expr is given [1, od_5]
>+ UINT_MAX
>> > on type unsigned.  We combine the lower bounds, which is 1 +
>UINT_MAX = 0(OVF).
>> > We then combine the upper bounds, because the max_op0 is not a
>constant, the
>> > result of that is UINT_MAX.  That results in min overflow -- and an
>assert is
>> > unhappy about that.  As suggested in the PR, a safe thing would be
>to change
>> > the assert to dropping to varying.
>> > 
>> > Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?
>> 
>> Ok if you leave the assert in (there is at least one unhandled case,
>> min_ovf == 1 && max_ovf == -1).
>> 
>> Alternatively make the code match the comment and drop the
>> == 0 checks in your added condition.  Which would suggest
>> to make the else { an else if (asserted condition) and common
>> the varying case to else { }.
>
>Oh, this is indeed better.  So like this?

Yes.

Thanks,
Richard.

>Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?
>
>2016-05-19  Marek Polacek  <pola...@redhat.com>
>
>       PR tree-optimization/71031
>       * tree-vrp.c (extract_range_from_binary_expr_1): Turn assert into a
>       condition and adjust the code a bit.
>
>       * gcc.dg/tree-ssa/vrp100.c: New test.
>
>diff --git gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
>gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
>index e69de29..c0fe4b5 100644
>--- gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
>+++ gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
>@@ -0,0 +1,32 @@
>+/* PR tree-optimization/71031 */
>+/* { dg-do compile } */
>+/* { dg-options "-Os" } */
>+
>+int zj;
>+int **yr;
>+
>+void
>+nn (void)
>+{
>+  unsigned int od = 4;
>+
>+  for (;;)
>+    {
>+      int lk;
>+
>+      for (lk = 0; lk < 2; ++lk)
>+        {
>+          static int cm;
>+
>+          zj = 0;
>+          if (od == 0)
>+            return;
>+          ++od;
>+          for (cm = 0; cm < 2; ++cm)
>+            {
>+              --od;
>+              **yr = 0;
>+            }
>+        }
>+    }
>+}
>diff --git gcc/tree-vrp.c gcc/tree-vrp.c
>index 69e6248..92d889c 100644
>--- gcc/tree-vrp.c
>+++ gcc/tree-vrp.c
>@@ -2519,20 +2519,13 @@ extract_range_from_binary_expr_1 (value_range
>*vr,
>                 min = wide_int_to_tree (expr_type, tmin);
>                 max = wide_int_to_tree (expr_type, tmax);
>               }
>-            else if (min_ovf == -1 && max_ovf == 1)
>-              {
>-                /* Underflow and overflow, drop to VR_VARYING.  */
>-                set_value_range_to_varying (vr);
>-                return;
>-              }
>-            else
>+            else if ((min_ovf == -1 && max_ovf == 0)
>+                     || (max_ovf == 1 && min_ovf == 0))
>               {
>                 /* Min underflow or max overflow.  The range kind
>                    changes to VR_ANTI_RANGE.  */
>                 bool covers = false;
>                 wide_int tem = tmin;
>-                gcc_assert ((min_ovf == -1 && max_ovf == 0)
>-                            || (max_ovf == 1 && min_ovf == 0));
>                 type = VR_ANTI_RANGE;
>                 tmin = tmax + 1;
>                 if (wi::cmp (tmin, tmax, sgn) < 0)
>@@ -2551,6 +2544,12 @@ extract_range_from_binary_expr_1 (value_range
>*vr,
>                 min = wide_int_to_tree (expr_type, tmin);
>                 max = wide_int_to_tree (expr_type, tmax);
>               }
>+            else
>+              {
>+                /* Other underflow and/or overflow, drop to VR_VARYING.  */
>+                set_value_range_to_varying (vr);
>+                return;
>+              }
>           }
>         else
>           {
>
>       Marek


Reply via email to