public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-6317] LoongArch: Fix ICE and use simplify_gen_subreg instead of gen_rtx_SUBREG directly.
@ 2023-12-08  8:44 LuluCheng
  0 siblings, 0 replies; only message in thread
From: LuluCheng @ 2023-12-08  8:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:75f9c2ea29989b1663e4fc2648096ab2836d3877

commit r14-6317-g75f9c2ea29989b1663e4fc2648096ab2836d3877
Author: Jiahao Xu <xujiahao@loongson.cn>
Date:   Wed Nov 29 11:18:00 2023 +0800

    LoongArch: Fix ICE and use simplify_gen_subreg instead of gen_rtx_SUBREG directly.
    
    loongarch_expand_vec_cond_mask_expr generates 'subreg's of 'subreg's, which are not supported
    in gcc, it causes an ICE:
    
    ice.c:55:1: error: unrecognizable insn:
       55 | }
          | ^
    (insn 63 62 64 8 (set (reg:V4DI 278)
            (subreg:V4DI (subreg:V4DF (reg:V4DI 273 [ vect__53.26 ]) 0) 0)) -1
         (nil))
    during RTL pass: vregs
    ice.c:55:1: internal compiler error: in extract_insn, at recog.cc:2804
    
    Last time, Ruoyao has fixed a similar ICE:
    https://gcc.gnu.org/pipermail/gcc-patches/2023-November/636156.html
    
    This patch fixes ICE and use simplify_gen_subreg instead of gen_rtx_SUBREG as much as possible
    to avoid the same ice happening again.
    
    gcc/ChangeLog:
    
            * config/loongarch/loongarch.cc (loongarch_try_expand_lsx_vshuf_const): Use
            simplify_gen_subreg instead of gen_rtx_SUBREG.
            (loongarch_expand_vec_perm_const_2): Ditto.
            (loongarch_expand_vec_cond_expr): Ditto.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/loongarch/pr112476-3.c: New test.
            * gcc.target/loongarch/pr112476-4.c: New test.

Diff:
---
 gcc/config/loongarch/loongarch.cc               | 79 ++++++++++++++-----------
 gcc/testsuite/gcc.target/loongarch/pr112476-3.c | 58 ++++++++++++++++++
 gcc/testsuite/gcc.target/loongarch/pr112476-4.c |  4 ++
 3 files changed, 108 insertions(+), 33 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 17508073eda..8630db44e89 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -8826,13 +8826,13 @@ loongarch_try_expand_lsx_vshuf_const (struct expand_vec_perm_d *d)
       if (d->vmode == E_V2DFmode)
 	{
 	  sel = gen_rtx_CONST_VECTOR (E_V2DImode, gen_rtvec_v (d->nelt, rperm));
-	  tmp = gen_rtx_SUBREG (E_V2DImode, d->target, 0);
+	  tmp = simplify_gen_subreg (E_V2DImode, d->target, d->vmode, 0);
 	  emit_move_insn (tmp, sel);
 	}
       else if (d->vmode == E_V4SFmode)
 	{
 	  sel = gen_rtx_CONST_VECTOR (E_V4SImode, gen_rtvec_v (d->nelt, rperm));
-	  tmp = gen_rtx_SUBREG (E_V4SImode, d->target, 0);
+	  tmp = simplify_gen_subreg (E_V4SImode, d->target, d->vmode, 0);
 	  emit_move_insn (tmp, sel);
 	}
       else
@@ -9616,8 +9616,8 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  /* Adjust op1 for selecting correct value in high 128bit of target
 	     register.
 	     op1: E_V4DImode, { 4, 5, 6, 7 } -> { 2, 3, 4, 5 }.  */
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, d->op0, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, op1_alt, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, d->op0, d->vmode, 0);
 	  emit_insn (gen_lasx_xvpermi_q_v4di (conv_op1, conv_op1,
 					      conv_op0, GEN_INT (0x21)));
 
@@ -9646,8 +9646,8 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  emit_move_insn (op0_alt, d->op0);
 
 	  /* Generate subreg for fitting into insn gen function.  */
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, op0_alt, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, op1_alt, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, op0_alt, d->vmode, 0);
 
 	  /* Adjust op value in temp register.
 	     op0 = {0,1,2,3}, op1 = {4,5,0,1}  */
@@ -9693,9 +9693,10 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  emit_move_insn (op1_alt, d->op1);
 	  emit_move_insn (op0_alt, d->op0);
 
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, op0_alt, 0);
-	  rtx conv_target = gen_rtx_SUBREG (E_V4DImode, d->target, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, op1_alt, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, op0_alt, d->vmode, 0);
+	  rtx conv_target = simplify_gen_subreg (E_V4DImode, d->target,
+						 d->vmode, 0);
 
 	  emit_insn (gen_lasx_xvpermi_q_v4di (conv_op1, conv_op1,
 					      conv_op0, GEN_INT (0x02)));
@@ -9727,9 +9728,10 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	 Selector sample: E_V4DImode, { 0, 1, 4 ,5 }  */
       if (!d->testing_p)
 	{
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, d->op1, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, d->op0, 0);
-	  rtx conv_target = gen_rtx_SUBREG (E_V4DImode, d->target, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, d->op1, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, d->op0, d->vmode, 0);
+	  rtx conv_target = simplify_gen_subreg (E_V4DImode, d->target,
+						 d->vmode, 0);
 
 	  /* We can achieve the expectation by using sinple xvpermi.q insn.  */
 	  emit_move_insn (conv_target, conv_op1);
@@ -9754,8 +9756,8 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  emit_move_insn (op1_alt, d->op1);
 	  emit_move_insn (op0_alt, d->op0);
 
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, op0_alt, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, op1_alt, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, op0_alt, d->vmode, 0);
 	  /* Adjust op value in temp regiter.
 	     op0 = { 0, 1, 2, 3 }, op1 = { 6, 7, 2, 3 }  */
 	  emit_insn (gen_lasx_xvpermi_q_v4di (conv_op1, conv_op1,
@@ -9799,9 +9801,10 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  emit_move_insn (op1_alt, d->op1);
 	  emit_move_insn (op0_alt, d->op0);
 
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, op0_alt, 0);
-	  rtx conv_target = gen_rtx_SUBREG (E_V4DImode, d->target, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, op1_alt, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, op0_alt, d->vmode, 0);
+	  rtx conv_target = simplify_gen_subreg (E_V4DImode, d->target,
+						 d->vmode, 0);
 
 	  emit_insn (gen_lasx_xvpermi_q_v4di (conv_op1, conv_op1,
 					      conv_op0, GEN_INT (0x13)));
@@ -9833,10 +9836,11 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	 Selector sample:E_V8SImode, { 2, 2, 2, 2, 2, 2, 2, 2 }  */
       if (!d->testing_p)
 	{
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, d->op1, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, d->op0, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, d->op1, d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, d->op0, d->vmode, 0);
 	  rtx temp_reg = gen_reg_rtx (d->vmode);
-	  rtx conv_temp = gen_rtx_SUBREG (E_V4DImode, temp_reg, 0);
+	  rtx conv_temp = simplify_gen_subreg (E_V4DImode, temp_reg,
+					       d->vmode, 0);
 
 	  emit_move_insn (temp_reg, d->op0);
 
@@ -9945,9 +9949,11 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  emit_move_insn (op0_alt, d->op0);
 	  emit_move_insn (op1_alt, d->op1);
 
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, d->op0, 0);
-	  rtx conv_op0a = gen_rtx_SUBREG (E_V4DImode, op0_alt, 0);
-	  rtx conv_op1a = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, d->op0, d->vmode, 0);
+	  rtx conv_op0a = simplify_gen_subreg (E_V4DImode, op0_alt,
+					       d->vmode, 0);
+	  rtx conv_op1a = simplify_gen_subreg (E_V4DImode, op1_alt,
+					       d->vmode, 0);
 
 	  /* Duplicate op0's low 128bit in op0, then duplicate high 128bit
 	     in op1.  After this, xvshuf.* insn's selector argument can
@@ -9980,10 +9986,12 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
 	  emit_move_insn (op0_alt, d->op0);
 	  emit_move_insn (op1_alt, d->op1);
 
-	  rtx conv_op0a = gen_rtx_SUBREG (E_V4DImode, op0_alt, 0);
-	  rtx conv_op1a = gen_rtx_SUBREG (E_V4DImode, op1_alt, 0);
-	  rtx conv_op0 = gen_rtx_SUBREG (E_V4DImode, d->op0, 0);
-	  rtx conv_op1 = gen_rtx_SUBREG (E_V4DImode, d->op1, 0);
+	  rtx conv_op0a = simplify_gen_subreg (E_V4DImode, op0_alt,
+					       d->vmode, 0);
+	  rtx conv_op1a = simplify_gen_subreg (E_V4DImode, op1_alt,
+					       d->vmode, 0);
+	  rtx conv_op0 = simplify_gen_subreg (E_V4DImode, d->op0, d->vmode, 0);
+	  rtx conv_op1 = simplify_gen_subreg (E_V4DImode, d->op1, d->vmode, 0);
 
 	  /* Reorganize op0's hi/lo 128bit and op1's hi/lo 128bit, to make sure
 	     that selector's low 128bit can access all op0's elements, and
@@ -10103,12 +10111,12 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
     {
     case E_V4DFmode:
       sel = gen_rtx_CONST_VECTOR (E_V4DImode, gen_rtvec_v (d->nelt, rperm));
-      tmp = gen_rtx_SUBREG (E_V4DImode, d->target, 0);
+      tmp = simplify_gen_subreg (E_V4DImode, d->target, d->vmode, 0);
       emit_move_insn (tmp, sel);
       break;
     case E_V8SFmode:
       sel = gen_rtx_CONST_VECTOR (E_V8SImode, gen_rtvec_v (d->nelt, rperm));
-      tmp = gen_rtx_SUBREG (E_V8SImode, d->target, 0);
+      tmp = simplify_gen_subreg (E_V8SImode, d->target, d->vmode, 0);
       emit_move_insn (tmp, sel);
       break;
     default:
@@ -10194,7 +10202,7 @@ loongarch_expand_vec_perm_const_2 (struct expand_vec_perm_d *d)
      64bit in target vector register.  */
   else if (extract_ev_od)
     {
-      rtx converted = gen_rtx_SUBREG (E_V4DImode, d->target, 0);
+      rtx converted = simplify_gen_subreg (E_V4DImode, d->target, d->vmode, 0);
       emit_insn (gen_lasx_xvpermi_d_v4di (converted, converted,
 					  GEN_INT (0xD8)));
     }
@@ -11284,7 +11292,9 @@ loongarch_expand_vec_cond_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);
 	}
@@ -11301,7 +11311,9 @@ loongarch_expand_vec_cond_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);
 	}
@@ -11320,7 +11332,8 @@ loongarch_expand_vec_cond_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-3.c b/gcc/testsuite/gcc.target/loongarch/pr112476-3.c
new file mode 100644
index 00000000000..d696d4182bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr112476-3.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mlsx" } */
+
+#include <stdint.h>
+
+typedef int8_t orc_int8;
+typedef int16_t orc_int16;
+typedef int32_t orc_int32;
+typedef int64_t orc_int64;
+
+typedef union
+{
+  orc_int32 i;
+  float f;
+  orc_int16 x2[2];
+  orc_int8 x4[4];
+} orc_union32;
+typedef union
+{
+  orc_int64 i;
+  double f;
+  orc_int32 x2[2];
+  float x2f[2];
+  orc_int16 x4[4];
+} orc_union64;
+
+void
+audio_orc_s32_to_double (double * restrict d1,
+    const signed int * restrict s1, int n)
+{
+  int i;
+  orc_union64 *restrict ptr0;
+  const orc_union32 *restrict ptr4;
+  orc_union32 var33;
+  orc_union64 var34;
+  orc_union64 var35;
+  orc_union64 var36;
+
+  ptr0 = (orc_union64 *) d1;
+  ptr4 = (orc_union32 *) s1;
+
+  var34.i = 0x41e0000000000000UL;
+
+  for (i = 0; i < n; i++) {
+    var33 = ptr4[i];
+    var36.f = var33.i;
+    {
+      orc_union64 _src1;
+      orc_union64 _src2;
+      orc_union64 _dest1;
+      _src1.i = ((var36.i) & ((((var36.i)&0x7ff0000000000000UL) == 0) ? 0xfff0000000000000UL : 0xffffffffffffffffUL));
+      _src2.i = ((var34.i) & ((((var34.i)&0x7ff0000000000000UL) == 0) ? 0xfff0000000000000UL : 0xffffffffffffffffUL));
+      _dest1.f = _src1.f / _src2.f;
+      var35.i = ((_dest1.i) & ((((_dest1.i)&0x7ff0000000000000UL) == 0) ? 0xfff0000000000000UL : 0xffffffffffffffffUL));
+    }
+    ptr0[i] = var35;
+  }
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/pr112476-4.c b/gcc/testsuite/gcc.target/loongarch/pr112476-4.c
new file mode 100644
index 00000000000..955d98552eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr112476-4.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mlasx" } */
+ 
+#include "pr112476-3.c"

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-12-08  8:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-08  8:44 [gcc r14-6317] LoongArch: Fix ICE and use simplify_gen_subreg instead of gen_rtx_SUBREG directly LuluCheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).