aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-09-03 09:50:46 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-09-03 09:50:46 +0200
commit3729852e407e5e1c4f1bbacea1b53e61d7609dad (patch)
tree1dcd10f803b96abc9205d08fe36771644ea96fc8
parente4a8d4a7ec496dbd6602e373dcfcb72c25c60f86 (diff)
downloadgcc-3729852e407e5e1c4f1bbacea1b53e61d7609dad.zip
gcc-3729852e407e5e1c4f1bbacea1b53e61d7609dad.tar.gz
gcc-3729852e407e5e1c4f1bbacea1b53e61d7609dad.tar.bz2
re PR tree-optimization/91597 (GCC miscompiles a branch depending on a pointer tag)
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. Co-Authored-By: Richard Biener <rguenther@suse.de> From-SVN: r275330
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr91597.c48
-rw-r--r--gcc/tree-vrp.c4
4 files changed, 63 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a0f917..1d20ffc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2019-09-03 Jakub Jelinek <jakub@redhat.com>
+ Richard Biener <rguenther@suse.de>
+
+ 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 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/91605
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index efb25df..651baeb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-09-03 Jakub Jelinek <jakub@redhat.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91597
+ * gcc.c-torture/execute/pr91597.c: New test.
+
2019-09-03 Alexandre Oliva <oliva@adacore.com>
* gcc.target/i386/20020616-1.c: Preserve full register across
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr91597.c b/gcc/testsuite/gcc.c-torture/execute/pr91597.c
new file mode 100644
index 0000000..6a917cb
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr91597.c
@@ -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;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index bc06480..0a7e7c7 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1741,9 +1741,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_nonzero (expr_type);
- else if (vr0.zero_p () || vr1.zero_p ())
+ if (vr0.zero_p () || vr1.zero_p ())
vr->set_zero (expr_type);
else
vr->set_varying (expr_type);