On Thu, 26 Feb 2009, Joseph S. Myers wrote:

> On Thu, 26 Feb 2009, Richard Guenther wrote:
> 
> > As a start there will be no-overflow variants of NEGATE_EXPR,
> > PLUS_EXPR, MINUS_EXPR, MULT_EXPR and POINTER_PLUS_EXPR.
> 
> So you would have both wrapping and no-overflow versions of these codes 
> (with it of course always being valid for a transformation to convert the 
> no-overflow version into a wrapping one if in a particular case that is 
> beneficial), and the gimplification process would select which codes to 
> use based on the -fwrapv setting?

Yes, there is a wrapping and a no-overflow variant (though the
no-overflow variant also wraps if it overflows - indeed, this is
so that existing build2 calls for example for PLUS_EXPR are
always valid).  I am thinking of not selecting the codes during
gimplification but instead force the frontends to choose whatever
they think match their semantics.

> Whereas trapping versions (any 
> reimplementation of -ftrapv) would be expected to be implemented at 
> gimplification time or before with explicit checks in GIMPLE rather than 
> further variant codes?

Yes.  I was thinking about overloading the no-overflow variants
for floating-point types to mean non-trapping, non-inf, non-nan
(thus a "fast-math" operation).  But that's for future thoughts.

> (RTL has only the overflow-wraps operation variants, as well as having 
> signed/unsigned operations where necessary instead of signed/unsigned 
> types.  (It has overflow-traps versions as well in the present -ftrapv 
> implementation.)

Yes, I am aware of that.

> If anyone were to wish to make -fwrapv get INT_MIN / -1 and INT_MIN % -1 
> right (see the discussions in PR 30484), where would this fit in this 
> scheme?  Different operations for division and modulo operations according 
> to whether these cases are defined, and a lowering stage carried out on 
> GIMPLE at some point to convert the versions where they are defined to the 
> versions where they aren't (inserting explicit checks for -1) if the 
> underlying target instructions do not make these operations defined?  
> (Both variants would embed an assumption that you are not dividing by 
> integer 0.)

The canonical way would be to have TRUNC_DIV_EXPR insert proper checks
at expansion time and TRUNC_DIVV_EXPR assume that the dividend isn't
INT_MIN at the same time as the divisor is -1 (I wonder if the
same implementation problem may exist for negating INT_MIN?  Or does
all hardware get this right?).

There is of course the question on whether we want to pay the
penalty of expanding TRUNC_DIV_EXPR "correct" or not.  I support the
idea of a separate target flag for this.

Note that I think this issue perfectly fits in the wrapping / no-overflow
scheme, just it isn't automagically solved ;)  (but we can use
value-range analysis to optimize the cases where we know we don't need
the checks).

> Making these semantics explicit in the IL instead of in global flags is of 
> course a good thing.

It's even needed for cross-language (and cross-TU) LTO.  I also think
it will end up creating more optimization opportunities rather than
less.

As with the first answer I hope that I get help from the frontend
maintainers properly emitting the no-overflow variants where they
think their language allows it.

Thanks,
Richard.

Reply via email to