On 2018-09-04 17:46:29 -0400, Tom Lane wrote: > Andrew Gierth <and...@tao11.riddles.org.uk> writes: > > The reason it behaves oddly is this: on i387 FPU (and NOT on arm32 or on > > 32-bit i386 with a modern architecture specified to the compiler), the > > result of 1e200 * 1e180 is not in fact infinite, because it fits in an > > 80-bit long double. So __builtin_isinf reports that it is finite; but if > > it gets stored to memory as a double (e.g. to pass as a parameter to a > > function), it then becomes infinite. > > Ah-hah. Can we fix it by explicitly casting the argument of isinf > to double?
No, that doesn't work, afaict the cast has vanished long before the optimizer stage. Note that we've previously encountered similar issues on gcc, which is why we've tried to force gcc's hand with -fexcess-precision=standard. The apparent reason this doesn't fail on master is that there check_float8_val() is an inline function, rather than a macro, but the inline function doesn't get inlined (probably due to the number of callsites). As the parameter passing convention doesn't do 80bit FPU registers, the value is infinity by the time it gets to __builtin_isinf(). I think this is pretty clearly a C99 violation by clang (note how gcc automatically enables -fexcess-precision=standard in C99 mode). I'll report something, but I've little hope this getting fixed quickly - and it'll definitely not get fixed for such old clang versions as the OP used. While we obviously could just neuter the isinf() macro hackery in this edge case, my concern is that it seems likely that further such issues are hidden in code that doesn't immediately cause regression test failure. I kinda wonder if we should add -mno-x87 or such in configure when we detect clang, obviously it doesn't deal correctly with this. SSE2 based floating point math is far from new... Or just error out in configure, although that seems a bit harder. I'm now looking at how it comes that clang on linux doesn't default to x87 math, but freebsd does. Greetings, Andres Freund