https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107591
--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Andrew Macleod from comment #11) > no, I meant in addition to the VREL_EQ. so > if (rel == VREL_EQ && op1_range != op2_range) > then you know you have something like if (x == y) z=x*y and may have > to check for various signed zero cobinations in each range, > whereas is op1_range == op2_range in this case, it should be perfectly safe.. I don't understand. Let's modify the testcase to: float foo (float x, y) { if (x < -13.f || x > 26.f) return -1.0f; if (y < -13.f || y > 26.f) return -1.0f; if (x == y) return x * y; return 42.0f; } I'd expect that fold_range on the x * y should see trio.op1_op2 () == VREL_EQ because of the guarding x == y condition. And the ranges of both are [-13.f, 26.f] +-NAN too. Still, x could be -0.0f and y 0.0f or vice versa, and so x * y could be -0.0f, so we need [-0.f, 676.f] +-NAN. While if it is x * x, we know the result will have always sign bit of 0 (except if NAN), so [0.f, 676.f] +-NAN.