On Fri, Nov 21, 2014 at 12:29 PM, Patrick Palka <patr...@parcs.ath.cx> wrote:
> 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?

Hmm, I don't think the change won't affect code-generation.  In fact
we check for overflow ourselves in the most interesting case
(the first block) - only the path adjusting min/max based on the
init value and the max value of the type needs to know whether
overflow may happen and fail or drop to +-INF(OVF).

So I'd rather open-code the relevant cases and not call
scev_probably_wraps_p at all.

Richard.

> 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