This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Determine more IVs to be non-overflowing
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Richard Biener <rguenther at suse dot de>
- Cc: Jan Hubicka <hubicka at ucw dot cz>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 5 Jul 2016 16:28:05 +0200
- Subject: Re: Determine more IVs to be non-overflowing
- Authentication-results: sourceware.org; auth=none
- References: <20160627140938.GF98078@kam.mff.cuni.cz> <alpine.LSU.2.11.1606290934010.29772@t29.fhfr.qr> <20160629080804.GA12114@kam.mff.cuni.cz> <alpine.LSU.2.11.1606291010410.29772@t29.fhfr.qr> <20160629105100.GA17019@kam.mff.cuni.cz> <20160630130301.GA40315@kam.mff.cuni.cz> <alpine.LSU.2.11.1607011330580.29772@t29.fhfr.qr> <20160703104754.GA83834@kam.mff.cuni.cz> <alpine.LSU.2.11.1607051548350.29772@t29.fhfr.qr>
>
> This can overflow for __uint128_t IV iterating to UINT128_MAX I think
> given widest_int has only precision of TImode on x86_64? An
> after-the-fact check like
>
> if (nit == 0)
> return true;
>
> does the trick I guess.
OK, I suppose we need to review niter and related code for similar overflow possibilities.
This approximation of infinite math precision is bit iffy :))
I wonder if widest int should not trap on overflows with checking enabled.
>
> Otherwise the patch looks ok now - thanks for the extensive comments ;)
Thanks for the patience! :)
Honza
>
> Richard.
>
> > +
> > + /* NIT is typeless and can exceed the precision of the type. In this case
> > + overflow is always possible, because we know STEP is non-zero. */
> > + if (wi::min_precision (nit, UNSIGNED) > TYPE_PRECISION (type))
> > + return true;
> > + wide_int nit2 = wide_int::from (nit, TYPE_PRECISION (type), UNSIGNED);
> > +
> > +
> > + /* If step can be positive, check that nit*step <= type_max-base.
> > + This can be done by unsigned arithmetic and we only need to watch overflow
> > + in the multiplication. The right hand side can always be represented in
> > + the type. */
> > + if (sgn == UNSIGNED || !wi::neg_p (step_max))
> > + {
> > + bool overflow = false;
> > + if (wi::gtu_p (wi::mul (step_max, nit2, UNSIGNED, &overflow),
> > + type_max - base_max)
> > + || overflow)
> > + return true;
> > + }
> > + /* If step can be negative, check that nit*(-step) <= base_min-type_min. */
> > + if (sgn == SIGNED && wi::neg_p (step_min))
> > + {
> > + bool overflow = false, overflow2 = false;
> > + if (wi::gtu_p (wi::mul (wi::neg (step_min, &overflow2),
> > + nit2, UNSIGNED, &overflow),
> > + base_min - type_min)
> > + || overflow || overflow2)
> > + return true;
> > + }
> > +
> > + return false;
> > +}
> > +
> > /* Checks whether use of OP in USE_LOOP behaves as a simple affine iv with
> > respect to WRTO_LOOP and returns its base and step in IV if possible
> > (see analyze_scalar_evolution_in_loop for more details on USE_LOOP
> > @@ -3375,8 +3458,12 @@ simple_iv (struct loop *wrto_loop, struc
> > if (tree_contains_chrecs (iv->base, NULL))
> > return false;
> >
> > - iv->no_overflow = (!folded_casts && ANY_INTEGRAL_TYPE_P (type)
> > - && TYPE_OVERFLOW_UNDEFINED (type));
> > + iv->no_overflow = !folded_casts && nowrap_type_p (type);
> > +
> > + if (!iv->no_overflow
> > + && !iv_can_overflow_p (wrto_loop, type, iv->base, iv->step))
> > + iv->no_overflow = true;
> > +
> >
> > /* Try to simplify iv base:
> >
> > Index: tree-ssa-loop-niter.c
> > ===================================================================
> > --- tree-ssa-loop-niter.c (revision 237908)
> > +++ tree-ssa-loop-niter.c (working copy)
> > @@ -4105,7 +4105,7 @@ n_of_executions_at_most (gimple *stmt,
> > bool
> > nowrap_type_p (tree type)
> > {
> > - if (INTEGRAL_TYPE_P (type)
> > + if (ANY_INTEGRAL_TYPE_P (type)
> > && TYPE_OVERFLOW_UNDEFINED (type))
> > return true;
> >
> >
> >
>
> --
> Richard Biener <rguenther@suse.de>
> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)