range-op-float: Improve infinity handling in reverse floating-point operations
Fixes incorrect range calculations for reverse floating-point operations involving infinity.
This commit improves the handling of infinity in reverse floating-point operations, addressing miscompilations that occurred with specific range analyses. Previously, ranges like [-inf, -inf] were incorrectly propagated in reverse operations, leading to wrong results when converting between floating-point types. The fix now correctly widens the bounds of infinity ranges by 1 unit in the penultimate representation, ensuring accurate results for conversions and other operations.
In Details
The range-op-float pass performs optimizations based on the possible range of floating-point values. This change corrects the float_widen_lhs_range function when dealing with reverse operations involving infinity. For ranges like [-inf, -inf] or [+inf, +inf], the previous implementation could incorrectly map them. The fix extends the bounds by +/- 1ulp to account for potential rounding or intermediate values, especially when the finite bounds are involved, preventing miscompilations in narrowing or widening casts.
- range-op-float
- A GCC optimization pass that analyzes and manipulates floating-point operations based on the possible range of their operands.
- infinity
- A special floating-point value representing positive or negative infinity, typically resulting from overflow or division by zero.
- ulp
- Unit in the Last Place; represents the smallest possible change in a floating-point number's value. Used here to denote a small increment or decrement near a boundary.
- narrowing cast
- A type conversion from a wider floating-point type (e.g., double) to a narrower one (e.g., float), which may lose precision or change the value.