This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Assuage ICE in VRP with [1, X] + UINT_MAX (PR tree-optimization/71031)
- From: Marek Polacek <polacek at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Eric Botcazou <ebotcazou at adacore dot com>
- Date: Thu, 19 May 2016 17:14:24 +0200
- Subject: Re: [PATCH] Assuage ICE in VRP with [1, X] + UINT_MAX (PR tree-optimization/71031)
- Authentication-results: sourceware.org; auth=none
- References: <20160519134333 dot GF1611 at redhat dot com> <alpine dot LSU dot 2 dot 11 dot 1605191551500 dot 18037 at t29 dot fhfr dot qr>
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?
Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?
2016-05-19 Marek Polacek <polacek@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