D79492 improves the materialization of constants for RV64. For ease of review, I'm splitting out several changes and improvements into separate patches.
This patch addresses RV32. For RV32, LUI/ADDI/LUI+ADDI is already optimal regarding the number of instructions, but we can use alternative sequences for improved compressibility.
Since we don't need the recursive approach of D79492, it's clearer and more efficient to split the two implementations.
For ease of review, this patch contributes only the RV32 improvements to constant materialization, with a split implementation approach.
I'm marking this patch/review as WIP due to the following code quality issues.
In isolation, these constant materialization changes should always be reasonable. Unfortunately, when multiple constants need to be materialized these optimizations can result in worse outcomes, due to how we optimize each constant materialization in isolation. For instance:
x = 0x80000000 y = 0x7FFFFFFF Before: x = (LUI 0x80000) y = (ADDI (LUI 0x80000) -1) = (ADDI x -1) => LUI+ADDI After: x = (LUI 0x80000) y = (SRLI (ADDI zero, -1) 1) => LUI+ADDI+SRLI
An example of this scenario occurs in copysign-casts.ll.
Another issue is that removing the ADDI from the materialization screws up folding the ADDIs into the load/stores (see fold-addi-loadstore.ll) and the computation of base+offset addresses (see hoist-global-addr-base.ll).
While these issues can be avoided for RV32I, by gating the materialization optimizations to +C, the problem remains for RVC.