diff mbox series

[v2] RISC-V: Bugfix for resolve_overloaded_builtin[PR113420]

Message ID 20240122041131.27552-1-xuli1@eswincomputing.com
State New
Headers show
Series [v2] RISC-V: Bugfix for resolve_overloaded_builtin[PR113420] | expand

Commit Message

Li Xu Jan. 22, 2024, 4:11 a.m. UTC
From: xuli <xuli1@eswincomputing.com>

v2:
Avoid internal ICE for the case below.
vint8mf8_t test_vle8_v_i8mf8_m(vbool64_t vm, const int32_t *rs1, size_t vl) {
  return __riscv_vle8(vm, rs1, vl);
}

v1:
Change the hash value of overloaded intrinsic from considering
all parameter types to:
1. Encoding vector data type
2. In order to distinguish vle8_v_i8mf8_m(vbool64_t vm, const int8_t *rs1, size_t vl)
   and vle8_v_u8mf8_m(vbool64_t vm, const uint8_t *rs1, size_t vl), encode the pointer type
3. In order to distinguish vfadd_vv_f32mf2_rm(vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
   and vfadd_vv_f32mf2(vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl), encode the number of
   parameters. The same goes for the vxrm intrinsics.

        PR target/113420

gcc/ChangeLog:

        * config/riscv/riscv-vector-builtins.cc (has_vxrm_or_frm_p):remove.
        (registered_function::overloaded_hash):refacotr.
        (resolve_overloaded_builtin):avoid interal ICE.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/base/pr113420-1.c: New test.
        * gcc.target/riscv/rvv/base/pr113420-2.c: New test.
---
 gcc/config/riscv/riscv-vector-builtins.cc     | 93 ++++---------------
 .../gcc.target/riscv/rvv/base/pr113420-1.c    | 30 ++++++
 .../gcc.target/riscv/rvv/base/pr113420-2.c    | 31 +++++++
 3 files changed, 77 insertions(+), 77 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c

Comments

juzhe.zhong@rivai.ai Jan. 22, 2024, 6:40 a.m. UTC | #1
LGTM.



juzhe.zhong@rivai.ai
 
From: Li Xu
Date: 2024-01-22 12:11
To: gcc-patches
CC: kito.cheng; palmer; juzhe.zhong; xuli
Subject: [PATCH v2] RISC-V: Bugfix for resolve_overloaded_builtin[PR113420]
From: xuli <xuli1@eswincomputing.com>
 
v2:
Avoid internal ICE for the case below.
vint8mf8_t test_vle8_v_i8mf8_m(vbool64_t vm, const int32_t *rs1, size_t vl) {
  return __riscv_vle8(vm, rs1, vl);
}
 
v1:
Change the hash value of overloaded intrinsic from considering
all parameter types to:
1. Encoding vector data type
2. In order to distinguish vle8_v_i8mf8_m(vbool64_t vm, const int8_t *rs1, size_t vl)
   and vle8_v_u8mf8_m(vbool64_t vm, const uint8_t *rs1, size_t vl), encode the pointer type
3. In order to distinguish vfadd_vv_f32mf2_rm(vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
   and vfadd_vv_f32mf2(vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl), encode the number of
   parameters. The same goes for the vxrm intrinsics.
 
        PR target/113420
 
gcc/ChangeLog:
 
        * config/riscv/riscv-vector-builtins.cc (has_vxrm_or_frm_p):remove.
        (registered_function::overloaded_hash):refacotr.
        (resolve_overloaded_builtin):avoid interal ICE.
 
gcc/testsuite/ChangeLog:
 
        * gcc.target/riscv/rvv/base/pr113420-1.c: New test.
        * gcc.target/riscv/rvv/base/pr113420-2.c: New test.
---
gcc/config/riscv/riscv-vector-builtins.cc     | 93 ++++---------------
.../gcc.target/riscv/rvv/base/pr113420-1.c    | 30 ++++++
.../gcc.target/riscv/rvv/base/pr113420-2.c    | 31 +++++++
3 files changed, 77 insertions(+), 77 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
 
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 25e0b6e56de..c0e7af482da 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4271,24 +4271,22 @@ registered_function::overloaded_hash () const
: TYPE_UNSIGNED (type);
       mode_p = POINTER_TYPE_P (type) ? TYPE_MODE (TREE_TYPE (type))
     : TYPE_MODE (type);
-      h.add_int (unsigned_p);
-      h.add_int (mode_p);
+      if (POINTER_TYPE_P (type) || lookup_vector_type_attribute (type))
+ {
+   h.add_int (unsigned_p);
+   h.add_int (mode_p);
+ }
+      else if (instance.base->may_require_vxrm_p ()
+        || instance.base->may_require_frm_p ())
+ {
+   h.add_int (argument_types.length ());
+   break;
+ }
     }
   return h.end ();
}
-bool
-has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
-{
-  if (instance.base->may_require_vxrm_p ()
-      || (instance.base->may_require_frm_p ()
-   && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
-       == INTEGER_TYPE)))
-    return true;
-  return false;
-}
-
hashval_t
registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
{
@@ -4296,68 +4294,8 @@ registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
   unsigned int len = arglist.length ();
   for (unsigned int i = 0; i < len; i++)
-    {
-      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
-      When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
-       form is used. The compiler recognizes that the parameter index is signed
-       int, which is inconsistent with size_t, so the index is converted to
-       size_t type in order to get correct hash value. vint8m2_t
-       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
-       is the same as above. */
-      if ((instance.base == bases::vget && (i == (len - 1)))
-   || ((instance.base == bases::vset
-               || instance.shape == shapes::crypto_vi)
-             && (i == (len - 2))))
- argument_types.safe_push (size_type_node);
-      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
-      For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
-      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
-      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
-      recognizes that the parameter vxrm is a signed int, which is inconsistent
-      with the parameter unsigned int vxrm declared by intrinsic, so the
-      parameter vxrm is converted to an unsigned int type in order to get
-      correct hash value.
-
-      Vector Floating-Point Instructions requiring argument frm.
-      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
-      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
-      Taking vfadd as an example, theoretically we can add base or shape to the
-      hash value to distinguish whether the frm parameter is required.
-      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
-      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
-      frm, size_t vl);
-
-     However, the current registration mechanism of overloaded intinsic for gcc
-      limits the intrinsic obtained by entering the hook to always be vfadd, not
-      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
-      parameter list and overload name, base or shape.
-      +--------+---------------------------+-------------------+
-      | index  | name                      | kind              |
-      +--------+---------------------------+-------------------+
-      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
-      +--------+---------------------------+-------------------+
-      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
-      +--------+---------------------------+-------------------+
-      | 124737 | __riscv_vfadd             | Placeholder       |
-      +--------+---------------------------+-------------------+
-      | ...                                                    |
-      +--------+---------------------------+-------------------+
-      | ...                                                    |
-      +--------+---------------------------+-------------------+
-      | 125739 | __riscv_vfadd             | Overloaded        |
-      +--------+---------------------------+-------------------+
-      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
-      +--------+---------------------------+-------------------+
-      | 125743 | __riscv_vfadd             | Placeholder       |
-      +--------+---------------------------+-------------------+
-
-     Therefore, the hash value cannot be added with base or shape, and needs
-      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
-      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
- argument_types.safe_push (unsigned_type_node);
-      else
- argument_types.safe_push (TREE_TYPE (arglist[i]));
-    }
+    argument_types.safe_push (TREE_TYPE (arglist[i]));
+
   return overloaded_hash ();
}
@@ -4611,8 +4549,9 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  gcc_assert (rfn);
-  return rfn->decl;
+  if (rfn)
+    return rfn->decl;
+  return NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
new file mode 100644
index 00000000000..d17f22804ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+void
+matrix_transpose_intrinsics (float *dst, float *src, size_t n)
+{
+  for (size_t row_id = 0; row_id < n; ++row_id)
+    { // input row-index
+      size_t avl = n;
+      // source pointer to row_id-th row
+      float *row_src = src + row_id * n;
+      // destination pointer to row_id-th column
+      float *row_dst = dst + row_id;
+      while (avl > 0)
+ {
+   size_t vl = __riscv_vsetvl_e32m1 (avl);
+   vfloat32m1_t row = __riscv_vle32_v_f32m1 (row_src, vl);
+   __riscv_vsse32 (row_dst, sizeof (float) * n, row, vl);
+   // updating application vector length
+   avl -= vl;
+   // updating source and destination pointers
+   row_src += vl;
+   row_dst += vl * n;
+ }
+    }
+}
+
+/* { dg-final { scan-assembler-times {vsse32\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
new file mode 100644
index 00000000000..76bdc01f94d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8mf8_t
+test_vle8_v_i8mf8_m (vbool64_t vm, const int8_t *rs1, size_t vl)
+{
+  return __riscv_vle8 (vm, rs1, vl);
+}
+
+vuint8mf8_t
+test_vle8_v_u8mf8_m (vbool64_t vm, const uint8_t *rs1, size_t vl)
+{
+  return __riscv_vle8 (vm, rs1, vl);
+}
+
+vfloat32mf2_t
+test_vfadd_vv_f32mf2 (vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
+{
+  return __riscv_vfadd (vs2, vs1, vl);
+}
+
+vfloat32mf2_t
+test_vfadd_vv_f32mf2_rm (vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
+{
+  return __riscv_vfadd (vs2, vs1, __RISCV_FRM_RNE, vl);
+}
+
+/* { dg-final { scan-assembler-times {vle8\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vfadd\.v} 2 } } */
Li Xu Jan. 22, 2024, 6:49 a.m. UTC | #2
Committed, thanks



xuli1@eswincomputing.com
 
From: juzhe.zhong@rivai.ai
Date: 2024-01-22 14:40
To: Li Xu; gcc-patches
CC: kito.cheng; palmer; Li Xu
Subject: Re: [PATCH v2] RISC-V: Bugfix for resolve_overloaded_builtin[PR113420]
LGTM.



juzhe.zhong@rivai.ai
 
From: Li Xu
Date: 2024-01-22 12:11
To: gcc-patches
CC: kito.cheng; palmer; juzhe.zhong; xuli
Subject: [PATCH v2] RISC-V: Bugfix for resolve_overloaded_builtin[PR113420]
From: xuli <xuli1@eswincomputing.com>
 
v2:
Avoid internal ICE for the case below.
vint8mf8_t test_vle8_v_i8mf8_m(vbool64_t vm, const int32_t *rs1, size_t vl) {
  return __riscv_vle8(vm, rs1, vl);
}
 
v1:
Change the hash value of overloaded intrinsic from considering
all parameter types to:
1. Encoding vector data type
2. In order to distinguish vle8_v_i8mf8_m(vbool64_t vm, const int8_t *rs1, size_t vl)
   and vle8_v_u8mf8_m(vbool64_t vm, const uint8_t *rs1, size_t vl), encode the pointer type
3. In order to distinguish vfadd_vv_f32mf2_rm(vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
   and vfadd_vv_f32mf2(vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl), encode the number of
   parameters. The same goes for the vxrm intrinsics.
 
        PR target/113420
 
gcc/ChangeLog:
 
        * config/riscv/riscv-vector-builtins.cc (has_vxrm_or_frm_p):remove.
        (registered_function::overloaded_hash):refacotr.
        (resolve_overloaded_builtin):avoid interal ICE.
 
gcc/testsuite/ChangeLog:
 
        * gcc.target/riscv/rvv/base/pr113420-1.c: New test.
        * gcc.target/riscv/rvv/base/pr113420-2.c: New test.
---
gcc/config/riscv/riscv-vector-builtins.cc     | 93 ++++---------------
.../gcc.target/riscv/rvv/base/pr113420-1.c    | 30 ++++++
.../gcc.target/riscv/rvv/base/pr113420-2.c    | 31 +++++++
3 files changed, 77 insertions(+), 77 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
 
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 25e0b6e56de..c0e7af482da 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4271,24 +4271,22 @@ registered_function::overloaded_hash () const
: TYPE_UNSIGNED (type);
       mode_p = POINTER_TYPE_P (type) ? TYPE_MODE (TREE_TYPE (type))
     : TYPE_MODE (type);
-      h.add_int (unsigned_p);
-      h.add_int (mode_p);
+      if (POINTER_TYPE_P (type) || lookup_vector_type_attribute (type))
+ {
+   h.add_int (unsigned_p);
+   h.add_int (mode_p);
+ }
+      else if (instance.base->may_require_vxrm_p ()
+        || instance.base->may_require_frm_p ())
+ {
+   h.add_int (argument_types.length ());
+   break;
+ }
     }
   return h.end ();
}
-bool
-has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
-{
-  if (instance.base->may_require_vxrm_p ()
-      || (instance.base->may_require_frm_p ()
-   && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
-       == INTEGER_TYPE)))
-    return true;
-  return false;
-}
-
hashval_t
registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
{
@@ -4296,68 +4294,8 @@ registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
   unsigned int len = arglist.length ();
   for (unsigned int i = 0; i < len; i++)
-    {
-      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
-      When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
-       form is used. The compiler recognizes that the parameter index is signed
-       int, which is inconsistent with size_t, so the index is converted to
-       size_t type in order to get correct hash value. vint8m2_t
-       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
-       is the same as above. */
-      if ((instance.base == bases::vget && (i == (len - 1)))
-   || ((instance.base == bases::vset
-               || instance.shape == shapes::crypto_vi)
-             && (i == (len - 2))))
- argument_types.safe_push (size_type_node);
-      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
-      For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
-      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
-      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
-      recognizes that the parameter vxrm is a signed int, which is inconsistent
-      with the parameter unsigned int vxrm declared by intrinsic, so the
-      parameter vxrm is converted to an unsigned int type in order to get
-      correct hash value.
-
-      Vector Floating-Point Instructions requiring argument frm.
-      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
-      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
-      Taking vfadd as an example, theoretically we can add base or shape to the
-      hash value to distinguish whether the frm parameter is required.
-      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
-      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
-      frm, size_t vl);
-
-     However, the current registration mechanism of overloaded intinsic for gcc
-      limits the intrinsic obtained by entering the hook to always be vfadd, not
-      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
-      parameter list and overload name, base or shape.
-      +--------+---------------------------+-------------------+
-      | index  | name                      | kind              |
-      +--------+---------------------------+-------------------+
-      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
-      +--------+---------------------------+-------------------+
-      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
-      +--------+---------------------------+-------------------+
-      | 124737 | __riscv_vfadd             | Placeholder       |
-      +--------+---------------------------+-------------------+
-      | ...                                                    |
-      +--------+---------------------------+-------------------+
-      | ...                                                    |
-      +--------+---------------------------+-------------------+
-      | 125739 | __riscv_vfadd             | Overloaded        |
-      +--------+---------------------------+-------------------+
-      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
-      +--------+---------------------------+-------------------+
-      | 125743 | __riscv_vfadd             | Placeholder       |
-      +--------+---------------------------+-------------------+
-
-     Therefore, the hash value cannot be added with base or shape, and needs
-      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
-      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
- argument_types.safe_push (unsigned_type_node);
-      else
- argument_types.safe_push (TREE_TYPE (arglist[i]));
-    }
+    argument_types.safe_push (TREE_TYPE (arglist[i]));
+
   return overloaded_hash ();
}
@@ -4611,8 +4549,9 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  gcc_assert (rfn);
-  return rfn->decl;
+  if (rfn)
+    return rfn->decl;
+  return NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
new file mode 100644
index 00000000000..d17f22804ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+void
+matrix_transpose_intrinsics (float *dst, float *src, size_t n)
+{
+  for (size_t row_id = 0; row_id < n; ++row_id)
+    { // input row-index
+      size_t avl = n;
+      // source pointer to row_id-th row
+      float *row_src = src + row_id * n;
+      // destination pointer to row_id-th column
+      float *row_dst = dst + row_id;
+      while (avl > 0)
+ {
+   size_t vl = __riscv_vsetvl_e32m1 (avl);
+   vfloat32m1_t row = __riscv_vle32_v_f32m1 (row_src, vl);
+   __riscv_vsse32 (row_dst, sizeof (float) * n, row, vl);
+   // updating application vector length
+   avl -= vl;
+   // updating source and destination pointers
+   row_src += vl;
+   row_dst += vl * n;
+ }
+    }
+}
+
+/* { dg-final { scan-assembler-times {vsse32\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
new file mode 100644
index 00000000000..76bdc01f94d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8mf8_t
+test_vle8_v_i8mf8_m (vbool64_t vm, const int8_t *rs1, size_t vl)
+{
+  return __riscv_vle8 (vm, rs1, vl);
+}
+
+vuint8mf8_t
+test_vle8_v_u8mf8_m (vbool64_t vm, const uint8_t *rs1, size_t vl)
+{
+  return __riscv_vle8 (vm, rs1, vl);
+}
+
+vfloat32mf2_t
+test_vfadd_vv_f32mf2 (vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
+{
+  return __riscv_vfadd (vs2, vs1, vl);
+}
+
+vfloat32mf2_t
+test_vfadd_vv_f32mf2_rm (vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
+{
+  return __riscv_vfadd (vs2, vs1, __RISCV_FRM_RNE, vl);
+}
+
+/* { dg-final { scan-assembler-times {vle8\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vfadd\.v} 2 } } */
diff mbox series

Patch

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 25e0b6e56de..c0e7af482da 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4271,24 +4271,22 @@  registered_function::overloaded_hash () const
 					 : TYPE_UNSIGNED (type);
       mode_p = POINTER_TYPE_P (type) ? TYPE_MODE (TREE_TYPE (type))
 				     : TYPE_MODE (type);
-      h.add_int (unsigned_p);
-      h.add_int (mode_p);
+      if (POINTER_TYPE_P (type) || lookup_vector_type_attribute (type))
+	{
+	  h.add_int (unsigned_p);
+	  h.add_int (mode_p);
+	}
+      else if (instance.base->may_require_vxrm_p ()
+	       || instance.base->may_require_frm_p ())
+	{
+	  h.add_int (argument_types.length ());
+	  break;
+	}
     }
 
   return h.end ();
 }
 
-bool
-has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
-{
-  if (instance.base->may_require_vxrm_p ()
-      || (instance.base->may_require_frm_p ()
-	  && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
-	      == INTEGER_TYPE)))
-    return true;
-  return false;
-}
-
 hashval_t
 registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
 {
@@ -4296,68 +4294,8 @@  registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
   unsigned int len = arglist.length ();
 
   for (unsigned int i = 0; i < len; i++)
-    {
-      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
-	     When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
-       form is used. The compiler recognizes that the parameter index is signed
-       int, which is inconsistent with size_t, so the index is converted to
-       size_t type in order to get correct hash value. vint8m2_t
-       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
-       is the same as above. */
-      if ((instance.base == bases::vget && (i == (len - 1)))
-	  || ((instance.base == bases::vset
-               || instance.shape == shapes::crypto_vi)
-             && (i == (len - 2))))
-	argument_types.safe_push (size_type_node);
-      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
-	     For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
-      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
-      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
-      recognizes that the parameter vxrm is a signed int, which is inconsistent
-      with the parameter unsigned int vxrm declared by intrinsic, so the
-      parameter vxrm is converted to an unsigned int type in order to get
-      correct hash value.
-
-      Vector Floating-Point Instructions requiring argument frm.
-      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
-      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
-      Taking vfadd as an example, theoretically we can add base or shape to the
-      hash value to distinguish whether the frm parameter is required.
-      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
-      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
-      frm, size_t vl);
-
-	    However, the current registration mechanism of overloaded intinsic for gcc
-      limits the intrinsic obtained by entering the hook to always be vfadd, not
-      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
-      parameter list and overload name, base or shape.
-      +--------+---------------------------+-------------------+
-      | index  | name                      | kind              |
-      +--------+---------------------------+-------------------+
-      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
-      +--------+---------------------------+-------------------+
-      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
-      +--------+---------------------------+-------------------+
-      | 124737 | __riscv_vfadd             | Placeholder       |
-      +--------+---------------------------+-------------------+
-      | ...                                                    |
-      +--------+---------------------------+-------------------+
-      | ...                                                    |
-      +--------+---------------------------+-------------------+
-      | 125739 | __riscv_vfadd             | Overloaded        |
-      +--------+---------------------------+-------------------+
-      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
-      +--------+---------------------------+-------------------+
-      | 125743 | __riscv_vfadd             | Placeholder       |
-      +--------+---------------------------+-------------------+
-
-	    Therefore, the hash value cannot be added with base or shape, and needs
-      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
-      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
-	argument_types.safe_push (unsigned_type_node);
-      else
-	argument_types.safe_push (TREE_TYPE (arglist[i]));
-    }
+    argument_types.safe_push (TREE_TYPE (arglist[i]));
+
   return overloaded_hash ();
 }
 
@@ -4611,8 +4549,9 @@  resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  gcc_assert (rfn);
-  return rfn->decl;
+  if (rfn)
+    return rfn->decl;
+  return NULL_TREE;
 }
 
 function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
new file mode 100644
index 00000000000..d17f22804ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-1.c
@@ -0,0 +1,30 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+void
+matrix_transpose_intrinsics (float *dst, float *src, size_t n)
+{
+  for (size_t row_id = 0; row_id < n; ++row_id)
+    { // input row-index
+      size_t avl = n;
+      // source pointer to row_id-th row
+      float *row_src = src + row_id * n;
+      // destination pointer to row_id-th column
+      float *row_dst = dst + row_id;
+      while (avl > 0)
+	{
+	  size_t vl = __riscv_vsetvl_e32m1 (avl);
+	  vfloat32m1_t row = __riscv_vle32_v_f32m1 (row_src, vl);
+	  __riscv_vsse32 (row_dst, sizeof (float) * n, row, vl);
+	  // updating application vector length
+	  avl -= vl;
+	  // updating source and destination pointers
+	  row_src += vl;
+	  row_dst += vl * n;
+	}
+    }
+}
+
+/* { dg-final { scan-assembler-times {vsse32\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
new file mode 100644
index 00000000000..76bdc01f94d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113420-2.c
@@ -0,0 +1,31 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8mf8_t
+test_vle8_v_i8mf8_m (vbool64_t vm, const int8_t *rs1, size_t vl)
+{
+  return __riscv_vle8 (vm, rs1, vl);
+}
+
+vuint8mf8_t
+test_vle8_v_u8mf8_m (vbool64_t vm, const uint8_t *rs1, size_t vl)
+{
+  return __riscv_vle8 (vm, rs1, vl);
+}
+
+vfloat32mf2_t
+test_vfadd_vv_f32mf2 (vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
+{
+  return __riscv_vfadd (vs2, vs1, vl);
+}
+
+vfloat32mf2_t
+test_vfadd_vv_f32mf2_rm (vfloat32mf2_t vs2, vfloat32mf2_t vs1, size_t vl)
+{
+  return __riscv_vfadd (vs2, vs1, __RISCV_FRM_RNE, vl);
+}
+
+/* { dg-final { scan-assembler-times {vle8\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vfadd\.v} 2 } } */