This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR tree-optimization/43833
- From: Jie Zhang <jie at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 21 Apr 2010 22:46:13 +0800
- Subject: [PATCH] PR tree-optimization/43833
When debugging this PR, I found VRP dump contained this:
Found new range for j_99: [35, 35]
Visiting statement:
D.2725_100 = j_99 & 7;
Found new range for D.2725_100: [0, 35]
But its range should be [3, 3]. Thus when we came to
Visiting statement:
if (D.2725_100 > 3)
Visiting conditional with predicate: if (D.2725_100 > 3)
With known ranges
D.2725_100: [0, 35]
Predicate evaluates to: DON'T KNOW
It should actually be evaluated to false, which would prevent GCC
issuing the "array subscript is above array bounds" warning in the
resulted dead code.
This patch fixes the range calculation for this case.
Bootstrapped and regtested on x86_64-pc-linux-gnu. Is it OK?
--
Jie Zhang
CodeSourcery
(650) 331-3385 x735
PR tree-optimization/43833
* tree-vrp.c (extract_range_from_binary_expr): Optimize
BIT_AND_EXPR case when both operands are constants.
testsuite/
PR tree-optimization/43833
gcc.dg/Warray-bounds-8.c: New test case.
Index: tree-vrp.c
===================================================================
--- tree-vrp.c (revision 158589)
+++ tree-vrp.c (working copy)
@@ -2498,19 +2498,34 @@ extract_range_from_binary_expr (value_ra
}
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_constant_p, vr1_constant_p;
+
+ vr0_constant_p = (vr0.type == VR_RANGE
+ && vr0.min == vr0.max
+ && TREE_CODE (vr0.max) == INTEGER_CST
+ && !TREE_OVERFLOW (vr0.max));
+ vr1_constant_p = (vr1.type == VR_RANGE
+ && vr1.min == vr1.max
+ && TREE_CODE (vr1.max) == INTEGER_CST
+ && !TREE_OVERFLOW (vr1.max));
+
+ if (vr0_constant_p && vr1_constant_p)
+ {
+ double_int vr0_max = tree_to_double_int (vr0.max);
+ double_int vr1_max = tree_to_double_int (vr1.max);
+ double_int and_max;
+
+ and_max.low = vr0_max.low & vr1_max.low;
+ and_max.high = vr0_max.high & vr1_max.high;
+ min = max = double_int_to_tree (expr_type, and_max);
+ }
+ else if (vr0_constant_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_constant_p
&& tree_int_cst_sgn (vr1.max) >= 0)
{
type = VR_RANGE;
Index: testsuite/gcc.dg/Warray-bounds-8.c
===================================================================
--- testsuite/gcc.dg/Warray-bounds-8.c (revision 0)
+++ testsuite/gcc.dg/Warray-bounds-8.c (revision 0)
@@ -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;
+}