http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57371

--- Comment #1 from joseph at codesourcery dot com <joseph at codesourcery dot 
com> ---
On Wed, 22 May 2013, glisse at gcc dot gnu.org wrote:

> int f(int i){
>   return (double)i != 0;
> }
> 
> compiled with -Ofast (I don't think -ffast-math matters) keeps the conversion
> to double. I think returning i != 0 is always valid. I didn't think long about
> the exact set of circumstances where it is ok.

For general integer and floating-point types, the issues that could arise 
are:

* If not all values of the integer type can be represented in the 
floating-point type exactly, then the change to an integer comparison 
would lose an "inexact" exception, so not be appropriate with 
-ftrapping-math (strictly interpreted; GCC may not follow that 
consistently).  For example, for int converted to float or long long 
converted to double.

* If values of the integer type can overflow the floating-point type on 
conversion, you'd also lose an "overflow" exception.  For example, 
unsigned __int128 converted to float.

The numerical result of the comparison should always be unchanged; it's 
just about exceptions.  More care in that regard is needed if you're 
comparing against something other than 0.  If the comparison is against an 
integer value, and the integer value in question, say +/-N, is such that 
all +/-M with the same sign and 0 <= M <= N + 1 can be exactly represented 
in the floating-point type, then I think the value will be OK for all 
comparisons.  (So for conversions to float, the value, ignoring 
exceptions, will be correct for comparisons with 0xffffff, but not for 
comparisons with 0x1000000 because 0x1000001 isn't representable.)  If the 
comparison is against a noninteger floating-point value inside the 
representable range of integers, the value could be adjusted to convert it 
to an equivalent integer comparison.  And if it's against a floating-point 
value outside the range of values to which integers of the given type 
could be converted (e.g. comparing the conversion of an int to float with 
something strictly bigger than 0x1p31f) then if ignoring exceptions it 
could be folded to 0 or 1 as appropriate (keeping any side-effects of the 
integer expression, of course).

Reply via email to