ivopts: Fix loop bound calculation when counter wraps
Corrects loop invariant code motion to handle counter wrap-around during increment.
This commit fixes a bug in the loop invariant code motion pass (ivopts) that miscalculated loop bounds when the loop counter wraps around during its first increment. Previously, the calculation assumed non-wrapping behavior, leading to incorrect iteration counts and potentially premature loop termination. The fix adjusts the bound calculation to consider a + 1 and b + 1 instead of a and b, ensuring correct behavior even when the counter reaches its maximum value and wraps to zero.
In Details
The iv_elimination_compare_lt pass incorrectly computed loop bounds when the loop counter i (initialized to a) could wrap around its type before reaching the loop bound b. The previous fix for PR113703 prevented deriving bounds from the iteration count b - a when a + 1 > b, but failed when a was MAX_INT and a + 1 became 0. This commit modifies the bound calculation to use a + 1 and b + 1, converting them to OFF_TYPE and ensuring they are non-negative and do not overflow, thereby correctly handling wrap-around cases.
- ivopts
- Short for 'invariant code motion', a compiler optimization pass that moves loop-invariant computations outside the loop to reduce redundant calculations.
- loop counter wrap-around
- Occurs when an arithmetic counter in a loop increments beyond its maximum representable value, typically resetting to zero or a minimum value, depending on the type.
- loop bound
- The condition that determines when a loop should terminate, often based on a counter variable reaching a specific value.
- OFF_TYPE
- GCC's internal type used for offset calculations within the loop optimization passes, typically a sufficiently large integer type.