aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJie Zhang <jie@codesourcery.com>2010-04-26 10:59:34 +0000
committerJie Zhang <jiez@gcc.gnu.org>2010-04-26 10:59:34 +0000
commit330af32c066a204be770dd623f9fe605262d58ac (patch)
treece0e499820982aa0f8a5cf58903650b5becea8b2
parentae2b08888a183d94f9a4f898600b347e5e66b29d (diff)
downloadgcc-330af32c066a204be770dd623f9fe605262d58ac.zip
gcc-330af32c066a204be770dd623f9fe605262d58ac.tar.gz
gcc-330af32c066a204be770dd623f9fe605262d58ac.tar.bz2
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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-8.c20
-rw-r--r--gcc/tree-vrp.c48
4 files changed, 67 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d7d669..77d6355 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 0524b7c..9f470ca 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 0000000..85839f3
--- /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 b23132c..d8ebbe8 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)
{