在 2023/11/12 上午9:00, Xi Ruoyao 写道:
GCC internal says:
'subreg's of 'subreg's are not supported. Using
'simplify_gen_subreg' is the recommended way to avoid this problem.
Unfortunately loongarch_expand_vec_cond_mask_expr might create nested
subreg under certain circumstances, causing an ICE.
Use simplify_gen_subreg as the internal document suggests.
* Similar problems have been fixed once on LA:-(, thank you for your
modification.
gcc/ChangeLog:
PR target/112476
* config/loongarch/loongarch.cc
(loongarch_expand_vec_cond_mask_expr): Call simplify_gen_subreg
instead of gen_rtx_SUBREG.
gcc/testsuite/ChangeLog:
PR target/112476
* gcc.target/loongarch/pr112476-1.c: New test.
* gcc.target/loongarch/pr112476-2.c: New test.
---
Bootstrapped and regtested on loongarch64-linux-gnu. Ok for trunk?
gcc/config/loongarch/loongarch.cc | 11 ++++++---
.../gcc.target/loongarch/pr112476-1.c | 24 +++++++++++++++++++
.../gcc.target/loongarch/pr112476-2.c | 5 ++++
3 files changed, 37 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/loongarch/pr112476-1.c
create mode 100644 gcc/testsuite/gcc.target/loongarch/pr112476-2.c
diff --git a/gcc/config/loongarch/loongarch.cc
b/gcc/config/loongarch/loongarch.cc
index d9b7a1076a2..0c7bafb5fb1 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -11197,7 +11197,9 @@ loongarch_expand_vec_cond_mask_expr (machine_mode mode,
machine_mode vimode,
if (mode != vimode)
{
xop1 = gen_reg_rtx (vimode);
- emit_move_insn (xop1, gen_rtx_SUBREG (vimode, operands[1], 0));
+ emit_move_insn (xop1,
+ simplify_gen_subreg (vimode, operands[1],
+ mode, 0));
}
emit_move_insn (src1, xop1);
}
@@ -11214,7 +11216,9 @@ loongarch_expand_vec_cond_mask_expr (machine_mode mode,
machine_mode vimode,
if (mode != vimode)
{
xop2 = gen_reg_rtx (vimode);
- emit_move_insn (xop2, gen_rtx_SUBREG (vimode, operands[2], 0));
+ emit_move_insn (xop2,
+ simplify_gen_subreg (vimode, operands[2],
+ mode, 0));
}
emit_move_insn (src2, xop2);
}
@@ -11233,7 +11237,8 @@ loongarch_expand_vec_cond_mask_expr (machine_mode mode,
machine_mode vimode,
gen_rtx_AND (vimode, mask, src1));
/* The result is placed back to a register with the mask. */
emit_insn (gen_rtx_SET (mask, bsel));
- emit_move_insn (operands[0], gen_rtx_SUBREG (mode, mask, 0));
+ emit_move_insn (operands[0], simplify_gen_subreg (mode, mask,
+ vimode, 0));
}
}
diff --git a/gcc/testsuite/gcc.target/loongarch/pr112476-1.c b/gcc/testsuite/gcc.target/loongarch/pr112476-1.c
new file mode 100644
index 00000000000..4cf133e7a26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr112476-1.c
@@ -0,0 +1,24 @@
+/* PR target/112476: ICE with -mlsx */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -mfpu=64 -mabi=lp64d -mlsx" } */
+
+int foo, bar;
+float baz, res, a;
+
+void
+apply_adjacent_ternary (float *dst, float *src0)
+{
+ do
+ {
+ __builtin_memcpy (&res, &src0, sizeof (res));
+ *dst = foo ? baz : res;
+ dst++;
+ }
+ while (dst != src0);
+}
+
+void
+xx (void)
+{
+ apply_adjacent_ternary (&a, &a);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/pr112476-2.c
b/gcc/testsuite/gcc.target/loongarch/pr112476-2.c
new file mode 100644
index 00000000000..cc0dfbfc912
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr112476-2.c
@@ -0,0 +1,5 @@
+/* PR target/112476: ICE with -mlasx */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -mfpu=64 -mabi=lp64d -mlasx" } */
+
+#include "pr112476-1.c"