https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111694
--- Comment #4 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Richard Biener from comment #3) > Looks like some frange / relation mistake then. l_3(D) [frange] double [-Inf, +Inf] Equivalence set : [l_3(D), r_4(D)] <bb 3> : _1 = __builtin_signbit (l_3(D)); if (_1 != 0) goto <bb 6>; [INV] else goto <bb 4>; [INV] 3->6 (T) _1 : [irange] int [-INF, -1][1, +INF] 3->6 (T) l_3(D) : [frange] double [-Inf, -0.0 (-0x0.0p+0)] 3->4 (F) _1 : [irange] int [0, 0] 3->4 (F) l_3(D) : [frange] double [0.0 (0x0.0p+0), +Inf] <bb 4> : _2 = __builtin_signbit (r_4(D)); Yeah, we know l_3 and r_4 are equivalent, and we also know that on the edge 3->4 l_3 has the range double [0.0 (0x0.0p+0), +Inf] When we miss is that with an equivalence, we also have to put -0.0 back into the range. We currently don't so we think we can fold the second signbit call. If I fix that, we then see r_4(D) [frange] double [-0.0 (-0x0.0p+0), +Inf] which prevents the folding. I need to audit to see if there are other places where we may have to "adjust" equivalence range, or how best to deal with this in the general case.