https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107569
--- Comment #24 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #22) > Folding statement: _2 = __builtin_pow (1.0e+1, _1); > Global Exported: _2 = [frange] double [0.0 (0x0.0p+0), +Inf] +NAN > The +NAN looks suspicious, shouldn't that be +-NAN ? > Of course once we handle POW builtins, if we are smart enough we should see > that it is 10.0 ** [INT_MIN, -1] and so [0.0, 1.0e-1] (plus some larger ulp > error because library functions aren't exactly 0.5ulp precise all the time). > But when we don't know what __builtin_pow does (from frange perspective), I > don't see what > tells us that NAN with negative sign can't appear. Yeah, that +NAN looks very suspicious. For that matter, it took me a while to figure out how we know that _2 can't be negative, because we don't have any range-op entries for __builtin_pow. So...here's a trick to figure this out: --param=ranger-debug=tracegori You'll see in the *evrp dump: Folding statement: _2 = __builtin_pow (1.0e+1, _1); 45 range_of_stmt (_2) at stmt _2 = __builtin_pow (1.0e+1, _1); TRUE : (45) range_of_stmt (_2) [frange] double [0.0 (0x0.0p+0), +Inf] +NAN 46 range_of_expr(_1) at stmt _2 = __builtin_pow (1.0e+1, _1); TRUE : (46) range_of_expr (_1) [frange] double VARYING +-NAN 47 range_of_stmt (_2) at stmt _2 = __builtin_pow (1.0e+1, _1); TRUE : (47) cached (_2) [frange] double [0.0 (0x0.0p+0), +Inf] +NAN Global Exported: _2 = [frange] double [0.0 (0x0.0p+0), +Inf] +NAN So ranger was able to figure out immediately that _2 was positive. Andrew added smarts to break into any given place, so we can break where the counter is 45: (gdb) break breakpoint if index == 45 Yes, amazingly there's only one function named breakpoint() in the entire compiler ;-). If you single step from there on, we run into: 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); IIRC, we had some discussion upstream about the meaning of set_nonnegative, and we all agreed that nuking -NAN was the right thing. Neat, huh? :)