]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/91597 (GCC miscompiles a branch depending on a pointer tag)
authorJakub Jelinek <jakub@redhat.com>
Tue, 3 Sep 2019 16:55:31 +0000 (18:55 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 3 Sep 2019 16:55:31 +0000 (18:55 +0200)
PR tree-optimization/91597
* tree-vrp.c (extract_range_from_binary_expr): Remove unsafe
BIT_AND_EXPR optimization for pointers, even if both operand
ranges don't include NULL, the result can be NULL.

* gcc.c-torture/execute/pr91597.c: New test.

From-SVN: r275345

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

index 569691bbb2cd50a1957a2c419cbb6b89582adc20..f362c3634c9ee0c6610a500d514eeb5ed45127cb 100644 (file)
@@ -1,3 +1,10 @@
+2019-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/91597
+       * tree-vrp.c (extract_range_from_binary_expr): Remove unsafe
+       BIT_AND_EXPR optimization for pointers, even if both operand
+       ranges don't include NULL, the result can be NULL.
+
 2019-09-02  Martin Liska  <mliska@suse.cz>
 
        Backport from mainline
index 7069eec2d8548c83fd3208da654b34adbf0d43dc..5b6958ceabd1cba3bd20f1be81b60cbf4991e010 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/91597
+       * gcc.c-torture/execute/pr91597.c: New test.
+
 2019-09-02  Steven G. Kargl  <kargl@gc.gnu.org>
 
        PR fortran/91552
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr91597.c b/gcc/testsuite/gcc.c-torture/execute/pr91597.c
new file mode 100644 (file)
index 0000000..6a917cb
--- /dev/null
@@ -0,0 +1,48 @@
+/* PR tree-optimization/91597 */
+
+enum E { A, B, C };
+struct __attribute__((aligned (4))) S { enum E e; };
+
+enum E
+foo (struct S *o)
+{
+  if (((__UINTPTR_TYPE__) (o) & 1) == 0)
+    return o->e;
+  else
+    return A;
+}
+
+int
+bar (struct S *o)
+{
+  return foo (o) == B || foo (o) == C;
+}
+
+static inline void
+baz (struct S *o, int d)
+{
+  if (__builtin_expect (!bar (o), 0))
+    __builtin_abort ();
+  if (d > 2) return;
+  baz (o, d + 1);
+}
+
+void
+qux (struct S *o)
+{
+  switch (o->e)
+    {
+    case A: return;
+    case B: baz (o, 0); break;
+    case C: baz (o, 0); break;
+    }
+}
+
+struct S s = { C };
+
+int
+main ()
+{
+  qux (&s);
+  return 0;
+}
index 795d7184a65f9afb6782ce1ba7ab26be6ece732a..4c9f8853fac407aa3249ed8bd8dc6d386b98bb8a 100644 (file)
@@ -1702,9 +1702,7 @@ extract_range_from_binary_expr (value_range_base *vr,
        {
          /* For pointer types, we are really only interested in asserting
             whether the expression evaluates to non-NULL.  */
-         if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1))
-           vr->set_nonnull (expr_type);
-         else if (range_is_null (&vr0) || range_is_null (&vr1))
+         if (range_is_null (&vr0) || range_is_null (&vr1))
            vr->set_null (expr_type);
          else
            vr->set_varying ();