https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79117

            Bug ID: 79117
           Summary: __builtin_isfinite edge case incorrect on 32 bit
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jtaylor.debian at googlemail dot com
  Target Milestone: ---

following program (arguably) incorrectly outputs "not finite when compiled:
gcc test.c  -O2 -m32
on gcc 6.3.0


#include <float.h>
#include <stdio.h>
void __attribute__((noinline)) myisfinite(double a, double b)
{
    double c = b - a;
    if (__builtin_isfinite(c)) {
        puts("finite");
    }
    else {
        puts("not finite");
    }
}

int main()
{
    myisfinite(-DBL_MAX, DBL_MAX / 1e18);
}


the reason is that __builtin_isfinite uses abs(x) <= DBL_MAX to determine if it
is finite, but on x87 extended precision DBL_MAX / 1e18 + DBL_MAX is not again
DBL_MAX as on e.g. amd64 but larger than DBL_MAX, so it is not considered
finite.
You can probably argue this is a duplicate of PR323, but I wanted to record it
as e.g. glibc now uses the builtin for isfinite() so you get different
behaviour compared to the function call in older glibc that effectively does
-ffloat-store
Maybe __builtin_isfinite could do this too for consistency?

Reply via email to