public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
@ 2023-11-30  7:21 pan2.li
  2023-11-30  7:24 ` juzhe.zhong
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: pan2.li @ 2023-11-30  7:21 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.

Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.

This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.

	PR target/112743

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_legitimize_move): Take the
	exist (U *mode) instead of directly require ().

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
 .../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
 2 files changed, 79 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
 	  smode = SImode;
 	  nunits = nunits * 2;
 	}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
 
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
 	{
-	  rtx result;
-	  if (num == 1)
-	    result = dest;
-	  else if (i == 0)
-	    result = gen_lowpart (smode, dest);
-	  else
-	    result = gen_reg_rtx (smode);
-	  riscv_vector::emit_vec_extract (result, v, index + i);
+	  rtx v = gen_lowpart (vmode, SUBREG_REG (src));
 
-	  if (i == 1)
+	  for (unsigned int i = 0; i < num; i++)
 	    {
-	      rtx tmp
-		= expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
-				gen_int_mode (32, Pmode), NULL_RTX, 0,
-				OPTAB_DIRECT);
-	      rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-				       OPTAB_DIRECT);
-	      emit_move_insn (dest, tmp2);
+	      rtx result;
+	      if (num == 1)
+		result = dest;
+	      else if (i == 0)
+		result = gen_lowpart (smode, dest);
+	      else
+		result = gen_reg_rtx (smode);
+
+	      riscv_vector::emit_vec_extract (result, v, index + i);
+
+	      if (i == 1)
+		{
+		  rtx tmp = expand_binop (Pmode, ashl_optab,
+					  gen_lowpart (Pmode, result),
+					  gen_int_mode (32, Pmode), NULL_RTX, 0,
+					  OPTAB_DIRECT);
+		  rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+					   NULL_RTX, 0,
+					   OPTAB_DIRECT);
+		  emit_move_insn (dest, tmp2);
+		}
 	    }
+	  return true;
 	}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+	{
+	  word0 (a) = 0x80000 >> L;
+	  word1 (a) = 0;
+	}
+      else
+	{
+	  word0 (a) = 0;
+	  L -= Exp_shift;
+	  word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+	}
+    }
+
+  return a.d;
+}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:21 [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f pan2.li
@ 2023-11-30  7:24 ` juzhe.zhong
  2023-11-30  7:31   ` Li, Pan2
  2023-12-01  7:52 ` [PATCH v2] " pan2.li
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: juzhe.zhong @ 2023-11-30  7:24 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 4599 bytes --]

Why does get_vector_mode doesn't exist a vector mode ?

It must exist a vector mode, otherwise, it will cause ICE in other situations.



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-11-30 15:21
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com>
 
When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.
 
Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.
 
This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.
 
PR target/112743
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) instead of directly require ().
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr112743-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
2 files changed, 79 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-   if (i == 1)
+   for (unsigned int i = 0; i < num; i++)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       rtx result;
+       if (num == 1)
+ result = dest;
+       else if (i == 0)
+ result = gen_lowpart (smode, dest);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (dest, tmp2);
+ }
    }
+   return true;
}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:24 ` juzhe.zhong
@ 2023-11-30  7:31   ` Li, Pan2
  2023-11-30  7:32     ` juzhe.zhong
  0 siblings, 1 reply; 14+ messages in thread
From: Li, Pan2 @ 2023-11-30  7:31 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 5438 bytes --]

> Why does get_vector_mode doesn't exist a vector mode ?

Because we set the zve32f here, but try to get_vect_mode with E_V1DFmode.
According to the ISA, FP64 is not support when zve32F.

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Thursday, November 30, 2023 3:24 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

Why does get_vector_mode doesn't exist a vector mode ?

It must exist a vector mode, otherwise, it will cause ICE in other situations.

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-11-30 15:21
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.

Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.

This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.

PR target/112743

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) instead of directly require ().

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
2 files changed, 79 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-   if (i == 1)
+   for (unsigned int i = 0; i < num; i++)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       rtx result;
+       if (num == 1)
+ result = dest;
+       else if (i == 0)
+ result = gen_lowpart (smode, dest);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (dest, tmp2);
+ }
    }
+   return true;
}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
--
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:31   ` Li, Pan2
@ 2023-11-30  7:32     ` juzhe.zhong
  2023-11-30  7:42       ` Li, Pan2
  0 siblings, 1 reply; 14+ messages in thread
From: juzhe.zhong @ 2023-11-30  7:32 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 5438 bytes --]

What it the RTX of the operand ?



juzhe.zhong@rivai.ai
 
From: Li, Pan2
Date: 2023-11-30 15:31
To: juzhe.zhong@rivai.ai; gcc-patches
CC: Wang, Yanzhang; kito.cheng
Subject: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
> Why does get_vector_mode doesn't exist a vector mode ?
 
Because we set the zve32f here, but try to get_vect_mode with E_V1DFmode.
According to the ISA, FP64 is not support when zve32F.
 
Pan
 
From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> 
Sent: Thursday, November 30, 2023 3:24 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
 
Why does get_vector_mode doesn't exist a vector mode ?
 
It must exist a vector mode, otherwise, it will cause ICE in other situations.
 


juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-11-30 15:21
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com>
 
When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.
 
Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.
 
This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.
 
PR target/112743
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) instead of directly require ().
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr112743-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
2 files changed, 79 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-   if (i == 1)
+   for (unsigned int i = 0; i < num; i++)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       rtx result;
+       if (num == 1)
+ result = dest;
+       else if (i == 0)
+ result = gen_lowpart (smode, dest);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (dest, tmp2);
+ }
    }
+   return true;
}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:32     ` juzhe.zhong
@ 2023-11-30  7:42       ` Li, Pan2
  2023-11-30  7:54         ` juzhe.zhong
  0 siblings, 1 reply; 14+ messages in thread
From: Li, Pan2 @ 2023-11-30  7:42 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 6765 bytes --]

Take this file riscv-gnu-toolchain/newlib/newlib/libc/stdlib/mprec.c for example, the arguments and/or related local variables list as below

riscv_legitimize_move
  mode = E_DFmode
  dest = (reg:DF 144 [ <retval> ])
  src = (subreg:DF (reg:V2SI 170) 0)

nunits = 1
smode = {m_mode = E_DFmode}

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Thursday, November 30, 2023 3:33 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

What it the RTX of the operand ?

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: Li, Pan2<mailto:pan2.li@intel.com>
Date: 2023-11-30 15:31
To: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>; gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: Wang, Yanzhang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
> Why does get_vector_mode doesn't exist a vector mode ?

Because we set the zve32f here, but try to get_vect_mode with E_V1DFmode.
According to the ISA, FP64 is not support when zve32F.

Pan

From: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai> <juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>
Sent: Thursday, November 30, 2023 3:24 PM
To: Li, Pan2 <pan2.li@intel.com<mailto:pan2.li@intel.com>>; gcc-patches <gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>>
Cc: Li, Pan2 <pan2.li@intel.com<mailto:pan2.li@intel.com>>; Wang, Yanzhang <yanzhang.wang@intel.com<mailto:yanzhang.wang@intel.com>>; kito.cheng <kito.cheng@gmail.com<mailto:kito.cheng@gmail.com>>
Subject: Re: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

Why does get_vector_mode doesn't exist a vector mode ?

It must exist a vector mode, otherwise, it will cause ICE in other situations.

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-11-30 15:21
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.

Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.

This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.

PR target/112743

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) instead of directly require ().

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
2 files changed, 79 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-   if (i == 1)
+   for (unsigned int i = 0; i < num; i++)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       rtx result;
+       if (num == 1)
+ result = dest;
+       else if (i == 0)
+ result = gen_lowpart (smode, dest);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (dest, tmp2);
+ }
    }
+   return true;
}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
--
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:42       ` Li, Pan2
@ 2023-11-30  7:54         ` juzhe.zhong
  2023-11-30  8:00           ` Li, Pan2
  0 siblings, 1 reply; 14+ messages in thread
From: juzhe.zhong @ 2023-11-30  7:54 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 6854 bytes --]

I see.

Is it possible to block this situation in other place ? that is, make the situation you said never reach here.

Or handle this situation with this following approach:

if (get_vector_mode doesn't exist such mode)

1. extract V2SI -> lowpart of the DI reg.
2. extract V2SI -> highpart of the DI reg.
3. scalar move DI reg to DF reg.

This patch just bypass the situation (return false) you mention is quite unsafe here.
As I remembered, I add this code to handle some ICE due to "return false" here.



juzhe.zhong@rivai.ai
 
From: Li, Pan2
Date: 2023-11-30 15:42
To: juzhe.zhong@rivai.ai; gcc-patches
CC: Wang, Yanzhang; kito.cheng
Subject: RE: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
Take this file riscv-gnu-toolchain/newlib/newlib/libc/stdlib/mprec.c for example, the arguments and/or related local variables list as below
 
riscv_legitimize_move
  mode = E_DFmode
  dest = (reg:DF 144 [ <retval> ])
  src = (subreg:DF (reg:V2SI 170) 0)
 
nunits = 1
smode = {m_mode = E_DFmode}
 
Pan
 
From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> 
Sent: Thursday, November 30, 2023 3:33 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
 
What it the RTX of the operand ?
 


juzhe.zhong@rivai.ai
 
From: Li, Pan2
Date: 2023-11-30 15:31
To: juzhe.zhong@rivai.ai; gcc-patches
CC: Wang, Yanzhang; kito.cheng
Subject: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
> Why does get_vector_mode doesn't exist a vector mode ?
 
Because we set the zve32f here, but try to get_vect_mode with E_V1DFmode.
According to the ISA, FP64 is not support when zve32F.
 
Pan
 
From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> 
Sent: Thursday, November 30, 2023 3:24 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
 
Why does get_vector_mode doesn't exist a vector mode ?
 
It must exist a vector mode, otherwise, it will cause ICE in other situations.
 


juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-11-30 15:21
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com>
 
When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.
 
Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.
 
This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.
 
PR target/112743
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) instead of directly require ().
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr112743-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
2 files changed, 79 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-   if (i == 1)
+   for (unsigned int i = 0; i < num; i++)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       rtx result;
+       if (num == 1)
+ result = dest;
+       else if (i == 0)
+ result = gen_lowpart (smode, dest);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (dest, tmp2);
+ }
    }
+   return true;
}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:54         ` juzhe.zhong
@ 2023-11-30  8:00           ` Li, Pan2
  0 siblings, 0 replies; 14+ messages in thread
From: Li, Pan2 @ 2023-11-30  8:00 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 8299 bytes --]

Got it, will have a try for the suggestion.

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Thursday, November 30, 2023 3:54 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

I see.

Is it possible to block this situation in other place ? that is, make the situation you said never reach here.

Or handle this situation with this following approach:

if (get_vector_mode doesn't exist such mode)

1. extract V2SI -> lowpart of the DI reg.
2. extract V2SI -> highpart of the DI reg.
3. scalar move DI reg to DF reg.

This patch just bypass the situation (return false) you mention is quite unsafe here.
As I remembered, I add this code to handle some ICE due to "return false" here.

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: Li, Pan2<mailto:pan2.li@intel.com>
Date: 2023-11-30 15:42
To: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>; gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: Wang, Yanzhang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: RE: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
Take this file riscv-gnu-toolchain/newlib/newlib/libc/stdlib/mprec.c for example, the arguments and/or related local variables list as below

riscv_legitimize_move
  mode = E_DFmode
  dest = (reg:DF 144 [ <retval> ])
  src = (subreg:DF (reg:V2SI 170) 0)

nunits = 1
smode = {m_mode = E_DFmode}

Pan

From: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai> <juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>
Sent: Thursday, November 30, 2023 3:33 PM
To: Li, Pan2 <pan2.li@intel.com<mailto:pan2.li@intel.com>>; gcc-patches <gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>>
Cc: Wang, Yanzhang <yanzhang.wang@intel.com<mailto:yanzhang.wang@intel.com>>; kito.cheng <kito.cheng@gmail.com<mailto:kito.cheng@gmail.com>>
Subject: Re: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

What it the RTX of the operand ?

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: Li, Pan2<mailto:pan2.li@intel.com>
Date: 2023-11-30 15:31
To: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>; gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: Wang, Yanzhang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: RE: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
> Why does get_vector_mode doesn't exist a vector mode ?

Because we set the zve32f here, but try to get_vect_mode with E_V1DFmode.
According to the ISA, FP64 is not support when zve32F.

Pan

From: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai> <juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>
Sent: Thursday, November 30, 2023 3:24 PM
To: Li, Pan2 <pan2.li@intel.com<mailto:pan2.li@intel.com>>; gcc-patches <gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>>
Cc: Li, Pan2 <pan2.li@intel.com<mailto:pan2.li@intel.com>>; Wang, Yanzhang <yanzhang.wang@intel.com<mailto:yanzhang.wang@intel.com>>; kito.cheng <kito.cheng@gmail.com<mailto:kito.cheng@gmail.com>>
Subject: Re: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

Why does get_vector_mode doesn't exist a vector mode ?

It must exist a vector mode, otherwise, it will cause ICE in other situations.

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-11-30 15:21
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

When require mode after get_vec_mode in riscv_legitimize_move,
there will be precondition that the mode is exists. Or we will
have E_VOIDMode and of course have ICE when required.

Typically we should first check the mode exists or not before
require, or more friendly like leverage exist (U *mode) to get
the expected mode if exists and unchanged if not.

This patch would like to fix this by exist (U *mode) for requiring
a mode after get_vec_mode.

PR target/112743

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) instead of directly require ().

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv.cc                     | 47 ++++++++++-------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++++++
2 files changed, 79 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..19413b2c976 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2615,32 +2615,39 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-   if (i == 1)
+   for (unsigned int i = 0; i < num; i++)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       rtx result;
+       if (num == 1)
+ result = dest;
+       else if (i == 0)
+ result = gen_lowpart (smode, dest);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (dest, tmp2);
+ }
    }
+   return true;
}
-      return true;
     }
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
--
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:21 [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f pan2.li
  2023-11-30  7:24 ` juzhe.zhong
@ 2023-12-01  7:52 ` pan2.li
  2023-12-01  8:00   ` juzhe.zhong
  2023-12-01 10:11 ` [PATCH v3] " pan2.li
  2023-12-02  0:59 ` [PATCH v4] " pan2.li
  3 siblings, 1 reply; 14+ messages in thread
From: pan2.li @ 2023-12-01  7:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.

This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:

rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done

	PR target/112743

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_legitimize_move): Take the
	exist (U *mode) and handle DFmode like DImode when EEW is
	32bits like ZVE32F.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv.cc                     | 67 +++++++++++++------
 .../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 ++++++++++++++
 2 files changed, 99 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..996347ee3fd 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,68 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = (smode == DImode || smode == DFmode)
+	&& !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
 
       if (num == 2)
 	{
 	  /* If we want to extract 64bit value but ELEN < 64,
 	     we use RVV vector mode with EEW = 32 to extract
 	     the highpart and lowpart.  */
+	  need_int_reg_p = smode == DFmode;
 	  smode = SImode;
 	  nunits = nunits * 2;
 	}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
 
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
 	{
-	  rtx result;
-	  if (num == 1)
-	    result = dest;
-	  else if (i == 0)
-	    result = gen_lowpart (smode, dest);
-	  else
-	    result = gen_reg_rtx (smode);
-	  riscv_vector::emit_vec_extract (result, v, index + i);
+	  rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+	  rtx int_reg = dest;
 
-	  if (i == 1)
+	  if (need_int_reg_p)
 	    {
-	      rtx tmp
-		= expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
-				gen_int_mode (32, Pmode), NULL_RTX, 0,
-				OPTAB_DIRECT);
-	      rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-				       OPTAB_DIRECT);
-	      emit_move_insn (dest, tmp2);
+	      int_reg = gen_reg_rtx (DImode);
+	      emit_insn (
+		gen_movdi (int_reg, gen_lowpart (GET_MODE (int_reg), dest)));
+	    }
+
+	  for (unsigned int i = 0; i < num; i++)
+	    {
+	      rtx result;
+	      if (num == 1)
+		result = int_reg;
+	      else if (i == 0)
+		result = gen_lowpart (smode, int_reg);
+	      else
+		result = gen_reg_rtx (smode);
+
+	      riscv_vector::emit_vec_extract (result, v, index + i);
+
+	      if (i == 1)
+		{
+		  rtx tmp = expand_binop (Pmode, ashl_optab,
+					  gen_lowpart (Pmode, result),
+					  gen_int_mode (32, Pmode), NULL_RTX, 0,
+					  OPTAB_DIRECT);
+		  rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+					   NULL_RTX, 0,
+					   OPTAB_DIRECT);
+		  emit_move_insn (int_reg, tmp2);
+		}
 	    }
+
+	  if (need_int_reg_p)
+	    emit_insn (
+	      gen_movdf (dest, gen_lowpart (GET_MODE (dest), int_reg)));
+	  else
+	    emit_move_insn (dest, int_reg);
 	}
+      else
+	gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+	{
+	  word0 (a) = 0x80000 >> L;
+	  word1 (a) = 0;
+	}
+      else
+	{
+	  word0 (a) = 0;
+	  L -= Exp_shift;
+	  word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+	}
+    }
+
+  return a.d;
+}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-12-01  7:52 ` [PATCH v2] " pan2.li
@ 2023-12-01  8:00   ` juzhe.zhong
  0 siblings, 0 replies; 14+ messages in thread
From: juzhe.zhong @ 2023-12-01  8:00 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 6064 bytes --]


+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
Remove.

+      if (opt_mode.exists (&vmode))  -> if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))

+	      emit_insn (
+		gen_movdi (int_reg, gen_lowpart (GET_MODE (int_reg), dest)));
Use emit_move_insn 

+	    emit_insn (
+	      gen_movdf (dest, gen_lowpart (GET_MODE (dest), int_reg)));
Use emit_move_insn 





juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-12-01 15:52
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v2] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com>
 
If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.
 
This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:
 
rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done
 
PR target/112743
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) and handle DFmode like DImode when EEW is
32bits like ZVE32F.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr112743-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     | 67 +++++++++++++------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 ++++++++++++++
2 files changed, 99 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..996347ee3fd 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,68 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = (smode == DImode || smode == DFmode)
+ && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
       if (num == 2)
{
  /* If we want to extract 64bit value but ELEN < 64,
     we use RVV vector mode with EEW = 32 to extract
     the highpart and lowpart.  */
+   need_int_reg_p = smode == DFmode;
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      opt_machine_mode opt_mode = riscv_vector::get_vector_mode (smode, nunits);
+
+      if (opt_mode.exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+   rtx int_reg = dest;
-   if (i == 1)
+   if (need_int_reg_p)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       int_reg = gen_reg_rtx (DImode);
+       emit_insn (
+ gen_movdi (int_reg, gen_lowpart (GET_MODE (int_reg), dest)));
+     }
+
+   for (unsigned int i = 0; i < num; i++)
+     {
+       rtx result;
+       if (num == 1)
+ result = int_reg;
+       else if (i == 0)
+ result = gen_lowpart (smode, int_reg);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (int_reg, tmp2);
+ }
    }
+
+   if (need_int_reg_p)
+     emit_insn (
+       gen_movdf (dest, gen_lowpart (GET_MODE (dest), int_reg)));
+   else
+     emit_move_insn (dest, int_reg);
}
+      else
+ gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:21 [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f pan2.li
  2023-11-30  7:24 ` juzhe.zhong
  2023-12-01  7:52 ` [PATCH v2] " pan2.li
@ 2023-12-01 10:11 ` pan2.li
  2023-12-01 11:58   ` juzhe.zhong
  2023-12-02  0:59 ` [PATCH v4] " pan2.li
  3 siblings, 1 reply; 14+ messages in thread
From: pan2.li @ 2023-12-01 10:11 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.

This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:

rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done

	PR target/112743

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_legitimize_move): Take the
	exist (U *mode) and handle DFmode like DImode when EEW is
	32bits for ZVE32F.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv.cc                     | 63 +++++++++++++------
 .../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++
 2 files changed, 95 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..2fbaaf01078 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,64 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = (smode == DImode || smode == DFmode)
+	&& !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
 
       if (num == 2)
 	{
 	  /* If we want to extract 64bit value but ELEN < 64,
 	     we use RVV vector mode with EEW = 32 to extract
 	     the highpart and lowpart.  */
+	  need_int_reg_p = smode == DFmode;
 	  smode = SImode;
 	  nunits = nunits * 2;
 	}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
 
-      for (unsigned int i = 0; i < num; i++)
+      if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
 	{
-	  rtx result;
-	  if (num == 1)
-	    result = dest;
-	  else if (i == 0)
-	    result = gen_lowpart (smode, dest);
-	  else
-	    result = gen_reg_rtx (smode);
-	  riscv_vector::emit_vec_extract (result, v, index + i);
+	  rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+	  rtx int_reg = dest;
 
-	  if (i == 1)
+	  if (need_int_reg_p)
 	    {
-	      rtx tmp
-		= expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
-				gen_int_mode (32, Pmode), NULL_RTX, 0,
-				OPTAB_DIRECT);
-	      rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-				       OPTAB_DIRECT);
-	      emit_move_insn (dest, tmp2);
+	      int_reg = gen_reg_rtx (DImode);
+	      emit_move_insn (int_reg, gen_lowpart (GET_MODE (int_reg), dest));
 	    }
+
+	  for (unsigned int i = 0; i < num; i++)
+	    {
+	      rtx result;
+	      if (num == 1)
+		result = int_reg;
+	      else if (i == 0)
+		result = gen_lowpart (smode, int_reg);
+	      else
+		result = gen_reg_rtx (smode);
+
+	      riscv_vector::emit_vec_extract (result, v, index + i);
+
+	      if (i == 1)
+		{
+		  rtx tmp = expand_binop (Pmode, ashl_optab,
+					  gen_lowpart (Pmode, result),
+					  gen_int_mode (32, Pmode), NULL_RTX, 0,
+					  OPTAB_DIRECT);
+		  rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+					   NULL_RTX, 0,
+					   OPTAB_DIRECT);
+		  emit_move_insn (int_reg, tmp2);
+		}
+	    }
+
+	  if (need_int_reg_p)
+	    emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
+	  else
+	    emit_move_insn (dest, int_reg);
 	}
+      else
+	gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+	{
+	  word0 (a) = 0x80000 >> L;
+	  word1 (a) = 0;
+	}
+      else
+	{
+	  word0 (a) = 0;
+	  L -= Exp_shift;
+	  word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+	}
+    }
+
+  return a.d;
+}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-12-01 10:11 ` [PATCH v3] " pan2.li
@ 2023-12-01 11:58   ` juzhe.zhong
  0 siblings, 0 replies; 14+ messages in thread
From: juzhe.zhong @ 2023-12-01 11:58 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 5795 bytes --]

One more comment:

+      unsigned int num = (smode == DImode || smode == DFmode)
+ && !TARGET_VECTOR_ELEN_64 ? 2 : 1;

change it into:

unsigned int num = known_eq (GET_MODE_SIZE (smode), 8) && !TARGET_VECTOR_ELEN_64 ? 2 : 1;



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-12-01 18:11
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v3] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com>
 
If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.
 
This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:
 
rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done
 
PR target/112743
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) and handle DFmode like DImode when EEW is
32bits for ZVE32F.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr112743-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     | 63 +++++++++++++------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++
2 files changed, 95 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..2fbaaf01078 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,64 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = (smode == DImode || smode == DFmode)
+ && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
       if (num == 2)
{
  /* If we want to extract 64bit value but ELEN < 64,
     we use RVV vector mode with EEW = 32 to extract
     the highpart and lowpart.  */
+   need_int_reg_p = smode == DFmode;
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+   rtx int_reg = dest;
-   if (i == 1)
+   if (need_int_reg_p)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       int_reg = gen_reg_rtx (DImode);
+       emit_move_insn (int_reg, gen_lowpart (GET_MODE (int_reg), dest));
    }
+
+   for (unsigned int i = 0; i < num; i++)
+     {
+       rtx result;
+       if (num == 1)
+ result = int_reg;
+       else if (i == 0)
+ result = gen_lowpart (smode, int_reg);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (int_reg, tmp2);
+ }
+     }
+
+   if (need_int_reg_p)
+     emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
+   else
+     emit_move_insn (dest, int_reg);
}
+      else
+ gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-11-30  7:21 [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f pan2.li
                   ` (2 preceding siblings ...)
  2023-12-01 10:11 ` [PATCH v3] " pan2.li
@ 2023-12-02  0:59 ` pan2.li
  2023-12-02  1:09   ` 钟居哲
  3 siblings, 1 reply; 14+ messages in thread
From: pan2.li @ 2023-12-02  0:59 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.

This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:

rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done

	PR target/112743

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_legitimize_move): Take the
	exist (U *mode) and handle DFmode like DImode when EEW is
	32bits for ZVE32F.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv.cc                     | 63 +++++++++++++------
 .../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++
 2 files changed, 95 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..84512dcdc68 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,64 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = known_eq (GET_MODE_SIZE (smode), 8)
+	&& !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
 
       if (num == 2)
 	{
 	  /* If we want to extract 64bit value but ELEN < 64,
 	     we use RVV vector mode with EEW = 32 to extract
 	     the highpart and lowpart.  */
+	  need_int_reg_p = smode == DFmode;
 	  smode = SImode;
 	  nunits = nunits * 2;
 	}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
 
-      for (unsigned int i = 0; i < num; i++)
+      if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
 	{
-	  rtx result;
-	  if (num == 1)
-	    result = dest;
-	  else if (i == 0)
-	    result = gen_lowpart (smode, dest);
-	  else
-	    result = gen_reg_rtx (smode);
-	  riscv_vector::emit_vec_extract (result, v, index + i);
+	  rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+	  rtx int_reg = dest;
 
-	  if (i == 1)
+	  if (need_int_reg_p)
 	    {
-	      rtx tmp
-		= expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
-				gen_int_mode (32, Pmode), NULL_RTX, 0,
-				OPTAB_DIRECT);
-	      rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-				       OPTAB_DIRECT);
-	      emit_move_insn (dest, tmp2);
+	      int_reg = gen_reg_rtx (DImode);
+	      emit_move_insn (int_reg, gen_lowpart (GET_MODE (int_reg), dest));
 	    }
+
+	  for (unsigned int i = 0; i < num; i++)
+	    {
+	      rtx result;
+	      if (num == 1)
+		result = int_reg;
+	      else if (i == 0)
+		result = gen_lowpart (smode, int_reg);
+	      else
+		result = gen_reg_rtx (smode);
+
+	      riscv_vector::emit_vec_extract (result, v, index + i);
+
+	      if (i == 1)
+		{
+		  rtx tmp = expand_binop (Pmode, ashl_optab,
+					  gen_lowpart (Pmode, result),
+					  gen_int_mode (32, Pmode), NULL_RTX, 0,
+					  OPTAB_DIRECT);
+		  rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+					   NULL_RTX, 0,
+					   OPTAB_DIRECT);
+		  emit_move_insn (int_reg, tmp2);
+		}
+	    }
+
+	  if (need_int_reg_p)
+	    emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
+	  else
+	    emit_move_insn (dest, int_reg);
 	}
+      else
+	gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+	{
+	  word0 (a) = 0x80000 >> L;
+	  word1 (a) = 0;
+	}
+      else
+	{
+	  word0 (a) = 0;
+	  L -= Exp_shift;
+	  word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+	}
+    }
+
+  return a.d;
+}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-12-02  0:59 ` [PATCH v4] " pan2.li
@ 2023-12-02  1:09   ` 钟居哲
  2023-12-02  3:19     ` Li, Pan2
  0 siblings, 1 reply; 14+ messages in thread
From: 钟居哲 @ 2023-12-02  1:09 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 5565 bytes --]

LGTM



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-12-02 08:59
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v4] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com>
 
If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.
 
This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:
 
rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done
 
PR target/112743
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) and handle DFmode like DImode when EEW is
32bits for ZVE32F.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr112743-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     | 63 +++++++++++++------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++
2 files changed, 95 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..84512dcdc68 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,64 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = known_eq (GET_MODE_SIZE (smode), 8)
+ && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
       if (num == 2)
{
  /* If we want to extract 64bit value but ELEN < 64,
     we use RVV vector mode with EEW = 32 to extract
     the highpart and lowpart.  */
+   need_int_reg_p = smode == DFmode;
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+   rtx int_reg = dest;
-   if (i == 1)
+   if (need_int_reg_p)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       int_reg = gen_reg_rtx (DImode);
+       emit_move_insn (int_reg, gen_lowpart (GET_MODE (int_reg), dest));
    }
+
+   for (unsigned int i = 0; i < num; i++)
+     {
+       rtx result;
+       if (num == 1)
+ result = int_reg;
+       else if (i == 0)
+ result = gen_lowpart (smode, int_reg);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (int_reg, tmp2);
+ }
+     }
+
+   if (need_int_reg_p)
+     emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
+   else
+     emit_move_insn (dest, int_reg);
}
+      else
+ gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v4] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
  2023-12-02  1:09   ` 钟居哲
@ 2023-12-02  3:19     ` Li, Pan2
  0 siblings, 0 replies; 14+ messages in thread
From: Li, Pan2 @ 2023-12-02  3:19 UTC (permalink / raw)
  To: 钟居哲, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 6227 bytes --]

Committed, thanks Juzhe.

Pan

From: 钟居哲 <juzhe.zhong@rivai.ai>
Sent: Saturday, December 2, 2023 9:10 AM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v4] RISC-V: Bugfix for legitimize move when get vec mode in zve32f

LGTM

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-12-02 08:59
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v4] RISC-V: Bugfix for legitimize move when get vec mode in zve32f
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

If we want to extract 64bit value but ELEN < 64, we use RVV
vector mode with EEW = 32 to extract the highpart and lowpart.
However, this approach doesn't honor DFmode when movdf pattern
when ZVE32f and of course results in ICE when zve32f.

This patch would like to reuse the approach with some additional
handing, consider lowpart bits is meaningless for FP mode, we need
one int reg as bridge here. For example:

rtx tmp = gen_rtx_reg (DImode)
reg:DI = reg:DF (fmv.d.x) // Move DF reg to DI
...
perform the extract for high and low parts
...
reg:DF = reg:DI (fmv.x.d) // Move DI reg back to DF after all done

PR target/112743

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_legitimize_move): Take the
exist (U *mode) and handle DFmode like DImode when EEW is
32bits for ZVE32F.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr112743-2.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv.cc                     | 63 +++++++++++++------
.../gcc.target/riscv/rvv/base/pr112743-2.c    | 52 +++++++++++++++
2 files changed, 95 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4fc858fb50..84512dcdc68 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2605,41 +2605,64 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       unsigned int nunits = vmode_size > mode_size ? vmode_size / mode_size : 1;
       scalar_mode smode = as_a<scalar_mode> (mode);
       unsigned int index = SUBREG_BYTE (src).to_constant () / mode_size;
-      unsigned int num = smode == DImode && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      unsigned int num = known_eq (GET_MODE_SIZE (smode), 8)
+ && !TARGET_VECTOR_ELEN_64 ? 2 : 1;
+      bool need_int_reg_p = false;
       if (num == 2)
{
  /* If we want to extract 64bit value but ELEN < 64,
     we use RVV vector mode with EEW = 32 to extract
     the highpart and lowpart.  */
+   need_int_reg_p = smode == DFmode;
  smode = SImode;
  nunits = nunits * 2;
}
-      vmode = riscv_vector::get_vector_mode (smode, nunits).require ();
-      rtx v = gen_lowpart (vmode, SUBREG_REG (src));
-      for (unsigned int i = 0; i < num; i++)
+      if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
{
-   rtx result;
-   if (num == 1)
-     result = dest;
-   else if (i == 0)
-     result = gen_lowpart (smode, dest);
-   else
-     result = gen_reg_rtx (smode);
-   riscv_vector::emit_vec_extract (result, v, index + i);
+   rtx v = gen_lowpart (vmode, SUBREG_REG (src));
+   rtx int_reg = dest;
-   if (i == 1)
+   if (need_int_reg_p)
    {
-       rtx tmp
- = expand_binop (Pmode, ashl_optab, gen_lowpart (Pmode, result),
- gen_int_mode (32, Pmode), NULL_RTX, 0,
- OPTAB_DIRECT);
-       rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, dest, NULL_RTX, 0,
-        OPTAB_DIRECT);
-       emit_move_insn (dest, tmp2);
+       int_reg = gen_reg_rtx (DImode);
+       emit_move_insn (int_reg, gen_lowpart (GET_MODE (int_reg), dest));
    }
+
+   for (unsigned int i = 0; i < num; i++)
+     {
+       rtx result;
+       if (num == 1)
+ result = int_reg;
+       else if (i == 0)
+ result = gen_lowpart (smode, int_reg);
+       else
+ result = gen_reg_rtx (smode);
+
+       riscv_vector::emit_vec_extract (result, v, index + i);
+
+       if (i == 1)
+ {
+   rtx tmp = expand_binop (Pmode, ashl_optab,
+   gen_lowpart (Pmode, result),
+   gen_int_mode (32, Pmode), NULL_RTX, 0,
+   OPTAB_DIRECT);
+   rtx tmp2 = expand_binop (Pmode, ior_optab, tmp, int_reg,
+    NULL_RTX, 0,
+    OPTAB_DIRECT);
+   emit_move_insn (int_reg, tmp2);
+ }
+     }
+
+   if (need_int_reg_p)
+     emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
+   else
+     emit_move_insn (dest, int_reg);
}
+      else
+ gcc_unreachable ();
+
       return true;
     }
   /* Expand
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
new file mode 100644
index 00000000000..fdb35fd70f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr112743-2.c
@@ -0,0 +1,52 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvfh_zfh -mabi=lp64 -O2" } */
+
+#include <sys/types.h>
+
+union double_union
+{
+  double d;
+  __uint32_t i[2];
+};
+
+#define word0(x)  (x.i[1])
+#define word1(x)  (x.i[0])
+
+#define P         53
+#define Exp_shift 20
+#define Exp_msk1  ((__uint32_t)0x100000L)
+#define Exp_mask  ((__uint32_t)0x7ff00000L)
+
+double ulp (double _x)
+{
+  union double_union x, a;
+  register int L;
+
+  x.d = _x;
+  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+
+  if (L > 0)
+    {
+      L |= Exp_msk1 >> 4;
+      word0 (a) = L;
+      word1 (a) = 0;
+    }
+  else
+    {
+      L = -L >> Exp_shift;
+      if (L < Exp_shift)
+ {
+   word0 (a) = 0x80000 >> L;
+   word1 (a) = 0;
+ }
+      else
+ {
+   word0 (a) = 0;
+   L -= Exp_shift;
+   word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ }
+    }
+
+  return a.d;
+}
--
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-12-02  3:19 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-30  7:21 [PATCH v1] RISC-V: Bugfix for legitimize move when get vec mode in zve32f pan2.li
2023-11-30  7:24 ` juzhe.zhong
2023-11-30  7:31   ` Li, Pan2
2023-11-30  7:32     ` juzhe.zhong
2023-11-30  7:42       ` Li, Pan2
2023-11-30  7:54         ` juzhe.zhong
2023-11-30  8:00           ` Li, Pan2
2023-12-01  7:52 ` [PATCH v2] " pan2.li
2023-12-01  8:00   ` juzhe.zhong
2023-12-01 10:11 ` [PATCH v3] " pan2.li
2023-12-01 11:58   ` juzhe.zhong
2023-12-02  0:59 ` [PATCH v4] " pan2.li
2023-12-02  1:09   ` 钟居哲
2023-12-02  3:19     ` Li, Pan2

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).