diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a0f9178c8b84fce26514af452151868823dd4f8..1d20ffc9d5ac812e79b87797cce0d2c8ba3b8a7a 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 efb25dff085b48e786a724be3c6ed52bfb8c2706..651baebe5f7a5d834ff00c34f9ecf554983753dc 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 0000000000000000000000000000000000000000..6a917cb58af4e2f96a985cf19dacc1df9faf0910
--- /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 bc0648080db62189d42ee25d56a5cfd9cf80a25a..0a7e7c7609b0eb575a228b3400e70ba4eac7e712 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);