3 ms·
This seems like a property of the Intel 8087 math coprocessor and its distant descendants found in x86 chips, not anything to do with gcc?
by wiml 6y ago
This seems like a property of the Intel 8087 math coprocessor and its distant descendants found in x86 chips, not anything to do with gcc?
- bhouston 6y agoBut then why does python and JavaScript on the same machines get it right?
- nitrogen 6y agoUnsure: compiled to use SSE instead of x87 for fpmath?
- stefan_ 6y agoBecause it's now getting exceedingly rare to find a program that was not compiled with at least SSE instructions enabled. So the x87 FPU is simply not used then.
- nwallin 6y agoBecause they're compiled to use SSE instructions instead of x87 FPU instructions. If you are still writing 32 bit x86 C code, it's probably some embedded or legacy CPU, and it's wrong to assume SSE instructions are available. So GCC correctly defaults to using FPU instructions instead of SSE instructions on 32 bit x86. Javascript and python will basically never be run in embedded environments, and their legacy environments probably aren't that legacy that SSE instructions aren't available. So it's reasonable to default to SSE.
- pwdisswordfish2 6y agoPython IIRC stores intermediate results in memory, it doesn't perform long chains of calculations entirely in FPU registers. This ensures the intermediate results are predictably rounded. JavaScript JITs blindly use SSE without checking if it is available. Bytecode interpreters behave the same as above.
- dpwm 6y agoMy understanding is that in this case it's GCC's optimizer evaluating the expression at compile time in a way that gives a different result to if it's done at runtime. EDIT: GCC gets it wrong with -O0 (when it's evaluated at runtime) and right with -O2 (when it evaluates it at compile time) Clang appears to get it right when evaluated at compile time or runtime. Clang uses the divsd instruction; GCC uses the fdiv instruction – so this really is SSE vs x87 FPU.
- nwallin 6y agoclang gets it "right" because it uses the sse divsd instruction to perform the division, gcc gets it "wrong" because it uses the x87 fdiv instruction. You can configure gcc to use sse math with the -mfpmath=sse instruction. The author states that gcc still gets it "wrong" but he simply is not correct. gcc will use divsd and gets 0.501782303180000055. gcc defaults to use the x87 fpu instead of sse because not all 32 bit x86 cpus have SSE instructions. It's a safer default. When compiled in 64 bit mode, it uses up to SSE2 instructions, because all x86_64 CPUs have SSE2. https://godbolt.org/z/3PfKQU https://godbolt.org/z/3PfKQU
- ndesaulniers 6y agoI think `-mno-see -mno-sse2` are of interest here, too.