Fix loop unroller epilogue bound when control IV wraps.
Corrects loop unroller's epilogue iteration count when the loop control variable wraps around.
This commit fixes a bug in GCC’s loop unrolling optimization where the epilogue loop’s iteration bound was incorrectly calculated when the loop’s control variable wraps. Previously, the unroller assumed the main loop consumed all but fewer than FACTOR iterations. However, when the control IV wraps, this assumption breaks, leading to miscompilation. The fix ensures the epilogue bound is only set when the exit test is not a NE_EXPR or when the control IV is known not to wrap, otherwise inheriting the original loop’s bound.
In Details
The tree_transform_and_unroll_loop function in tree-ssa-loop-manip.cc incorrectly set the epilogue loop's nb_iterations_upper_bound and scaled its profile. This was based on the assumption that the main unrolled loop consumed all but fewer than FACTOR iterations. However, determine_exit_conditions can rewrite exit tests into comparisons of the control IV, which is only valid if the IV does not wrap. When the IV wraps (e.g., with unsigned types and decrements), this leads to incorrect folding of ENTER_MAIN_COND and subsequent miscompilation, as demonstrated in the test case. The fi…
- Loop unrolling
- An optimization technique that replicates the body of a loop multiple times to reduce loop overhead and expose more opportunities for instruction-level parallelism.
- Epilogue loop
- In loop unrolling, a smaller loop that executes any remaining iterations after the main, unrolled portion of the loop.
- Control IV
- The induction variable of a loop, which is typically incremented or decremented in each iteration to control loop termination.
- NE_EXPR
- An expression representing a 'not equal' comparison, often used as a loop termination condition.
- LT_EXPR / GT_EXPR
- Expressions representing 'less than' and 'greater than' comparisons, respectively, often used to represent loop termination conditions based on an induction variable.
- TREE-SSA
- Static Single Assignment form. A representation of code used in compilers that simplifies certain optimizations by ensuring each variable is assigned a value only once.