https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85957
Alexander Monakov <amonakov at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Last reconfirmed| |2018-05-29 CC| |amonakov at gcc dot gnu.org Resolution|DUPLICATE |--- Ever confirmed|0 |1 --- Comment #7 from Alexander Monakov <amonakov at gcc dot gnu.org> --- Reopening, the issue here is way more subtle than bug 323 and points to a possible issue in DOM. Hopefully Richi can have a look and comment. It appears dom2 pass performs something like jump threading based on compile-time-evaluated floating-point expression values without also substituting those expressions in IR. At run time, they are evaluated to different values, leading to an inconsistency. Namely, dom2 creates bb 10: <bb 9>: # iftmp.1_1 = PHI <"true"(7), "false"(8), "true"(10)> printf ("(a6 == b6) = %s\n", iftmp.1_1); return 0; <bb 10>: _24 = __n2_13 * 1.0e+6; b6_25 = (guint64) _24; printf ("a6 = %llu\n", 1); printf ("b6 = %llu\n", b6_25); goto <bb 9>; where jump to bb 9 implies that _24 evaluates to 1.0 and b6_25 to 1, but they are not substituted as such, and at run time evaluate to 0.99... and 0 due to excess precision. The following reduced testcase demonstrates the same issue, but requires -fdisable-tree-dom3 (on gcc-6 at least, as otherwise dom3 substitutes results of compile-time evaluation). __attribute__((noinline,noclone)) static double f(void) { return 1e-6; } int main(void) { double a = 1e-6, b = f(); if (a != b) __builtin_printf("uneq"); unsigned long long ia = a * 1e6, ib = b * 1e6; __builtin_printf("%lld %s %lld\n", ia, ia == ib ? "==" : "!=", ib); }