Discussion:
[PATCH] Fix PR63445
Richard Biener
2014-10-09 07:58:36 UTC
Permalink
This fixes a bogus strict overflow warning from VRPs
simplify_cond_using_ranges. I believe that when optimizing
equality compares from (T) x != CST to x != (T) CST we do
not have to care about the fact whether the computation of x
possibly overflowed.

Besides that it looks odd that we guard the transform by
overflow infinities / strict-overflow behavior - those
should only guard the warning. Jeff - you added the overflow
checking stuff, can you remember why you did that? (I didn't
adjust those checks to not apply for equality compares with
this patch)

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk
(probably latent on the 4.9 branch but the testcase doesn't fail there).

Thanks,
Richard.

2014-10-08 Richard Biener <***@suse.de>

PR tree-optimization/63445
* tree-vrp.c (simplify_cond_using_ranges): Only warn about
overflow for non-equality compares.

* gcc.dg/Wstrict-overflow-26.c: New testcase.

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c (revision 215917)
+++ gcc/tree-vrp.c (working copy)
@@ -9189,8 +9189,9 @@ simplify_cond_using_ranges (gimple stmt)
/* If the range overflowed and the user has asked for warnings
when strict overflow semantics were used to optimize code,
issue an appropriate warning. */
- if ((is_negative_overflow_infinity (vr->min)
- || is_positive_overflow_infinity (vr->max))
+ if (cond_code != EQ_EXPR && cond_code != NE_EXPR
+ && (is_negative_overflow_infinity (vr->min)
+ || is_positive_overflow_infinity (vr->max))
&& issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_CONDITIONAL))
{
location_t location;
Index: gcc/testsuite/gcc.dg/Wstrict-overflow-26.c
===================================================================
--- gcc/testsuite/gcc.dg/Wstrict-overflow-26.c (revision 0)
+++ gcc/testsuite/gcc.dg/Wstrict-overflow-26.c (working copy)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstrict-overflow" } */
+
+int
+f (int i, int j)
+{
+ unsigned int c = 0;
+ if (i < j)
+ {
+ unsigned int n = j - i;
+ unsigned int i;
+ for (i = 0; i < n; i++) /* { dg-bogus "signed overflow" } */
+ c++;
+ }
+ return c;
+}

Loading...