https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107972
--- Comment #5 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Jakub Jelinek from comment #3) > The backwards propagation fixed, but neither: <...> > avoids the 4.2e+1 cases in the output, because in neither case we properly > determine the ranges of res (that it is in foo/bar/baz/qux > [-DBL_MAX,DBL_MAX]). > For quux I think we don't have a way to represent that right now, we'd need > a union of 2 ranges and after all, we also flush denormals to zero, so I > think we'd need if (!(res < 1.0)) __builtin_unreachable (); or > __attribute__((assume (res < 1.0))); so that we get [1.0, +INF] non-NAN > range. > Aldy/Andrew, any ideas what's going on? Relooking at this, I am confused a bit. First, how can we remove the 42.0 from the output? I see no reason the caller can't pass a NAN in for a or b, and then the first if will trigger and return 42? Sure, once we get to the calculation of res and know its not a NAN, we also know the first if wasn't necessary, but thats only true if we actually get past that first If...? Second, we do actually know res is is that range on the outgoing edge if the if.. ie for quux: res_8 = a_7(D) / b_6(D); _2 = res_8 unord res_8; _3 = res_8 == 0.0; _4 = _2 | _3; if (_4 != 0) goto <bb 5>; [INV] else goto <bb 6>; [INV] 4->5 (T) _4 : [irange] _Bool [1, 1] 4->5 (T) b_6(D) : [frange] double [-1.79769313486231570814527423731704356798070567525844996599e+308 (-0x0.fffffffffffff8p+1024), 1.79769313486231570814527423731704356798070567525844996599e+308 (0x0.fffffffffffff8p+1024)] 4->5 (T) res_8 : [frange] double [-0.0 (-0x0.0p+0), 0.0 (0x0.0p+0)] +-NAN 4->6 (F) _2 : [irange] _Bool [0, 0] NONZERO 0x0 4->6 (F) _3 : [irange] _Bool [0, 0] NONZERO 0x0 4->6 (F) _4 : [irange] _Bool [0, 0] NONZERO 0x0 4->6 (F) b_6(D) : [frange] double [-1.79769313486231570814527423731704356798070567525844996599e+308 (-0x0.fffffffffffff8p+1024), 1.79769313486231570814527423731704356798070567525844996599e+308 (0x0.fffffffffffff8p+1024)] 4->6 (F) a_7(D) : [frange] double [-Inf, +Inf] 4->6 (F) res_8 : [frange] double [-Inf, +Inf] We know on the edge 4->6 res_8 can't be a NAN (I think we have no way to also represent ~0.0 right now, true) We don't set the global that way due to some restrictions of the way we currently remove unreachable(). there are 2 uses of res_8 in the expressions in that block which ranger is currently not comfortable propagating the [-Inf, +Inf] into since they precede the condition itself... it currently only deals with this situation if there is ONE use in a condtion. Since this has 2, it gives up on this release. On the reachable edge leading to the return, in each of the 4 cases we know res is not a NAN. we just dont reflect it in the global always. Next release I plan to revamp the unreachable stuff... again. so many nooks and crannies :-)