GCC claims to follow C99 Annex F when converting a floating value to an integer
type when the integral part exceeds the range of the integer type (C99 6.3.1.4
and F.4).  Annex F says that in this case the conversion raises the "invalid"
floating-point exception.  On powerpc64-linux and x86_64-linux, however, the
instruction that is used to convert double to int converts to a 64-bit integer,
not a 32-bit register, so the exception is not raised.  On powerpc64-linux with
-m64 the instruction is fctidz (floating convert to integer doubleword with
round toward zero).  If I replace that instruction with fctiwz (convert to
integer word) in the .s file and compile that, the code behaves as expected. 
Here's a small test case:

#include <fenv.h>
extern void abort (void);

double x = 4294967296.0;
unsigned int i;

int
main ()
{
#pragma STDC FENV_ACCESS ON
    feclearexcept (FE_ALL_EXCEPT);
    i = x;    /* value exceeds the range of 32-bit int */
    if (! fetestexcept (FE_INVALID))
        abort ();
    return 0;
}

I see this behavior in all powerpc64-linux compilers I've checked from 3.2
through mainline.  The exception is raised for tests compiled with -m32.

This is a problem for applications that try to detect such invalid conversions
after checking for __STDC_IEC_559__, which claims that the implementation
conforms to Annex F.

A possibly-related issue is that this macro is defined in a header file
provided by glibc, not by GCC.


-- 
           Summary: float to int conversion doesn't raise invalid exception
           Product: gcc
           Version: 4.0.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: janis at gcc dot gnu dot org
GCC target triplet: powerpc64-linux, x86_64-linux


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

Reply via email to