https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121906

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-15 branch has been updated by Xi Ruoyao <xry...@gcc.gnu.org>:

https://gcc.gnu.org/g:4dd2885905afde80da0498f381b0818b05bc9844

commit r15-10325-g4dd2885905afde80da0498f381b0818b05bc9844
Author: Xi Ruoyao <xry...@xry111.site>
Date:   Fri Sep 12 15:57:08 2025 +0800

    LoongArch: Fix wrong code from bstrpick split

    After late-combine is added, split1 can see an input like

        (insn 56 55 169 5
          (set (reg/v:DI 87 [ n ])
            (ior:DI (and:DI (reg/v:DI 87 [ n ])
                            (const_int 281474976710655 [0xffffffffffff]))
                    (and:DI (reg:DI 131 [ _45 ])
                            (const_int -281474976710656
[0xffff000000000000]))))
          "pr121906.c":22:8 108 {*bstrins_di_for_ior_mask}
          (nil))

    And the splitter ends up emitting

        (insn 184 55 185 5
          (set (reg/v:DI 87 [ n ])
               (reg:DI 131 [ _45 ]))
          "pr121906.c":22:8 -1
          (nil))
        (insn 185 184 169 5
          (set (zero_extract:DI (reg/v:DI 87 [ n ])
                                (const_int 48 [0x30])
                                (const_int 0 [0]))
               (reg/v:DI 87 [ n ]))
          "pr121906.c":22:8 -1
          (nil))

    which obviously lost everything in r87, instead of retaining its lower
    bits as we expect.  It's because the splitter didn't anticipate the
    output register may be one of the input registers.

            PR target/121906

    gcc/

            * config/loongarch/loongarch.md (*bstrins_<mode>_for_ior_mask):
            Always create a new pseudo for the input register of the bstrins
            instruction.

    gcc/testsuite/

            * gcc.target/loongarch/pr121906.c: New test.

    (cherry picked from commit 290851e63a5b99c99eb196f2823ea3051c0f0214)

Reply via email to