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 PR43000


This fixes PR43000, when introducing -[Wf]strict-overflow Ian changed
manual overflow handling in VRPs vrp_int_const_binop to be considered
when TYPE_OVERFLOW_WRAPS, but the check in question assumes it only
needs to deal with unsigned arithmetic.  Oops.  In fact int_const_binop
handles signed overflow correct, independent of -fwrapv.  Thus the
simple fix is to revert Ians change.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk
(the issue is latent on the branches, but as the bug only results in
more TREE_OVERFLOW set (really?), it should be safe as on the branches
we punt in that cases).

Richard.

2010-02-09  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43000
	* tree-vrp.c (vrp_int_const_binop): Only handle unsigned
	arithmetic manually.

	* gcc.dg/torture/pr43000.c: New testcase.
	* gcc.dg/torture/pr43002.c: Likewise.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 156601)
--- gcc/tree-vrp.c	(working copy)
*************** vrp_int_const_binop (enum tree_code code
*** 1898,1906 ****
  
    res = int_const_binop (code, val1, val2, 0);
  
!   /* If we are not using wrapping arithmetic, operate symbolically
!      on -INF and +INF.  */
!   if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
      {
        int checkz = compare_values (res, val1);
        bool overflow = false;
--- 1898,1906 ----
  
    res = int_const_binop (code, val1, val2, 0);
  
!   /* If we are using unsigned arithmetic, operate symbolically
!      on -INF and +INF as int_const_binop only handles signed overflow.  */
!   if (TYPE_UNSIGNED (TREE_TYPE (val1)))
      {
        int checkz = compare_values (res, val1);
        bool overflow = false;
Index: gcc/testsuite/gcc.dg/torture/pr43000.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr43000.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr43000.c	(revision 0)
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do run } */
+ /* { dg-options "-fwrapv" } */
+ 
+ int __attribute__((noinline))
+ foo (long i, long j)
+ {
+   if (i >= 1)
+     if (j > -(long)(((unsigned long)(long)-1)>>1))
+       {
+         long x;
+ 	j--;
+ 	x = i + j;
+ 	if (x >= 0)
+ 	  return 1;
+       }
+   return 0;
+ }
+ extern void abort (void);
+ int main()
+ {
+   if (foo (1, 1) != 1)
+     abort ();
+   return 0;
+ }
Index: gcc/testsuite/gcc.dg/torture/pr43002.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr43002.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr43002.c	(revision 0)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ /* { dg-options "-Wall -fwrapv" } */
+ 
+ long A[4], B[100];
+ 
+ void foo(void)
+ {
+   int i, j, k = 3;
+   while (A[k] && k > 0) k--; /* k = {0, 1, 2, 3} */
+   for (i = 3 - k; i >= 0; i--) /* i = {0..3-k} */
+     for (j = 0; j <= k; j++) { /* line 8; j = {0..k} */
+ 	B[i + j] = 0; /* line 9; i + j = {0..3-k+k} = {0..3} */
+ 	for (j = 0; j <= k; j++); /* only one iteration is done, with j == 0 */
+     }
+ }
+ 


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