https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108540
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ah, so back_threader::find_taken_edge_cond calls path_range_query::range_of_stmt on the d_1 == 0.0 with the assumption that d_1 is -0.0, fold_using_range::range_of_range_op sees (gdb) p debug (range1) [frange] double [-0.0 (-0x0.0p+0), -0.0 (-0x0.0p+0)] (gdb) p debug (range2) [frange] double [0.0 (0x0.0p+0), 0.0 (0x0.0p+0)] (that is correct) and foperator_equal::fold_range is called on those. There we trigger the 604 // We can be sure the values are always equal or not if both ranges 605 // consist of a single value, and then compare them. 606 else if (op1.singleton_p () && op2.singleton_p ()) 607 { 608 if (op1 == op2) 609 r = range_true (type); 610 else 611 r = range_false (type); 612 } code, which is clearly wrong if both ops are singleton zeros with different sign.