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] tree-vrp.c: Avoid VR_ANTI_RANGE in certain binary expression. (Take 2)


Hi,

Attached is a revised version of the patch posted at

http://gcc.gnu.org/ml/gcc-patches/2005-06/msg01729.html

This version tries a bit harder not to drop to VR_VARYING right away
when a binary expression involves VR_ANTI_RANGE.  Specifically, We
drop to VR_VARYING only if a binary expression involving VR_ANTI_RANGE
is PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR.  Other cases are left
intact.

The testcase has been updated to cover MINUS_EXPR and unsigned
MULT_EXPR as well as PLUS_EXPR, which was already in the previous
version of the testcase.

Tested on x86_64-pc-linux-gnu.  OK to apply?

Kazu Hirata

2005-06-23  Kazu Hirata  <kazu@codesourcery.com>

	PR tree-optimization/22026
	* tree-vrp.c (extract_range_from_binary_expr): Drop to
	VR_VARYING if a binary expression involving VR_ANTI_RANGE is
	PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR.

2005-06-23  Kazu Hirata  <kazu@codesourcery.com>

	PR tree-optimization/22026
	* gcc.dg/tree-ssa/pr22026.c: New.

Index: tree-vrp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vrp.c,v
retrieving revision 2.32
diff -u -d -p -r2.32 tree-vrp.c
--- tree-vrp.c	21 Jun 2005 18:46:19 -0000	2.32
+++ tree-vrp.c	22 Jun 2005 20:33:01 -0000
@@ -1100,6 +1100,19 @@ extract_range_from_binary_expr (value_ra
 	   || code == MIN_EXPR
 	   || code == MAX_EXPR)
     {
+      /* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
+	 VR_VARYING.  It would take more effort to compute a precise
+	 range for such a case.  For example, if we have op0 == 1 and
+	 op1 == -1 with their ranges both being ~[0,0], we would have
+	 op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
+	 Note that we are guaranteed to have vr0.type == vr1.type at
+	 this point.  */
+      if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
+	{
+	  set_value_range_to_varying (vr);
+	  return;
+	}
+
       /* For operations that make the resulting range directly
 	 proportional to the original ranges, apply the operation to
 	 the same end of each range.  */
@@ -1116,6 +1129,22 @@ extract_range_from_binary_expr (value_ra
       tree val[4];
       size_t i;
 
+      /* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
+	 drop to VR_VARYING.  It would take more effort to compute a
+	 precise range for such a case.  For example, if we have
+	 op0 == 65536 and op1 == 65536 with their ranges both being
+	 ~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
+	 we cannot claim that the product is in ~[0,0].  Note that we
+	 are guaranteed to have vr0.type == vr1.type at this
+	 point.  */
+      if (code == MULT_EXPR
+	  && vr0.type == VR_ANTI_RANGE
+	  && (flag_wrapv || TYPE_UNSIGNED (TREE_TYPE (op0))))
+	{
+	  set_value_range_to_varying (vr);
+	  return;
+	}
+
       /* Multiplications and divisions are a bit tricky to handle,
 	 depending on the mix of signs we have in the two ranges, we
 	 need to operate on different values to get the minimum and
@@ -1181,7 +1210,20 @@ extract_range_from_binary_expr (value_ra
     }
   else if (code == MINUS_EXPR)
     {
+      /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
+	 VR_VARYING.  It would take more effort to compute a precise
+	 range for such a case.  For example, if we have op0 == 1 and
+	 op1 == 1 with their ranges both being ~[0,0], we would have
+	 op0 - op1 == 0, so we cannot claim that the difference is in
+	 ~[0,0].  Note that we are guaranteed to have
+	 vr0.type == vr1.type at this point.  */
+      if (vr0.type == VR_ANTI_RANGE)
+	{
+	  set_value_range_to_varying (vr);
+	  return;
+	}
+
       /* For MINUS_EXPR, apply the operation to the opposite ends of
 	 each range.  */
       min = vrp_int_const_binop (code, vr0.min, vr1.max);
--- /dev/null	2004-06-24 11:05:26.000000000 -0700
+++ testsuite/gcc.dg/tree-ssa/pr22026.c	2005-06-22 10:38:07.000000000 -0700
@@ -0,0 +1,49 @@
+/* PR tree-optimization/22026
+   VRP used think that ~[0,0] + ~[0,0] = ~[0,0], which is wrong.  The
+   same applies to subtraction and unsigned multiplication.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+int
+plus (int x, int y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+        int z = x + y;
+        if (z != 0)
+          return 1;
+      }
+  return 0;
+}
+
+int
+minus (int x, int y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+        int z = x - y;
+        if (z != 0)
+          return 1;
+      }
+  return 0;
+}
+
+int
+mult (unsigned x, unsigned y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+	unsigned z = x * y;
+	if (z != 0)
+	  return 1;
+      }
+  return 0;
+}
+
+/* None of the predicates can be folded in these functions.  */
+/* { dg-final { scan-tree-dump-times "Folding predicate" 0 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */


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