]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/92131 (incorrect assumption that (ao >= 0) is always false)
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 23 Oct 2019 11:37:28 +0000 (11:37 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 23 Oct 2019 11:37:28 +0000 (11:37 +0000)
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 neither range is a singleton.

From-SVN: r277315

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20191023-1.c [new file with mode: 0644]
gcc/tree-vrp.c

index 1ab4bb9195387375c500cab7e029607d9dc3e084..d6d04b79d386b9a20131bc7bc48ea0869dcbdeab 100644 (file)
@@ -1,3 +1,10 @@
+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 neither range is a singleton.
+
 2019-10-23  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index 7c7e0bf8375342ba8d413cdd4fba49f96d53637c..71f2025075b500a3713c11459b79d47d0194ccb2 100644 (file)
@@ -1,3 +1,7 @@
+2019-10-23  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.c-torture/execute/20191023-1.c: New test.
+
 2019-10-23  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.c-torture/execute/20191023-1.c b/gcc/testsuite/gcc.c-torture/execute/20191023-1.c
new file mode 100644 (file)
index 0000000..3811ebc
--- /dev/null
@@ -0,0 +1,73 @@
+/* PR tree-optimization/92131 */
+/* Testcase by Armin Rigo <arigo@tunes.org> */
+
+long b, c, d, e, f, i;
+char g, h, j, k;
+int *aa;
+
+static void error (void) __attribute__((noipa));
+static void error (void) { __builtin_abort(); }
+
+static void see_me_here (void) __attribute__((noipa));
+static void see_me_here (void) {}
+
+static void aaa (void) __attribute__((noipa));
+static void aaa (void) {}
+
+static void a (void) __attribute__((noipa));
+static void a (void) {
+  long am, ao;
+  if (aa == 0) {
+    aaa();
+    if (j)
+      goto ay;
+  }
+  return;
+ay:
+  aaa();
+  if (k) {
+    aaa();
+    goto az;
+  }
+  return;
+az:
+  if (i)
+    if (g)
+      if (h)
+        if (e)
+          goto bd;
+  return;
+bd:
+  am = 0;
+  while (am < e) {
+    switch (c) {
+    case 8:
+      goto bh;
+    case 4:
+      return;
+    }
+  bh:
+    if (am >= 0)
+      b = -am;
+    ao = am + b;
+    f = ao & 7;
+    if (f == 0)
+      see_me_here();
+    if (ao >= 0)
+      am++;
+    else
+      error();
+  }
+}
+
+int main (void)
+{
+    j++;
+    k++;
+    i++;
+    g++;
+    h++;
+    e = 1;
+    a();
+    return 0;
+}
index 4c9f8853fac407aa3249ed8bd8dc6d386b98bb8a..2140101d7d2c348cf35a744b1a5e5c8f5b1a4908 100644 (file)
@@ -1770,18 +1770,19 @@ extract_range_from_binary_expr (value_range_base *vr,
          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 ();
              return;
            }
 
          /* Adjust the range for possible overflow.  */
-         min = NULL_TREE;
-         max = NULL_TREE;
          set_value_range_with_overflow (type, min, max, expr_type,
                                         wmin, wmax, min_ovf, max_ovf);
          if (type == VR_VARYING)