On Mon, Sep 19, 2022 at 10:14 AM Richard Biener wrote: > > On Mon, Sep 19, 2022 at 9:59 AM Aldy Hernandez wrote: > > > > ISTM that a specifically nonnegative range should not contain -NAN, > > otherwise signbit_p() would return false, because we'd be unsure of the > > sign. > > > > Do y'all agree? > > what tree_expr_nonnegative_p actually means isn't 100% clear. For REAL_CST > it actually looks at the sign-bit but we have > > (simplify > /* copysign(x,y) -> fabs(x) if y is nonnegative. */ > (COPYSIGN_ALL @0 tree_expr_nonnegative_p@1) > (abs @0)) > > is abs (@0) OK for sNaNs and -NaN/+NaN? At least for real_value's, ABS_EXPR works on NAN's. There's no special code dealing with them. We just clear the sign bit: real_arithmetic: case ABS_EXPR: *r = *op0; r->sign = 0; break; > > And we have > > /* Convert abs[u] (X) where X is nonnegative -> (X). */ > (simplify > (abs tree_expr_nonnegative_p@0) > @0) > > where at least sNaN -> qNaN would be dropped? > > And of course > > (simplify > /* signbit(x) -> 0 if x is nonnegative. */ > (SIGNBIT tree_expr_nonnegative_p@0) > { integer_zero_node; }) > > that is, is tree_expr_nonnegative_p actually tree_expr_sign or > does tree_expr_nonnegative (x) mean x >= (typeof(X)) 0 > or !(x < (typeof(X))0)? I have no idea, but I'm happy to have frange::set_nonnegative() do whatever you agree on. Actually TBH, ranger only uses set_nonnegative for call's, not much else: if (range_of_builtin_call (r, call, src)) ; else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p)) r.set_nonnegative (type); else if (gimple_call_nonnull_result_p (call) || gimple_call_nonnull_arg (call)) r.set_nonzero (type); else r.set_varying (type); but I guess it's good we do the right thing for correctness sake, and if it ever gets used by someone else. > > That said, 'set_nonnegative' could be interpreted to be without > NaNs? Sounds good to me. How's this? Aldy