Pushed to r16-6815 r15-10678 and r14-12243.

在 2026/1/15 上午10:54, Lulu Cheng 写道:
In the vector initialization process, optimization can be performed
if it can be determined that all elements are the same, or if the
upper or lower halves are identical.  However, during this
optimization, when the identical element is an immediate value
larger than 10 bits, an internal compiler error (ICE) occurs.
The reason is that in such cases, the function
`simplify_gen_subreg (imode, reg_tmp, GET_MODE (reg_tmp), 0)` is
called, where `imode` is `E_DImode`.  The mode of `reg_tmp` in
`GET_MODE (reg_tmp)` is taken from the immediate value's mode,
which is `E_VOIDmode`.  This results in a move from `E_VOIDmode`
to `E_DImode`, an operation not supported by LoongArch.

        PR target/123521

gcc/ChangeLog:

        * config/loongarch/loongarch.cc
        (loongarch_expand_vector_init_same): Fixed a bug in the
        vector initialization section..

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/vector/lasx/pr123521.c: New test.

Suggested-by: Xi Ruoyao <[email protected]>

---
  gcc/config/loongarch/loongarch.cc             | 27 +------------------
  .../loongarch/vector/lasx/pr123521.c          | 11 ++++++++
  2 files changed, 12 insertions(+), 26 deletions(-)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/vector/lasx/pr123521.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 0b50aa214fd..983779401b4 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -10436,32 +10436,7 @@ loongarch_expand_vector_init_same (rtx target, rtx 
vals, unsigned nvar)
        }
      }
- if (imode == GET_MODE (same))
-    temp = same;
-  else if (GET_MODE_SIZE (imode) >= UNITS_PER_WORD)
-    {
-      if (GET_CODE (same) == MEM)
-       {
-         rtx reg_tmp = gen_reg_rtx (GET_MODE (same));
-         loongarch_emit_move (reg_tmp, same);
-         temp = simplify_gen_subreg (imode, reg_tmp, GET_MODE (reg_tmp), 0);
-       }
-      else
-       temp = simplify_gen_subreg (imode, same, GET_MODE (same), 0);
-    }
-  else
-    {
-      if (GET_CODE (same) == MEM)
-       {
-         rtx reg_tmp = gen_reg_rtx (GET_MODE (same));
-         loongarch_emit_move (reg_tmp, same);
-         temp = lowpart_subreg (imode, reg_tmp, GET_MODE (reg_tmp));
-       }
-      else
-       temp = lowpart_subreg (imode, same, GET_MODE (same));
-    }
-
-  temp = force_reg (imode, temp);
+  temp = force_reg (imode, same);
switch (vmode)
      {
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr123521.c 
b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr123521.c
new file mode 100644
index 00000000000..9ccf391d38d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr123521.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -msimd=lasx" } */
+
+typedef long long v4i64 __attribute__ ((vector_size (32), aligned (32)));
+extern long long *x_si;
+v4i64
+test (void)
+{
+  v4i64 a = { x_si[1], x_si[0], 0x411, 0x411 };
+  return a;
+}

Reply via email to