diff options
author | Xi Ruoyao <xry111@xry111.site> | 2025-01-14 17:26:04 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@xry111.site> | 2025-01-20 21:27:55 +0800 |
commit | 10e98638998745ebc3888a20e661a8364e88ea3a (patch) | |
tree | adaf5cd6b41ac32997fca6f1c73d465ab77567ba /gcc/fortran/trans-expr.cc | |
parent | f3bedc9a3b8b7dd3911272731a1ea595621e13cd (diff) | |
download | gcc-10e98638998745ebc3888a20e661a8364e88ea3a.zip gcc-10e98638998745ebc3888a20e661a8364e88ea3a.tar.gz gcc-10e98638998745ebc3888a20e661a8364e88ea3a.tar.bz2 |
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.
Diffstat (limited to 'gcc/fortran/trans-expr.cc')
0 files changed, 0 insertions, 0 deletions