Fix PR tree-optimization/92131

Message ID 3809287.lTAF2qdqtq@polaris
State New
Headers show
Series
  • Fix PR tree-optimization/92131
Related show

Commit Message

Eric Botcazou Oct. 23, 2019, 8:32 a.m.
This is a regression present on mainline, 9 and 8 branches, but the underlying 
issue is probably latent on the 7 branch.  compare_values in tree-vrp.c can 
rely on undefined overflow to compare symbolic expressions with constants so 
we must make sure not to introduce such an overflow when combining ranges with 
symbolic expressions.

Tested on x86_64-suse-linux, OK for all active branches?


2019-10-23  Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/92131
	* tree-vrp.c (extract_range_from_plus_minus_expr): If the resulting
	range would be symbolic, drop to varying for any explicit overflow
	in the constant part or if one of the ranges is not a singleton.


2019-10-23  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/execute/20191023-1.c: New test.

-- 
Eric Botcazou

Comments

Richard Biener Oct. 23, 2019, 8:47 a.m. | #1
On Wed, Oct 23, 2019 at 10:33 AM Eric Botcazou <ebotcazou@adacore.com> wrote:
>

> This is a regression present on mainline, 9 and 8 branches, but the underlying

> issue is probably latent on the 7 branch.  compare_values in tree-vrp.c can

> rely on undefined overflow to compare symbolic expressions with constants so

> we must make sure not to introduce such an overflow when combining ranges with

> symbolic expressions.

>

> Tested on x86_64-suse-linux, OK for all active branches?


OK.

Thanks,
Richard.

>

> 2019-10-23  Eric Botcazou  <ebotcazou@adacore.com>

>

>         PR tree-optimization/92131

>         * tree-vrp.c (extract_range_from_plus_minus_expr): If the resulting

>         range would be symbolic, drop to varying for any explicit overflow

>         in the constant part or if one of the ranges is not a singleton.

>

>

> 2019-10-23  Eric Botcazou  <ebotcazou@adacore.com>

>

>         * gcc.c-torture/execute/20191023-1.c: New test.

>

> --

> Eric Botcazou

Patch

Index: tree-vrp.c
===================================================================
--- tree-vrp.c	(revision 277149)
+++ tree-vrp.c	(working copy)
@@ -1652,7 +1652,7 @@  extract_range_from_plus_minus_expr (valu
   value_range_kind vr0_kind = vr0.kind (), vr1_kind = vr1.kind ();
   tree vr0_min = vr0.min (), vr0_max = vr0.max ();
   tree vr1_min = vr1.min (), vr1_max = vr1.max ();
-  tree min = NULL, max = NULL;
+  tree min = NULL_TREE, max = NULL_TREE;
 
   /* This will normalize things such that calculating
      [0,0] - VR_VARYING is not dropped to varying, but is
@@ -1715,18 +1715,19 @@  extract_range_from_plus_minus_expr (valu
       combine_bound (code, wmin, min_ovf, expr_type, min_op0, min_op1);
       combine_bound (code, wmax, max_ovf, expr_type, max_op0, max_op1);
 
-      /* If we have overflow for the constant part and the resulting
-	 range will be symbolic, drop to VR_VARYING.  */
-      if (((bool)min_ovf && sym_min_op0 != sym_min_op1)
-	  || ((bool)max_ovf && sym_max_op0 != sym_max_op1))
+      /* If the resulting range will be symbolic, we need to eliminate any
+	 explicit or implicit overflow introduced in the above computation
+	 because compare_values could make an incorrect use of it.  That's
+	 why we require one of the ranges to be a singleton.  */
+      if ((sym_min_op0 != sym_min_op1 || sym_max_op0 != sym_max_op1)
+	  && ((bool)min_ovf || (bool)max_ovf
+	      || (min_op0 != max_op0 && min_op1 != max_op1)))
 	{
 	  vr->set_varying (expr_type);
 	  return;
 	}
 
       /* Adjust the range for possible overflow.  */
-      min = NULL_TREE;
-      max = NULL_TREE;
       set_value_range_with_overflow (kind, min, max, expr_type,
 				     wmin, wmax, min_ovf, max_ovf);
       if (kind == VR_VARYING)