Sometimes, the constant folding pass creates a large constant from smaller constants, even though the smaller constant is used multiple times and hence can benefit from materializing the constant once and reusing that for multiple operations instead of creating a new large constant and trying to materialize both the constants into two registers.
The simple test case is as follows:
int test(int A, int B) {
int t = A * B >> 8; return ((t <= 4096) ? t : 4096);
}
Here, the right shift by 8 is folded into the 4096 for the compare. Thus the generated code materializes both 4096 as well as 4096 << 8.
We add a new pass to analyze the number of times a given constant is used. If a constant is used more than once, we prevent folding on that constant as it is better to materialize it once and reuse.