As we have hardware instructions for those operations, developers will
reasonably assume they can emit them even after reload. But on LA64 we
are expanding them using pseudos to reduce unneeded sign extensions,
breaking such an expectation and causing ICE like PR 123320.
Only create the pseudo when can_create_pseudo_p () to fix such cases.
PR target/123320
gcc
* config/loongarch/loongarch.md (<optab><mode>3): Only expand
using psuedos when can_create_pseudo_p ().
(addsi3): Likewise.
gcc/testsuite
* gcc.target/loongarch/la64/pr123320.c: New test.
---
Bootstrapped and regtested on loongarch64-linux-gnu. Ok for trunk?
gcc/config/loongarch/loongarch.md | 9 +-
.../gcc.target/loongarch/la64/pr123320.c | 128 ++++++++++++++++++
2 files changed, 133 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/loongarch/la64/pr123320.c
diff --git a/gcc/config/loongarch/loongarch.md
b/gcc/config/loongarch/loongarch.md
index 39e315c818b..3d7e8dca208 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -648,7 +648,7 @@ (define_expand "<optab><mode>3"
(match_operand:SI 2 "arith_operand" "rI")))]
""
{
- if (TARGET_64BIT && <MODE>mode == SImode)
+ if (TARGET_64BIT && <MODE>mode == SImode && can_create_pseudo_p ())
{
rtx t = gen_reg_rtx (DImode);
emit_insn (gen_<optab>si3_extend (t, operands[1], operands[2]));
@@ -666,7 +666,7 @@ (define_expand "<optab><mode>3"
(match_operand:GPR 2 "register_operand" "r")))]
""
{
- if (TARGET_64BIT && <MODE>mode == SImode)
+ if (TARGET_64BIT && <MODE>mode == SImode && can_create_pseudo_p ())
{
rtx t = gen_reg_rtx (DImode);
emit_insn (gen_<optab>si3_extend (t, operands[1], operands[2]));
@@ -751,7 +751,7 @@ (define_expand "addsi3"
(match_operand:SI 2 "plus_si_operand" "r,I,La,Le,Lb")))]
""
{
- if (TARGET_64BIT)
+ if (TARGET_64BIT && can_create_pseudo_p ())
{
if (CONST_INT_P (operands[2]) && !IMM12_INT (operands[2])
&& ADDU16I_OPERAND (INTVAL (operands[2])))
@@ -1066,7 +1066,8 @@ (define_expand "<optab><mode>3"
(match_operand:GPR 2 "register_operand")))]
""
{
- if (GET_MODE (operands[0]) == SImode && TARGET_64BIT)
+ if (GET_MODE (operands[0]) == SImode && TARGET_64BIT
+ && can_create_pseudo_p ())
{
if (ISA_HAS_DIV32)
{
diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr123320.c
b/gcc/testsuite/gcc.target/loongarch/la64/pr123320.c
new file mode 100644
index 00000000000..0abb2d65d8e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/la64/pr123320.c
@@ -0,0 +1,128 @@
+/* PR 123320: ICE in peephole2 */
+/* { dg-do compile } */
+/* { dg-options "-Os -mlsx -fstack-protector -w" } */
+
+typedef char a;
+typedef short b;
+typedef int c;
+typedef long d;
+typedef char e;
+typedef short f;
+typedef int g;
+f h;
+struct i {
+ signed j : 20
+} * k;
+c l, m, n;
+a o;
+static struct i p[][5];
+static struct i q;
+d r, s;
+__attribute__((__vector_size__(32))) a t;
+g __attribute__((vector_size(16)))
+u(f __attribute__((vector_size(2 * sizeof(f)))),
+ b __attribute__((vector_size(16 * sizeof(b)))), e);
+c __attribute__((vector_size(8 * sizeof(c))))
+v(e __attribute__((vector_size(2))), a,
+ d __attribute__((vector_size(2 * sizeof(d)))),
+ e __attribute__((vector_size(16))), a __attribute__((vector_size(32))),
+ f __attribute__((vector_size(16 * sizeof(f)))));
+ f(w)(f x) { return x - h; }
+void y(int);
+void z(g, g, f, struct i);
+static c aa(struct i ab, struct i ac)
+{
+ a __attribute__((vector_size(8))) ad;
+ for (; l;)
+ {
+ __asm("" ::: "$r31");
+ r = w(0 == ab.j);
+ ac.j = ab.j;
+ ab.j = ad[0] =
+ v((e __attribute__((vector_size(2)))){}, 0,
+ (d __attribute__((vector_size(2 * sizeof(d))))){},
+ (e __attribute__((vector_size(16)))){},
+ (a __attribute__((vector_size(32)))){},
+ ~__builtin_shufflevector(
+ __builtin_shufflevector(
+ (f __attribute__((vector_size(16 *sizeof(f))))){},
+ __builtin_convertvector(
+ __builtin_shufflevector(t, t, 9, 2, 9, 6, 3, 6, 2, 2,
+ 8, 8, 2, 7, 3, 0, 5, 0),
+ f __attribute__((vector_size(16 * sizeof(f))))),
+ 25, 8, 1, 8, 9, 1, 7, 2, 5, 2, 0, 4, 8, 1, 9, 0, 6, 3, 3,
+ 7, 1, 6, 2, 0, 5, 1, 3, 5, 0, 1, 4, 6),
+ (f __attribute__((vector_size(sizeof(f))))){}, 9, 1, 4, 4, 0,
+ 2, 5, 2, 8, 6, 3, 8, 4, 1, 4, 9))[3];
+ }
+ if (ac.j)
+ __builtin_convertvector(
+ __builtin_shufflevector(
+ v(__builtin_convertvector(__builtin_shufflevector(ad, ad, 2,
2),
+ e __attribute__((vector_size(2)))),
+ 0, (d __attribute__((vector_size(2 * sizeof(d))))){},
+ (e __attribute__((vector_size(16)))){},
+ (a __attribute__((vector_size(32)))){},
+ (f __attribute__((vector_size(16 * sizeof(f))))){}),
+ v(__builtin_convertvector(__builtin_shufflevector(ad, ad, 2,
2),
+ e __attribute__((vector_size(2)))),
+ 0, (d __attribute__((vector_size(2 * sizeof(d))))){},
+ (e __attribute__((vector_size(16)))){},
+ (a __attribute__((vector_size(32)))){},
+ (f __attribute__((vector_size(16 * sizeof(f))))){}),
+ 2, 6, 0, 6),
+ a __attribute__((vector_size(4))));
+}
+
+void ae()
+{
+ int af = 0;
+ if (m) af = 1;
+ struct i ag;
+ (g __attribute__((vector_size(sizeof(
+ g))))){}[u((f __attribute__((vector_size(2 *sizeof(f))))){},
+ (b __attribute__((vector_size(16 * sizeof(b))))){}, 0)[2]
+ ? u((f __attribute__((vector_size(2 *sizeof(f))))){},
+ (b __attribute__((vector_size(16 * sizeof(b))))){},
+ 0)[2]
+ : 0];
+ a __attribute__((vector_size(2))) ah;
+ ag.j == o;
+ __asm("" ::: "$r26");
+ __asm("" ::: "$r30", "$r23");
+ __builtin_convertvector(
+ __builtin_shufflevector(
+ v(__builtin_shufflevector(
+ __builtin_convertvector(
+ __builtin_shufflevector(ah, ah, 3, 2, 0, 3),
+ e __attribute__((vector_size(4)))),
+ (e __attribute__((vector_size(4)))){}, 2, 6),
+ 0, (d __attribute__((vector_size(2 * sizeof(d))))){},
+ (e __attribute__((vector_size(16)))){},
+ (a __attribute__((vector_size(32)))){},
+ __builtin_convertvector(
+ __builtin_shufflevector(ah, ah, 3, 0, 3, 3, 0, 1, 0, 1, 1, 3,
+ 1, 1, 2, 1, 2, 2),
+ f __attribute__((vector_size(16 * sizeof(f)))))),
+ v(__builtin_shufflevector(
+ __builtin_convertvector(
+ __builtin_shufflevector(ah, ah, 3, 2, 0, 3),
+ e __attribute__((vector_size(4)))),
+ (e __attribute__((vector_size(4)))){}, 2, 6),
+ 0, (d __attribute__((vector_size(2 * sizeof(d))))){},
+ (e __attribute__((vector_size(16)))){},
+ (a __attribute__((vector_size(32)))){},
+ __builtin_convertvector(
+ __builtin_shufflevector(ah, ah, 3, 0, 3, 3, 0, 1, 0, 1, 1, 3,
+ 1, 1, 2, 1, 2, 2),
+ f __attribute__((vector_size(16 * sizeof(f)))))),
+ 3, 2, 1, 0, 8, 6, 3, 2, 5, 2, 0, 2, 2, 3, 1, 0, 2, 6, 5, 6, 9, 6,
0,
+ 2, 4, 2, 5, 1, 4, 4, 6, 0),
+ b __attribute__((vector_size(32 * sizeof(b)))));
+ __asm goto("" : : : : ai);
+ ag = *k;
+ai:
+ aa(ag, p[5][4]);
+ z(n, s, s, q);
+ y(af);
+}
--
2.52.0