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.

Reply via email to