https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121906
--- Comment #4 from Xi Ruoyao <xry111 at gcc dot gnu.org> --- (In reply to Xi Ruoyao from comment #3) > Tentative patch: > > diff --git a/gcc/config/loongarch/loongarch.md > b/gcc/config/loongarch/loongarch.md > index 8cf2ac90c64..b9425dcb44e 100644 > --- a/gcc/config/loongarch/loongarch.md > +++ b/gcc/config/loongarch/loongarch.md > @@ -1619,13 +1619,12 @@ (define_insn_and_split "*bstrins_<mode>_for_ior_mask" > operands[2] = GEN_INT (len); > operands[4] = GEN_INT (lo); > > - if (lo) > - { > - rtx tmp = gen_reg_rtx (<MODE>mode); > - emit_move_insn (tmp, gen_rtx_ASHIFTRT(<MODE>mode, operands[3], > - GEN_INT (lo))); > - operands[3] = tmp; > - } > + /* Use a new pseudo register even if lo == 0 or we'll wreck havoc > + when operands[0] is same as operands[3]. See PR 121906. */ > + rtx tmp = gen_reg_rtx (<MODE>mode); > + rtx val = lo ? gen_rtx_ASHIFTRT (<MODE>mode, operands[3], GEN_INT (lo)) > + : operands[3]; > + emit_move_insn (tmp, val); Obviously missing operands[3] = tmp here :(. > }) > > ;; We always avoid the shift operation in bstrins_<mode>_for_ior_mask > > Submitting it to my test facility.