https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115921
--- Comment #10 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Xi Ruoyao <xry...@gcc.gnu.org>: https://gcc.gnu.org/g:10e98638998745ebc3888a20e661a8364e88ea3a commit r15-7062-g10e98638998745ebc3888a20e661a8364e88ea3a Author: Xi Ruoyao <xry...@xry111.site> Date: Tue Jan 14 17:26:04 2025 +0800 LoongArch: Improve reassociation for bitwise operation and left shift [PR 115921] For things like (x | 0x101) << 11 It's obvious to write: ori $r4,$r4,257 slli.d $r4,$r4,11 But we are actually generating something insane: lu12i.w $r12,524288>>12 # 0x80000 ori $r12,$r12,2048 slli.d $r4,$r4,11 or $r4,$r4,$r12 jr $r1 It's because the target-independent canonicalization was written before we have all the RISC targets where loading an immediate may need multiple instructions. So for these targets we need to handle this in the target code. We do the reassociation on our own (i.e. reverting the target-independent reassociation) if "(reg [&|^] mask) << shamt" does not need to load mask into an register, and either: - (mask << shamt) needs to be loaded into an register, or - shamt is a const_immalsl_operand, so the outer shift may be further combined with an add. gcc/ChangeLog: PR target/115921 * config/loongarch/loongarch-protos.h (loongarch_reassoc_shift_bitwise): New function prototype. * config/loongarch/loongarch.cc (loongarch_reassoc_shift_bitwise): Implement. * config/loongarch/loongarch.md (*alslsi3_extend_subreg): New define_insn_and_split. (<any_bitwise:optab>_shift_reverse<X:mode>): New define_insn_and_split. (<any_bitwise:optab>_alsl_reversesi_extended): New define_insn_and_split. (zero_extend_ashift): Remove as it's just a special case of and_shift_reversedi, and it does not make too much sense to write "alsl.d rd,rs,r0,shamt" instead of "slli.d rd,rs,shamt". (bstrpick_alsl_paired): Remove as it is already done by splitting and_shift_reversedi into and + ashift first, then late combining the ashift and a further add. gcc/testsuite/ChangeLog: PR target/115921 * gcc.target/loongarch/bstrpick_alsl_paired.c (scan-rtl-dump): Scan for and_shift_reversedi instead of the removed bstrpick_alsl_paired. * gcc.target/loongarch/bitwise-shift-reassoc.c: New test.