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] Fix missed VRP for unsigned addition


This is a simple but common case where unsigned subtract causes
spurious overflow during range computations.  Fixed by properly
handling the case when both additions overflow.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2009-04-24  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (extract_range_from_binary_expr): Handle overflow
	from unsigned additions.

	* gcc.dg/tree-ssa/vrp48.c: New testcase.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 146590)
--- gcc/tree-vrp.c	(working copy)
*************** extract_range_from_binary_expr (value_ra
*** 2248,2253 ****
--- 2248,2269 ----
  	 the same end of each range.  */
        min = vrp_int_const_binop (code, vr0.min, vr1.min);
        max = vrp_int_const_binop (code, vr0.max, vr1.max);
+ 
+       /* If both additions overflowed the range kind is still correct.
+ 	 This happens regularly with subtracting something in unsigned
+ 	 arithmetic.
+          ???  See PR30318 for all the cases we do not handle.  */
+       if (code == PLUS_EXPR
+ 	  && (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
+ 	  && (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
+ 	{
+ 	  min = build_int_cst_wide (TREE_TYPE (min),
+ 				    TREE_INT_CST_LOW (min),
+ 				    TREE_INT_CST_HIGH (min));
+ 	  max = build_int_cst_wide (TREE_TYPE (max),
+ 				    TREE_INT_CST_LOW (max),
+ 				    TREE_INT_CST_HIGH (max));
+ 	}
      }
    else if (code == MULT_EXPR
  	   || code == TRUNC_DIV_EXPR
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp48.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp48.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp48.c	(revision 0)
***************
*** 0 ****
--- 1,20 ----
+ extern void link_failure (void);
+ 
+ static int __attribute__ ((noinline)) foo (int x)
+ {
+   if (x >= 1)
+     if (x <= 10)
+       {
+ 	if (x < 1 || x > 10)
+ 	  link_failure ();
+ 	x = x + 1;
+       }
+   return x;
+ }
+ 
+ int main (void)
+ {
+   int i = foo (0);
+   return 0;
+ }
+ 


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