diff options
author | Jie Zhang <jie@codesourcery.com> | 2010-04-26 10:59:34 +0000 |
---|---|---|
committer | Jie Zhang <jiez@gcc.gnu.org> | 2010-04-26 10:59:34 +0000 |
commit | 330af32c066a204be770dd623f9fe605262d58ac (patch) | |
tree | ce0e499820982aa0f8a5cf58903650b5becea8b2 | |
parent | ae2b08888a183d94f9a4f898600b347e5e66b29d (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Warray-bounds-8.c | 20 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 48 |
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) { |