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; +}
