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.

Reply via email to