This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]