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

Xi Ruoyao <xry111 at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|needs-bisection             |patch
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |xry111 at gcc dot 
gnu.org

--- Comment #3 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
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);
   })

 ;; We always avoid the shift operation in bstrins_<mode>_for_ior_mask

Submitting it to my test facility.

Reply via email to