[patch] Lno branch merge part 8 -- canonical induction variable creation

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Sat Aug 21 22:44:00 GMT 2004


Hello,

> On Sat, 21 Aug 2004, Zdenek Dvorak wrote:
> > > The simplest fix is to add a test for "TYPE_UNSIGNED () || flag_wrapv"
> > > to the problematic transformation in your code.
> >
> > Unfortunately this is not possible since it would totally cripple whole
> > optimization (many of interesting induction variables are signed).
> 
> As it stands your "canonical induction variable creation" patch has failed
> GCC's peer review due to correctness problems that will destabilize the
> compiler.
> 
> The first alternative is to refuse to add the necessary checks, and
> abandon any hope of getting LNO or the vectorizer branches merged into
> mainline CVS.  I think everyone agrees this isn't particularly viable.
> 
> 
> The second and more reasonable alternative is to add these checks to
> your patch, and subsequently change the flag_wrapv default to true.
> 
> Perhaps the only major reason why flag_wrapv isn't currently the default
> for the C family languages, is because the optimizations guarded by
> !flag_wrapv are marginally stronger than those guarded by flag_wrapv.
> 
> If many interesting optimizations in LNO require flag_wrapv, that would
> be a strong argument in favour of shifting the default.  Both Intel's
> and Microsoft's IA-32 compilers assume flag_wrapv by default.
> 
> [Indeed I suspect there are already a number of unsafe transformations
> in GCC that aren't correctly guarded by flag_wrapv, but fixing the code
> would pessimise GCC's code quality until the default was switched].

The reason I don't like setting flag_wrapv on by default is that
loop optimizer (concretely determining number of iterations of a loop)
is one of the places where using the fact that some operations cannot
wrap would be very useful.

There is the third alternative -- to abandon the whole system, for that
you yourself admit that it probably does not work on many places,
and we are not likely to ever be able to get it working.

My proposal is:  Add for each operation flag(s) telling whether it is
1) Wrapping -- i.e. the compiler cannot assume anything about it.
2) Wrap undefined -- i.e. compiler can assume it does not wrap if it
                     wants to.
3) Trapping -- i.e. the compiler not only assumes it does not wrap,
               but also adds check for it.

This allows for greater flexibility, as frontends/optimization that
from some reason know that a particular operation does not wrap can
indicate it, regardless of what it the type of operands.

As long as the "Wrapping" version of operations is produced by default
and the "Trapping" ones are respected, we should also have no problems
with correctness.

The transition should be quite easy -- the flags would be set up
according to flag_frapv/flag_trapv for the beginning, and all
places (about 20) that check for one of these flags would be updated.

Zdenek



More information about the Gcc-patches mailing list