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. 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" -- 2.42.1