GCC Newspaper
OCTOBER 6, 2026
Date
/
Architectures
Components
Topics
News & Policy
Other
tree-optimization Performance Win

Hoist shifts by in-range constants out of loops

Improves loop optimization by hoisting shifts with constant counts that are provably in range.

This commit corrects a bug in loop optimization where shifts with constant counts were incorrectly restricted from being hoisted out of loops. The movement_possibility_1 logic mistakenly pinned shifts with in-range counts, while shifts with out-of-range counts were incorrectly marked as movable. The fix inverts this logic, allowing shifts with constant counts that are proven to be in range to be hoisted. This can lead to performance improvements by reducing redundant computations within loop bodies, as demonstrated by reductions in loop-invariant code and register pressure on ARM targets.

In Details

The movement_possibility_1 logic in GCC's loop invariant code motion pass was inverted regarding shifts and rotates. It used wi::ltu_p(count, precision) to check if the shift count was within the valid range. The original code restricted shifts when count < precision (i.e., in-range) to MOVE_PRESERVE_EXECUTION, while out-of-range shifts (count >= precision) were incorrectly marked MOVE_POSSIBLE. This was due to a misunderstanding of the PR111000 fix which aimed to prevent hoisting of *undefined* shifts (out-of-range counts). This commit corrects the condition: shifts with in-ran…

For Context
loop optimization
Compiler techniques to improve the performance of code within loops, such as reducing redundant computations or reordering operations.
hoisting
Moving a computation from inside a loop to outside the loop, if the result of the computation is the same on every iteration.
shift operation
A bitwise operation that shifts the bits of a number to the left or right.
constant count
In a shift operation, the number of positions to shift is a fixed value known at compile time.
loop invariant code motion
An optimization that moves computations that produce the same result in every loop iteration from inside the loop to outside.
libcall
A call to a function in a shared or static library, often used when the compiler cannot generate inline code for an operation.
register pressure
A measure of how many registers are needed by the program at a given point; high register pressure can lead to performance degradation as the compiler must spill values to memory.
Filed Under: optimizationloop optimizationshiftsARM