When adjusting the value range of an induction variable using SCEV, VRP
calls scev_probably_wraps_p() with use_overflow_semantics=true.  This
parameter set to true makes scev_probably_wraps_p() assume that signed
induction variables never wrap, so for these variables it always returns
false (when strict overflow rules are in effect).  This is wrong because
if a signed induction variable really does overflow then we want to give
it an INF(OVF) value range and not the (finite) estimation returned by
SCEV.

While this change shouldn't make a difference in code generation, it
should help improve the coverage of -Wstrict-overflow warnings on
induction variables like in the test case.

OK after bootstrap + regtest on x86_64-unknown-linux-gnu?

gcc/
        * tree-vrp.c (adjust_range_with_scev): Call
        scev_probably_wraps_p with use_overflow_semantics=false.

gcc/testsuite/
        * gcc.dg/Wstrict-overflow-27.c: New test.
---
 gcc/testsuite/gcc.dg/Wstrict-overflow-27.c | 22 ++++++++++++++++++++++
 gcc/tree-vrp.c                             |  2 +-
 2 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wstrict-overflow-27.c

diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-27.c 
b/gcc/testsuite/gcc.dg/Wstrict-overflow-27.c
new file mode 100644
index 0000000..c1f27ab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-27.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
+
+/* Warn about an overflow when folding i < 0.  */
+
+void bar (unsigned *p);
+
+int
+foo (unsigned *p)
+{
+  int i;
+  int sum = 0;
+
+  for (i = 0; i < *p; i++)
+    {
+      if (i < 0) /* { dg-warning "signed overflow" } */
+       sum += 2;
+      bar (p);
+    }
+
+  return sum;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index a75138f..bf9ff61 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4270,7 +4270,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop 
*loop,
       dir == EV_DIR_UNKNOWN
       /* ... or if it may wrap.  */
       || scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
-                               true))
+                               /*use_overflow_semantics=*/false))
     return;
 
   /* We use TYPE_MIN_VALUE and TYPE_MAX_VALUE here instead of
-- 
2.2.0.rc1.23.gf570943

Reply via email to