From 330af32c066a204be770dd623f9fe605262d58ac Mon Sep 17 00:00:00 2001
From: Jie Zhang <jie@codesourcery.com>
Date: Mon, 26 Apr 2010 10:59:34 +0000
Subject: [PATCH] re PR tree-optimization/43833 (false warning: array subscript
 is above array bounds with -O3)

	PR tree-optimization/43833
	* tree-vrp.c (range_int_cst_p): New.
	(range_int_cst_singleton_p): New.
	(extract_range_from_binary_expr): Optimize BIT_AND_EXPR case
	when both operands are constants.  Use range_int_cst_p in
	BIT_IOR_EXPR case.

	testsuite/
	PR tree-optimization/43833
	gcc.dg/Warray-bounds-8.c: New test case.

From-SVN: r158727
---
 gcc/ChangeLog                          |  9 +++++
 gcc/testsuite/ChangeLog                |  5 +++
 gcc/testsuite/gcc.dg/Warray-bounds-8.c | 20 +++++++++++
 gcc/tree-vrp.c                         | 48 ++++++++++++++++++--------
 4 files changed, 67 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-8.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d7d66931cd1..77d63554876f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-26  Jie Zhang  <jie@codesourcery.com>
+
+	PR tree-optimization/43833
+	* tree-vrp.c (range_int_cst_p): New.
+	(range_int_cst_singleton_p): New.
+	(extract_range_from_binary_expr): Optimize BIT_AND_EXPR case
+	when both operands are constants.  Use range_int_cst_p in
+	BIT_IOR_EXPR case.
+
 2010-04-26  Jan Hubicka  <jh@suse.cz>
 
 	* cgraphunit.c (cgraph_copy_node_for_versioning): Fix profile updating.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0524b7cffd25..9f470ca7d8cb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-26  Jie Zhang  <jie@codesourcery.com>
+
+	PR tree-optimization/43833
+	gcc.dg/Warray-bounds-8.c: New test case.
+
 2010-04-26  Richard Guenther  <rguenther@suse.de>
 
 	PR lto/43080
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-8.c b/gcc/testsuite/gcc.dg/Warray-bounds-8.c
new file mode 100644
index 000000000000..85839f3f07ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-8.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -Wall" } */
+/* based on PR 43833 */
+
+extern unsigned char data[5];
+
+unsigned char
+foo (char *str)
+{
+  int i, j;
+  unsigned char c = 0;
+
+  for (i = 0; i < 8; i++)
+    {
+      j = i * 5;
+      if ((j % 8) > 3)
+	c |= data[(j / 8) + 1];
+    }
+  return c;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b23132ca0439..d8ebbe8f369b 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -764,6 +764,27 @@ range_is_null (value_range_t *vr)
 	 && integer_zerop (vr->max);
 }
 
+/* Return true if max and min of VR are INTEGER_CST.  It's not necessary
+   a singleton.  */
+
+static inline bool
+range_int_cst_p (value_range_t *vr)
+{
+  return (vr->type == VR_RANGE
+	  && TREE_CODE (vr->max) == INTEGER_CST
+	  && TREE_CODE (vr->min) == INTEGER_CST
+	  && !TREE_OVERFLOW (vr->max)
+	  && !TREE_OVERFLOW (vr->min));
+}
+
+/* Return true if VR is a INTEGER_CST singleton.  */
+
+static inline bool
+range_int_cst_singleton_p (value_range_t *vr)
+{
+  return (range_int_cst_p (vr)
+	  && tree_int_cst_equal (vr->min, vr->max));
+}
 
 /* Return true if value range VR involves at least one symbol.  */
 
@@ -2498,19 +2519,20 @@ extract_range_from_binary_expr (value_range_t *vr,
     }
   else if (code == BIT_AND_EXPR)
     {
-      if (vr0.type == VR_RANGE
-	  && vr0.min == vr0.max
-	  && TREE_CODE (vr0.max) == INTEGER_CST
-	  && !TREE_OVERFLOW (vr0.max)
-	  && tree_int_cst_sgn (vr0.max) >= 0)
+      bool vr0_int_cst_singleton_p, vr1_int_cst_singleton_p;
+
+      vr0_int_cst_singleton_p = range_int_cst_singleton_p (&vr0);
+      vr1_int_cst_singleton_p = range_int_cst_singleton_p (&vr1);
+
+      if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p)
+	min = max = int_const_binop (code, vr0.max, vr1.max, 0);
+      else if (vr0_int_cst_singleton_p
+	       && tree_int_cst_sgn (vr0.max) >= 0)
 	{
 	  min = build_int_cst (expr_type, 0);
 	  max = vr0.max;
 	}
-      else if (vr1.type == VR_RANGE
-	       && vr1.min == vr1.max
-	       && TREE_CODE (vr1.max) == INTEGER_CST
-	       && !TREE_OVERFLOW (vr1.max)
+      else if (vr1_int_cst_singleton_p
 	       && tree_int_cst_sgn (vr1.max) >= 0)
 	{
 	  type = VR_RANGE;
@@ -2525,12 +2547,8 @@ extract_range_from_binary_expr (value_range_t *vr,
     }
   else if (code == BIT_IOR_EXPR)
     {
-      if (vr0.type == VR_RANGE
-          && vr1.type == VR_RANGE
-	  && TREE_CODE (vr0.min) == INTEGER_CST
-	  && TREE_CODE (vr1.min) == INTEGER_CST
-	  && TREE_CODE (vr0.max) == INTEGER_CST
-	  && TREE_CODE (vr1.max) == INTEGER_CST
+      if (range_int_cst_p (&vr0)
+	  && range_int_cst_p (&vr1)
 	  && tree_int_cst_sgn (vr0.min) >= 0
 	  && tree_int_cst_sgn (vr1.min) >= 0)
 	{
-- 
GitLab