Open llvmbot opened 9 years ago
I have tried this using clang 3.6.0-RC3 and that version gives -0.0083223357032193145, whereas 3.5.1 gave -0.0083223357032193128
This is independent of the employed optimization level (-O0 to -Ofast). I don't know, what has changed, but wanted to share my observation.
Thanks, Chandler!
I think I at least understand the difference in gcc results via: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64677
I'm still not sure which answer (if any) is wrong or how to prove which answer is better.
While I've not looked into this specifically, please note that the C standard provides special rules for the mathematical operations between a real and complex number. Because std::complex is implemented in terms of C _Complex numbers, those rules actually govern how we implement these operations.
I'm not sure that this is relevant here, but it is one of the more subtle aspects of determining what the "correct" result is in the case of mixed real/complex arithmetic.
clang and gcc have the same bit representation for the input values:
clang: movabsq $-4589465388246309647, %rax ## imm = 0xC04EF18BA0A0E4F1 movabsq $-4589723640175316136, %rax ## imm = 0xC04E06AAAA233358
gcc: .long 2694898929 = 0xA0A0E4F1 .long -1068568181 = 0xC04EF18B .long 2854433624 = 0xAA233358 .long -1068628310 = 0xC04E06AA
Interestingly, "gcc -O1" precomputes the "wrong" result. There's no math at all in that binary. Clang apparently doesn't have that optimization because it has to do lots of math ops to arrive at the resulting:
0xbf810b4cfd5f8f56 (-0.0083223357032193128)
The supposedly correct result from gcc -O0 is 1 ULP greater: 0xbf810b4cfd5f8f57 (-0.0083223357032193145)
gcc 4.8.2 returns the "wrong" (not sure yet if it's really wrong or not) output at -O1 too. So either gcc is also doing something wrong (-O1 shouldn't enable any kind of fast-math AFAIK) or something else is wrong here.
NOTE: I messed up leaving e-3 for the first output!
Extended Description
Hi.
Consider the following code:
include
include
include
int main() { std::complex c(-61.887073591767951,-60.052083270252012);
double a = (1.0 / c).real();
}
With g++ and gfortran (with corresponding Fortran code) and Octave (ditto), this outputs:
-8.3223357032193145 (ends with 45)
However, clang++ outputs:
-0.0083223357032193128 (ends with 28)
The thing is, when compiling with g++ -ffast-math, I get the same as I get in clang++ (without any optimization or -ffast-math).
So: "g++ -ffast-math complex.cpp" gives the same output as "clang++ complex.cpp"
I'm on Fedora 21 with clang++ --version:
clang version 3.4.2 (tags/RELEASE_34/dot2-final) Target: x86_64-redhat-linux-gnu Thread model: posix