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

--- Comment #5 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:290851e63a5b99c99eb196f2823ea3051c0f0214

commit r16-3856-g290851e63a5b99c99eb196f2823ea3051c0f0214
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.

Reply via email to