This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR43000
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 9 Feb 2010 11:15:48 +0100 (CET)
- Subject: [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 */
+ }
+ }
+