public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
@ 2024-02-06  8:09 pan2.li
  2024-02-06  8:11 ` juzhe.zhong
  0 siblings, 1 reply; 7+ messages in thread
From: pan2.li @ 2024-02-06  8:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

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

There is one corn case when similar as below example:

void test (void)
{
  __riscv_vfredosum_tu ();
}

It will meet ICE because of the implement details of overloaded function
in gcc.  According to the rvv intrinisc doc, we have no such overloaded
function with empty args.  Unfortunately, we register the empty args
function as overloaded for avoiding conflict.  Thus, there will be actual
one register function after return NULL_TREE back to the middle-end,
and finally result in ICE when expanding.  For example:

1. First we registered void __riscv_vfredmax () as the overloaded function.
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
3. The functions register in step 1 bypass the args check as empty args.
4. Finally, fall into expand_builtin with empty args and meet ICE.

Here we report error when overloaded function with empty args.  For example:

test.c: In function 'foo':
test.c:8:3: error: no matching function call to '__riscv_vfredosum_tu' with empty args
    8 |   __riscv_vfredosum_tu();
      |   ^~~~~~~~~~~~~~~~~~~~

Below test are passed for this patch.

* The riscv regression tests.

	PR target/113766

gcc/ChangeLog:

	* config/riscv/riscv-protos.h (resolve_overloaded_builtin): Adjust
	the signature of func.
	* config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Ditto.
	* config/riscv/riscv-vector-builtins.cc (resolve_overloaded_builtin): Make
	overloaded func with empty args error.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-c.cc                   |  3 +-
 gcc/config/riscv/riscv-protos.h               |  2 +-
 gcc/config/riscv/riscv-vector-builtins.cc     | 23 ++++-
 .../gcc.target/riscv/rvv/base/pr113766-1.c    | 85 +++++++++++++++++++
 .../gcc.target/riscv/rvv/base/pr113766-2.c    | 48 +++++++++++
 5 files changed, 155 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 2e306057347..94c3871c760 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
     case RISCV_BUILTIN_GENERAL:
       break;
     case RISCV_BUILTIN_VECTOR:
-      new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
+      new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
+							     fndecl, arglist);
       break;
     default:
       gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b3f0bdb9924..ae1685850ac 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
 rtx expand_builtin (unsigned int, tree, rtx);
 bool check_builtin_call (location_t, vec<location_t>, unsigned int,
 			   tree, unsigned int, tree *);
-tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
+tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
 bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
 bool legitimize_move (rtx, rtx *);
 void emit_vlmax_vsetvl (machine_mode, rtx);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 403e1021fd1..efcdc8f1767 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
 }
 
 tree
-resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
+			    vec<tree, va_gc> *arglist)
 {
   if (code >= vec_safe_length (registered_functions))
     return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   if (!rfun || !rfun->overloaded_p)
     return NULL_TREE;
 
+  /* According to the rvv intrinisc doc, we have no such overloaded function
+     with empty args.  Unfortunately, we register the empty args function as
+     overloaded for avoiding conflict.  Thus, there will actual one register
+     function after return NULL_TREE back to the middle-end, and finally result
+     in ICE when expanding.  For example:
+
+     1. First we registered void __riscv_vfredmax () as the overloaded function.
+     2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
+     3. The functions register in step 1 bypass the args check as empty args.
+     4. Finally, fall into expand_builtin with empty args and meet ICE.
+
+     Here we report error when overloaded function with empty args.  */
+  if (rfun->overloaded_p && arglist->length () == 0)
+    error_at (loc, "no matching function call to %qE with empty args", fndecl);
+
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  if (rfn)
-    return rfn->decl;
-  return NULL_TREE;
+
+  return rfn ? rfn->decl : NULL_TREE;
 }
 
 function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
new file mode 100644
index 00000000000..bd4943b0b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test ()
+{
+  __riscv_vand ();              /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
+  __riscv_vand_tu ();           /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
+  __riscv_vand_tumu ();         /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
+
+  __riscv_vcompress ();         /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
+  __riscv_vcompress_tu ();      /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
+
+  __riscv_vcpop ();             /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
+
+  __riscv_vdiv ();              /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
+  __riscv_vdiv_tu ();           /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
+  __riscv_vdiv_tumu ();         /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
+
+  __riscv_vfabs ();             /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
+  __riscv_vfabs_tu ();          /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
+  __riscv_vfabs_tumu ();        /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
+
+  __riscv_vfadd ();             /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
+  __riscv_vfadd_tu ();          /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
+  __riscv_vfadd_tumu ();        /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
+
+  __riscv_vfclass ();           /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
+  __riscv_vfclass_tu ();        /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
+  __riscv_vfclass_tumu ();      /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
+
+  __riscv_vfcvt_x ();           /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
+  __riscv_vfcvt_x_tu ();        /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
+  __riscv_vfcvt_x_tumu ();      /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
+
+  __riscv_vfirst ();            /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
+
+  __riscv_vfmadd ();            /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
+  __riscv_vfmadd_tu ();         /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
+  __riscv_vfmadd_tumu ();       /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
+
+  __riscv_vfmerge ();           /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
+  __riscv_vfmerge_tu ();        /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
+
+  __riscv_vfncvt_x ();          /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
+  __riscv_vfncvt_x_tu ();       /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
+  __riscv_vfncvt_x_tumu ();     /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
+
+  __riscv_vfrec7 ();            /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
+  __riscv_vfrec7_tu ();         /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
+  __riscv_vfrec7_tumu ();       /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
+
+  __riscv_vfrsqrt7 ();          /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
+  __riscv_vfrsqrt7_tu ();       /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
+  __riscv_vfrsqrt7_tumu ();     /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
+
+  __riscv_vfsgnjn ();           /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
+  __riscv_vfsgnjn_tu ();        /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
+  __riscv_vfsgnjn_tumu ();     /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
+
+  __riscv_vfslide1down ();      /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
+  __riscv_vfslide1down_tu ();   /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
+  __riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
+
+  __riscv_vfwmul ();            /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
+  __riscv_vfwmul_tu ();         /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
+  __riscv_vfwmul_tumu ();       /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
+
+  __riscv_vle32 ();             /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
+  __riscv_vle32_tu ();          /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
+  __riscv_vle32_tumu ();        /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
+
+  __riscv_vlse64 ();            /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
+  __riscv_vlse64_tu ();         /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
+  __riscv_vlse64_tumu ();       /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
+
+  __riscv_vmfeq ();             /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
+
+  __riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
+
+  __riscv_vfredosum ();         /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
+  __riscv_vfredosum_tu ();      /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
new file mode 100644
index 00000000000..621fb9f1b08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
+{
+  __riscv_vand (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
+
+  __riscv_vcompress (vi32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
+
+  __riscv_vcpop (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
+
+  __riscv_vdiv (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
+
+  __riscv_vfabs (vf32m1);            /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
+
+  __riscv_vfadd (vf32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
+
+  __riscv_vfcvt_x (vf32m1);          /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
+
+  __riscv_vfirst (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
+
+  __riscv_vfmadd (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
+
+  __riscv_vfmerge (vf32m1, vl);      /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
+
+  __riscv_vfncvt_x (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
+
+  __riscv_vfrec7 (vf32m1);           /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
+
+  __riscv_vfrsqrt7 (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
+
+  __riscv_vfsgnjn (vf32m1, vl);      /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
+
+  __riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
+
+  __riscv_vfwmul (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
+
+  __riscv_vle32 (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vle32'} } */
+
+  __riscv_vlse64 (vi64m1, vl);       /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
+
+  __riscv_vmfeq (vf32m1, vl);        /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
+
+  __riscv_vfredosum (vf32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
+}
-- 
2.34.1


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

* Re: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
  2024-02-06  8:09 [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args pan2.li
@ 2024-02-06  8:11 ` juzhe.zhong
  2024-02-06  8:16   ` Li, Pan2
  0 siblings, 1 reply; 7+ messages in thread
From: juzhe.zhong @ 2024-02-06  8:11 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

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

Did you run the C compiler compile C++ intrinsic test ?



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2024-02-06 16:09
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
From: Pan Li <pan2.li@intel.com>
 
There is one corn case when similar as below example:
 
void test (void)
{
  __riscv_vfredosum_tu ();
}
 
It will meet ICE because of the implement details of overloaded function
in gcc.  According to the rvv intrinisc doc, we have no such overloaded
function with empty args.  Unfortunately, we register the empty args
function as overloaded for avoiding conflict.  Thus, there will be actual
one register function after return NULL_TREE back to the middle-end,
and finally result in ICE when expanding.  For example:
 
1. First we registered void __riscv_vfredmax () as the overloaded function.
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
3. The functions register in step 1 bypass the args check as empty args.
4. Finally, fall into expand_builtin with empty args and meet ICE.
 
Here we report error when overloaded function with empty args.  For example:
 
test.c: In function 'foo':
test.c:8:3: error: no matching function call to '__riscv_vfredosum_tu' with empty args
    8 |   __riscv_vfredosum_tu();
      |   ^~~~~~~~~~~~~~~~~~~~
 
Below test are passed for this patch.
 
* The riscv regression tests.
 
PR target/113766
 
gcc/ChangeLog:
 
* config/riscv/riscv-protos.h (resolve_overloaded_builtin): Adjust
the signature of func.
* config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Ditto.
* config/riscv/riscv-vector-builtins.cc (resolve_overloaded_builtin): Make
overloaded func with empty args error.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr113766-1.c: New test.
* gcc.target/riscv/rvv/base/pr113766-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv-c.cc                   |  3 +-
gcc/config/riscv/riscv-protos.h               |  2 +-
gcc/config/riscv/riscv-vector-builtins.cc     | 23 ++++-
.../gcc.target/riscv/rvv/base/pr113766-1.c    | 85 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/pr113766-2.c    | 48 +++++++++++
5 files changed, 155 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
 
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 2e306057347..94c3871c760 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
     case RISCV_BUILTIN_GENERAL:
       break;
     case RISCV_BUILTIN_VECTOR:
-      new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
+      new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
+      fndecl, arglist);
       break;
     default:
       gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b3f0bdb9924..ae1685850ac 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
rtx expand_builtin (unsigned int, tree, rtx);
bool check_builtin_call (location_t, vec<location_t>, unsigned int,
   tree, unsigned int, tree *);
-tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
+tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
bool legitimize_move (rtx, rtx *);
void emit_vlmax_vsetvl (machine_mode, rtx);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 403e1021fd1..efcdc8f1767 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
}
tree
-resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
+     vec<tree, va_gc> *arglist)
{
   if (code >= vec_safe_length (registered_functions))
     return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   if (!rfun || !rfun->overloaded_p)
     return NULL_TREE;
+  /* According to the rvv intrinisc doc, we have no such overloaded function
+     with empty args.  Unfortunately, we register the empty args function as
+     overloaded for avoiding conflict.  Thus, there will actual one register
+     function after return NULL_TREE back to the middle-end, and finally result
+     in ICE when expanding.  For example:
+
+     1. First we registered void __riscv_vfredmax () as the overloaded function.
+     2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
+     3. The functions register in step 1 bypass the args check as empty args.
+     4. Finally, fall into expand_builtin with empty args and meet ICE.
+
+     Here we report error when overloaded function with empty args.  */
+  if (rfun->overloaded_p && arglist->length () == 0)
+    error_at (loc, "no matching function call to %qE with empty args", fndecl);
+
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  if (rfn)
-    return rfn->decl;
-  return NULL_TREE;
+
+  return rfn ? rfn->decl : NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
new file mode 100644
index 00000000000..bd4943b0b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test ()
+{
+  __riscv_vand ();              /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
+  __riscv_vand_tu ();           /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
+  __riscv_vand_tumu ();         /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
+
+  __riscv_vcompress ();         /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
+  __riscv_vcompress_tu ();      /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
+
+  __riscv_vcpop ();             /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
+
+  __riscv_vdiv ();              /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
+  __riscv_vdiv_tu ();           /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
+  __riscv_vdiv_tumu ();         /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
+
+  __riscv_vfabs ();             /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
+  __riscv_vfabs_tu ();          /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
+  __riscv_vfabs_tumu ();        /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
+
+  __riscv_vfadd ();             /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
+  __riscv_vfadd_tu ();          /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
+  __riscv_vfadd_tumu ();        /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
+
+  __riscv_vfclass ();           /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
+  __riscv_vfclass_tu ();        /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
+  __riscv_vfclass_tumu ();      /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
+
+  __riscv_vfcvt_x ();           /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
+  __riscv_vfcvt_x_tu ();        /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
+  __riscv_vfcvt_x_tumu ();      /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
+
+  __riscv_vfirst ();            /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
+
+  __riscv_vfmadd ();            /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
+  __riscv_vfmadd_tu ();         /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
+  __riscv_vfmadd_tumu ();       /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
+
+  __riscv_vfmerge ();           /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
+  __riscv_vfmerge_tu ();        /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
+
+  __riscv_vfncvt_x ();          /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
+  __riscv_vfncvt_x_tu ();       /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
+  __riscv_vfncvt_x_tumu ();     /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
+
+  __riscv_vfrec7 ();            /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
+  __riscv_vfrec7_tu ();         /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
+  __riscv_vfrec7_tumu ();       /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
+
+  __riscv_vfrsqrt7 ();          /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
+  __riscv_vfrsqrt7_tu ();       /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
+  __riscv_vfrsqrt7_tumu ();     /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
+
+  __riscv_vfsgnjn ();           /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
+  __riscv_vfsgnjn_tu ();        /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
+  __riscv_vfsgnjn_tumu ();     /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
+
+  __riscv_vfslide1down ();      /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
+  __riscv_vfslide1down_tu ();   /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
+  __riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
+
+  __riscv_vfwmul ();            /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
+  __riscv_vfwmul_tu ();         /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
+  __riscv_vfwmul_tumu ();       /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
+
+  __riscv_vle32 ();             /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
+  __riscv_vle32_tu ();          /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
+  __riscv_vle32_tumu ();        /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
+
+  __riscv_vlse64 ();            /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
+  __riscv_vlse64_tu ();         /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
+  __riscv_vlse64_tumu ();       /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
+
+  __riscv_vmfeq ();             /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
+
+  __riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
+
+  __riscv_vfredosum ();         /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
+  __riscv_vfredosum_tu ();      /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
new file mode 100644
index 00000000000..621fb9f1b08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
+{
+  __riscv_vand (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
+
+  __riscv_vcompress (vi32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
+
+  __riscv_vcpop (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
+
+  __riscv_vdiv (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
+
+  __riscv_vfabs (vf32m1);            /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
+
+  __riscv_vfadd (vf32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
+
+  __riscv_vfcvt_x (vf32m1);          /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
+
+  __riscv_vfirst (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
+
+  __riscv_vfmadd (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
+
+  __riscv_vfmerge (vf32m1, vl);      /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
+
+  __riscv_vfncvt_x (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
+
+  __riscv_vfrec7 (vf32m1);           /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
+
+  __riscv_vfrsqrt7 (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
+
+  __riscv_vfsgnjn (vf32m1, vl);      /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
+
+  __riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
+
+  __riscv_vfwmul (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
+
+  __riscv_vle32 (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vle32'} } */
+
+  __riscv_vlse64 (vi64m1, vl);       /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
+
+  __riscv_vmfeq (vf32m1, vl);        /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
+
+  __riscv_vfredosum (vf32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
+}
-- 
2.34.1
 
 

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

* RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
  2024-02-06  8:11 ` juzhe.zhong
@ 2024-02-06  8:16   ` Li, Pan2
  2024-02-06 12:46     ` Li, Pan2
  0 siblings, 1 reply; 7+ messages in thread
From: Li, Pan2 @ 2024-02-06  8:16 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

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

Not yet. It is long time since last round run, will make sure there is no surprises from that.

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Tuesday, February 6, 2024 4:11 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 RVV overloaded intrinisc ICE when empty args

Did you run the C compiler compile C++ intrinsic test ?

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

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2024-02-06 16:09
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 RVV overloaded intrinisc ICE when empty args
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

There is one corn case when similar as below example:

void test (void)
{
  __riscv_vfredosum_tu ();
}

It will meet ICE because of the implement details of overloaded function
in gcc.  According to the rvv intrinisc doc, we have no such overloaded
function with empty args.  Unfortunately, we register the empty args
function as overloaded for avoiding conflict.  Thus, there will be actual
one register function after return NULL_TREE back to the middle-end,
and finally result in ICE when expanding.  For example:

1. First we registered void __riscv_vfredmax () as the overloaded function.
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
3. The functions register in step 1 bypass the args check as empty args.
4. Finally, fall into expand_builtin with empty args and meet ICE.

Here we report error when overloaded function with empty args.  For example:

test.c: In function 'foo':
test.c:8:3: error: no matching function call to '__riscv_vfredosum_tu' with empty args
    8 |   __riscv_vfredosum_tu();
      |   ^~~~~~~~~~~~~~~~~~~~

Below test are passed for this patch.

* The riscv regression tests.

PR target/113766

gcc/ChangeLog:

* config/riscv/riscv-protos.h (resolve_overloaded_builtin): Adjust
the signature of func.
* config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Ditto.
* config/riscv/riscv-vector-builtins.cc (resolve_overloaded_builtin): Make
overloaded func with empty args error.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv-c.cc                   |  3 +-
gcc/config/riscv/riscv-protos.h               |  2 +-
gcc/config/riscv/riscv-vector-builtins.cc     | 23 ++++-
.../gcc.target/riscv/rvv/base/pr113766-1.c    | 85 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/pr113766-2.c    | 48 +++++++++++
5 files changed, 155 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 2e306057347..94c3871c760 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
     case RISCV_BUILTIN_GENERAL:
       break;
     case RISCV_BUILTIN_VECTOR:
-      new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
+      new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
+      fndecl, arglist);
       break;
     default:
       gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b3f0bdb9924..ae1685850ac 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
rtx expand_builtin (unsigned int, tree, rtx);
bool check_builtin_call (location_t, vec<location_t>, unsigned int,
   tree, unsigned int, tree *);
-tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
+tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
bool legitimize_move (rtx, rtx *);
void emit_vlmax_vsetvl (machine_mode, rtx);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 403e1021fd1..efcdc8f1767 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
}
tree
-resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
+     vec<tree, va_gc> *arglist)
{
   if (code >= vec_safe_length (registered_functions))
     return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   if (!rfun || !rfun->overloaded_p)
     return NULL_TREE;
+  /* According to the rvv intrinisc doc, we have no such overloaded function
+     with empty args.  Unfortunately, we register the empty args function as
+     overloaded for avoiding conflict.  Thus, there will actual one register
+     function after return NULL_TREE back to the middle-end, and finally result
+     in ICE when expanding.  For example:
+
+     1. First we registered void __riscv_vfredmax () as the overloaded function.
+     2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
+     3. The functions register in step 1 bypass the args check as empty args.
+     4. Finally, fall into expand_builtin with empty args and meet ICE.
+
+     Here we report error when overloaded function with empty args.  */
+  if (rfun->overloaded_p && arglist->length () == 0)
+    error_at (loc, "no matching function call to %qE with empty args", fndecl);
+
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  if (rfn)
-    return rfn->decl;
-  return NULL_TREE;
+
+  return rfn ? rfn->decl : NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
new file mode 100644
index 00000000000..bd4943b0b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test ()
+{
+  __riscv_vand ();              /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
+  __riscv_vand_tu ();           /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
+  __riscv_vand_tumu ();         /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
+
+  __riscv_vcompress ();         /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
+  __riscv_vcompress_tu ();      /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
+
+  __riscv_vcpop ();             /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
+
+  __riscv_vdiv ();              /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
+  __riscv_vdiv_tu ();           /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
+  __riscv_vdiv_tumu ();         /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
+
+  __riscv_vfabs ();             /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
+  __riscv_vfabs_tu ();          /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
+  __riscv_vfabs_tumu ();        /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
+
+  __riscv_vfadd ();             /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
+  __riscv_vfadd_tu ();          /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
+  __riscv_vfadd_tumu ();        /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
+
+  __riscv_vfclass ();           /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
+  __riscv_vfclass_tu ();        /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
+  __riscv_vfclass_tumu ();      /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
+
+  __riscv_vfcvt_x ();           /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
+  __riscv_vfcvt_x_tu ();        /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
+  __riscv_vfcvt_x_tumu ();      /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
+
+  __riscv_vfirst ();            /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
+
+  __riscv_vfmadd ();            /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
+  __riscv_vfmadd_tu ();         /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
+  __riscv_vfmadd_tumu ();       /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
+
+  __riscv_vfmerge ();           /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
+  __riscv_vfmerge_tu ();        /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
+
+  __riscv_vfncvt_x ();          /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
+  __riscv_vfncvt_x_tu ();       /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
+  __riscv_vfncvt_x_tumu ();     /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
+
+  __riscv_vfrec7 ();            /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
+  __riscv_vfrec7_tu ();         /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
+  __riscv_vfrec7_tumu ();       /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
+
+  __riscv_vfrsqrt7 ();          /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
+  __riscv_vfrsqrt7_tu ();       /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
+  __riscv_vfrsqrt7_tumu ();     /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
+
+  __riscv_vfsgnjn ();           /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
+  __riscv_vfsgnjn_tu ();        /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
+  __riscv_vfsgnjn_tumu ();     /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
+
+  __riscv_vfslide1down ();      /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
+  __riscv_vfslide1down_tu ();   /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
+  __riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
+
+  __riscv_vfwmul ();            /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
+  __riscv_vfwmul_tu ();         /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
+  __riscv_vfwmul_tumu ();       /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
+
+  __riscv_vle32 ();             /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
+  __riscv_vle32_tu ();          /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
+  __riscv_vle32_tumu ();        /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
+
+  __riscv_vlse64 ();            /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
+  __riscv_vlse64_tu ();         /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
+  __riscv_vlse64_tumu ();       /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
+
+  __riscv_vmfeq ();             /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
+
+  __riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
+
+  __riscv_vfredosum ();         /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
+  __riscv_vfredosum_tu ();      /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
new file mode 100644
index 00000000000..621fb9f1b08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
+{
+  __riscv_vand (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
+
+  __riscv_vcompress (vi32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
+
+  __riscv_vcpop (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
+
+  __riscv_vdiv (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
+
+  __riscv_vfabs (vf32m1);            /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
+
+  __riscv_vfadd (vf32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
+
+  __riscv_vfcvt_x (vf32m1);          /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
+
+  __riscv_vfirst (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
+
+  __riscv_vfmadd (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
+
+  __riscv_vfmerge (vf32m1, vl);      /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
+
+  __riscv_vfncvt_x (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
+
+  __riscv_vfrec7 (vf32m1);           /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
+
+  __riscv_vfrsqrt7 (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
+
+  __riscv_vfsgnjn (vf32m1, vl);      /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
+
+  __riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
+
+  __riscv_vfwmul (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
+
+  __riscv_vle32 (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vle32'} } */
+
+  __riscv_vlse64 (vi64m1, vl);       /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
+
+  __riscv_vmfeq (vf32m1, vl);        /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
+
+  __riscv_vfredosum (vf32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
+}
--
2.34.1



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

* RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
  2024-02-06  8:16   ` Li, Pan2
@ 2024-02-06 12:46     ` Li, Pan2
  2024-02-07  1:11       ` juzhe.zhong
  0 siblings, 1 reply; 7+ messages in thread
From: Li, Pan2 @ 2024-02-06 12:46 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

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

All passed, include overloaded and non-overloaded.

# of expected passes            10885

Pan

From: Li, Pan2
Sent: Tuesday, February 6, 2024 4:17 PM
To: juzhe.zhong@rivai.ai; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args

Not yet. It is long time since last round run, will make sure there is no surprises from that.

Pan

From: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai> <juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>
Sent: Tuesday, February 6, 2024 4:11 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 RVV overloaded intrinisc ICE when empty args

Did you run the C compiler compile C++ intrinsic test ?

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

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2024-02-06 16:09
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 RVV overloaded intrinisc ICE when empty args
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

There is one corn case when similar as below example:

void test (void)
{
  __riscv_vfredosum_tu ();
}

It will meet ICE because of the implement details of overloaded function
in gcc.  According to the rvv intrinisc doc, we have no such overloaded
function with empty args.  Unfortunately, we register the empty args
function as overloaded for avoiding conflict.  Thus, there will be actual
one register function after return NULL_TREE back to the middle-end,
and finally result in ICE when expanding.  For example:

1. First we registered void __riscv_vfredmax () as the overloaded function.
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
3. The functions register in step 1 bypass the args check as empty args.
4. Finally, fall into expand_builtin with empty args and meet ICE.

Here we report error when overloaded function with empty args.  For example:

test.c: In function 'foo':
test.c:8:3: error: no matching function call to '__riscv_vfredosum_tu' with empty args
    8 |   __riscv_vfredosum_tu();
      |   ^~~~~~~~~~~~~~~~~~~~

Below test are passed for this patch.

* The riscv regression tests.

PR target/113766

gcc/ChangeLog:

* config/riscv/riscv-protos.h (resolve_overloaded_builtin): Adjust
the signature of func.
* config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Ditto.
* config/riscv/riscv-vector-builtins.cc (resolve_overloaded_builtin): Make
overloaded func with empty args error.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv-c.cc                   |  3 +-
gcc/config/riscv/riscv-protos.h               |  2 +-
gcc/config/riscv/riscv-vector-builtins.cc     | 23 ++++-
.../gcc.target/riscv/rvv/base/pr113766-1.c    | 85 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/pr113766-2.c    | 48 +++++++++++
5 files changed, 155 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 2e306057347..94c3871c760 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
     case RISCV_BUILTIN_GENERAL:
       break;
     case RISCV_BUILTIN_VECTOR:
-      new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
+      new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
+      fndecl, arglist);
       break;
     default:
       gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b3f0bdb9924..ae1685850ac 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
rtx expand_builtin (unsigned int, tree, rtx);
bool check_builtin_call (location_t, vec<location_t>, unsigned int,
   tree, unsigned int, tree *);
-tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
+tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
bool legitimize_move (rtx, rtx *);
void emit_vlmax_vsetvl (machine_mode, rtx);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 403e1021fd1..efcdc8f1767 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
}
tree
-resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
+     vec<tree, va_gc> *arglist)
{
   if (code >= vec_safe_length (registered_functions))
     return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   if (!rfun || !rfun->overloaded_p)
     return NULL_TREE;
+  /* According to the rvv intrinisc doc, we have no such overloaded function
+     with empty args.  Unfortunately, we register the empty args function as
+     overloaded for avoiding conflict.  Thus, there will actual one register
+     function after return NULL_TREE back to the middle-end, and finally result
+     in ICE when expanding.  For example:
+
+     1. First we registered void __riscv_vfredmax () as the overloaded function.
+     2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
+     3. The functions register in step 1 bypass the args check as empty args.
+     4. Finally, fall into expand_builtin with empty args and meet ICE.
+
+     Here we report error when overloaded function with empty args.  */
+  if (rfun->overloaded_p && arglist->length () == 0)
+    error_at (loc, "no matching function call to %qE with empty args", fndecl);
+
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  if (rfn)
-    return rfn->decl;
-  return NULL_TREE;
+
+  return rfn ? rfn->decl : NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
new file mode 100644
index 00000000000..bd4943b0b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test ()
+{
+  __riscv_vand ();              /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
+  __riscv_vand_tu ();           /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
+  __riscv_vand_tumu ();         /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
+
+  __riscv_vcompress ();         /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
+  __riscv_vcompress_tu ();      /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
+
+  __riscv_vcpop ();             /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
+
+  __riscv_vdiv ();              /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
+  __riscv_vdiv_tu ();           /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
+  __riscv_vdiv_tumu ();         /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
+
+  __riscv_vfabs ();             /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
+  __riscv_vfabs_tu ();          /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
+  __riscv_vfabs_tumu ();        /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
+
+  __riscv_vfadd ();             /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
+  __riscv_vfadd_tu ();          /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
+  __riscv_vfadd_tumu ();        /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
+
+  __riscv_vfclass ();           /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
+  __riscv_vfclass_tu ();        /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
+  __riscv_vfclass_tumu ();      /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
+
+  __riscv_vfcvt_x ();           /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
+  __riscv_vfcvt_x_tu ();        /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
+  __riscv_vfcvt_x_tumu ();      /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
+
+  __riscv_vfirst ();            /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
+
+  __riscv_vfmadd ();            /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
+  __riscv_vfmadd_tu ();         /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
+  __riscv_vfmadd_tumu ();       /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
+
+  __riscv_vfmerge ();           /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
+  __riscv_vfmerge_tu ();        /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
+
+  __riscv_vfncvt_x ();          /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
+  __riscv_vfncvt_x_tu ();       /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
+  __riscv_vfncvt_x_tumu ();     /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
+
+  __riscv_vfrec7 ();            /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
+  __riscv_vfrec7_tu ();         /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
+  __riscv_vfrec7_tumu ();       /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
+
+  __riscv_vfrsqrt7 ();          /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
+  __riscv_vfrsqrt7_tu ();       /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
+  __riscv_vfrsqrt7_tumu ();     /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
+
+  __riscv_vfsgnjn ();           /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
+  __riscv_vfsgnjn_tu ();        /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
+  __riscv_vfsgnjn_tumu ();     /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
+
+  __riscv_vfslide1down ();      /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
+  __riscv_vfslide1down_tu ();   /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
+  __riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
+
+  __riscv_vfwmul ();            /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
+  __riscv_vfwmul_tu ();         /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
+  __riscv_vfwmul_tumu ();       /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
+
+  __riscv_vle32 ();             /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
+  __riscv_vle32_tu ();          /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
+  __riscv_vle32_tumu ();        /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
+
+  __riscv_vlse64 ();            /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
+  __riscv_vlse64_tu ();         /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
+  __riscv_vlse64_tumu ();       /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
+
+  __riscv_vmfeq ();             /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
+
+  __riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
+
+  __riscv_vfredosum ();         /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
+  __riscv_vfredosum_tu ();      /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
new file mode 100644
index 00000000000..621fb9f1b08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
+{
+  __riscv_vand (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
+
+  __riscv_vcompress (vi32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
+
+  __riscv_vcpop (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
+
+  __riscv_vdiv (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
+
+  __riscv_vfabs (vf32m1);            /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
+
+  __riscv_vfadd (vf32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
+
+  __riscv_vfcvt_x (vf32m1);          /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
+
+  __riscv_vfirst (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
+
+  __riscv_vfmadd (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
+
+  __riscv_vfmerge (vf32m1, vl);      /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
+
+  __riscv_vfncvt_x (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
+
+  __riscv_vfrec7 (vf32m1);           /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
+
+  __riscv_vfrsqrt7 (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
+
+  __riscv_vfsgnjn (vf32m1, vl);      /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
+
+  __riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
+
+  __riscv_vfwmul (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
+
+  __riscv_vle32 (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vle32'} } */
+
+  __riscv_vlse64 (vi64m1, vl);       /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
+
+  __riscv_vmfeq (vf32m1, vl);        /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
+
+  __riscv_vfredosum (vf32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
+}
--
2.34.1



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

* Re: RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
  2024-02-06 12:46     ` Li, Pan2
@ 2024-02-07  1:11       ` juzhe.zhong
  2024-02-07  1:20         ` Li, Pan2
  0 siblings, 1 reply; 7+ messages in thread
From: juzhe.zhong @ 2024-02-07  1:11 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: yanzhang.wang, kito.cheng

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

OK。 LGTM。 Thanks.



juzhe.zhong@rivai.ai
 
From: Li, Pan2
Date: 2024-02-06 20:46
To: juzhe.zhong@rivai.ai; gcc-patches
CC: Wang, Yanzhang; kito.cheng
Subject: RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
All passed, include overloaded and non-overloaded.
 
# of expected passes            10885
 
Pan
 
From: Li, Pan2 
Sent: Tuesday, February 6, 2024 4:17 PM
To: juzhe.zhong@rivai.ai; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
 
Not yet. It is long time since last round run, will make sure there is no surprises from that.
 
Pan
 
From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> 
Sent: Tuesday, February 6, 2024 4:11 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 RVV overloaded intrinisc ICE when empty args
 
Did you run the C compiler compile C++ intrinsic test ?
 


juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2024-02-06 16:09
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
From: Pan Li <pan2.li@intel.com>
 
There is one corn case when similar as below example:
 
void test (void)
{
  __riscv_vfredosum_tu ();
}
 
It will meet ICE because of the implement details of overloaded function
in gcc.  According to the rvv intrinisc doc, we have no such overloaded
function with empty args.  Unfortunately, we register the empty args
function as overloaded for avoiding conflict.  Thus, there will be actual
one register function after return NULL_TREE back to the middle-end,
and finally result in ICE when expanding.  For example:
 
1. First we registered void __riscv_vfredmax () as the overloaded function.
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
3. The functions register in step 1 bypass the args check as empty args.
4. Finally, fall into expand_builtin with empty args and meet ICE.
 
Here we report error when overloaded function with empty args.  For example:
 
test.c: In function 'foo':
test.c:8:3: error: no matching function call to '__riscv_vfredosum_tu' with empty args
    8 |   __riscv_vfredosum_tu();
      |   ^~~~~~~~~~~~~~~~~~~~
 
Below test are passed for this patch.
 
* The riscv regression tests.
 
PR target/113766
 
gcc/ChangeLog:
 
* config/riscv/riscv-protos.h (resolve_overloaded_builtin): Adjust
the signature of func.
* config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Ditto.
* config/riscv/riscv-vector-builtins.cc (resolve_overloaded_builtin): Make
overloaded func with empty args error.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr113766-1.c: New test.
* gcc.target/riscv/rvv/base/pr113766-2.c: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv-c.cc                   |  3 +-
gcc/config/riscv/riscv-protos.h               |  2 +-
gcc/config/riscv/riscv-vector-builtins.cc     | 23 ++++-
.../gcc.target/riscv/rvv/base/pr113766-1.c    | 85 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/pr113766-2.c    | 48 +++++++++++
5 files changed, 155 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
 
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 2e306057347..94c3871c760 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
     case RISCV_BUILTIN_GENERAL:
       break;
     case RISCV_BUILTIN_VECTOR:
-      new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
+      new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
+      fndecl, arglist);
       break;
     default:
       gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b3f0bdb9924..ae1685850ac 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
rtx expand_builtin (unsigned int, tree, rtx);
bool check_builtin_call (location_t, vec<location_t>, unsigned int,
   tree, unsigned int, tree *);
-tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
+tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
bool legitimize_move (rtx, rtx *);
void emit_vlmax_vsetvl (machine_mode, rtx);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 403e1021fd1..efcdc8f1767 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
}
tree
-resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
+     vec<tree, va_gc> *arglist)
{
   if (code >= vec_safe_length (registered_functions))
     return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   if (!rfun || !rfun->overloaded_p)
     return NULL_TREE;
+  /* According to the rvv intrinisc doc, we have no such overloaded function
+     with empty args.  Unfortunately, we register the empty args function as
+     overloaded for avoiding conflict.  Thus, there will actual one register
+     function after return NULL_TREE back to the middle-end, and finally result
+     in ICE when expanding.  For example:
+
+     1. First we registered void __riscv_vfredmax () as the overloaded function.
+     2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
+     3. The functions register in step 1 bypass the args check as empty args.
+     4. Finally, fall into expand_builtin with empty args and meet ICE.
+
+     Here we report error when overloaded function with empty args.  */
+  if (rfun->overloaded_p && arglist->length () == 0)
+    error_at (loc, "no matching function call to %qE with empty args", fndecl);
+
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  if (rfn)
-    return rfn->decl;
-  return NULL_TREE;
+
+  return rfn ? rfn->decl : NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
new file mode 100644
index 00000000000..bd4943b0b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test ()
+{
+  __riscv_vand ();              /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
+  __riscv_vand_tu ();           /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
+  __riscv_vand_tumu ();         /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
+
+  __riscv_vcompress ();         /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
+  __riscv_vcompress_tu ();      /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
+
+  __riscv_vcpop ();             /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
+
+  __riscv_vdiv ();              /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
+  __riscv_vdiv_tu ();           /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
+  __riscv_vdiv_tumu ();         /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
+
+  __riscv_vfabs ();             /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
+  __riscv_vfabs_tu ();          /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
+  __riscv_vfabs_tumu ();        /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
+
+  __riscv_vfadd ();             /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
+  __riscv_vfadd_tu ();          /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
+  __riscv_vfadd_tumu ();        /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
+
+  __riscv_vfclass ();           /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
+  __riscv_vfclass_tu ();        /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
+  __riscv_vfclass_tumu ();      /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
+
+  __riscv_vfcvt_x ();           /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
+  __riscv_vfcvt_x_tu ();        /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
+  __riscv_vfcvt_x_tumu ();      /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
+
+  __riscv_vfirst ();            /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
+
+  __riscv_vfmadd ();            /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
+  __riscv_vfmadd_tu ();         /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
+  __riscv_vfmadd_tumu ();       /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
+
+  __riscv_vfmerge ();           /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
+  __riscv_vfmerge_tu ();        /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
+
+  __riscv_vfncvt_x ();          /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
+  __riscv_vfncvt_x_tu ();       /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
+  __riscv_vfncvt_x_tumu ();     /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
+
+  __riscv_vfrec7 ();            /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
+  __riscv_vfrec7_tu ();         /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
+  __riscv_vfrec7_tumu ();       /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
+
+  __riscv_vfrsqrt7 ();          /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
+  __riscv_vfrsqrt7_tu ();       /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
+  __riscv_vfrsqrt7_tumu ();     /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
+
+  __riscv_vfsgnjn ();           /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
+  __riscv_vfsgnjn_tu ();        /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
+  __riscv_vfsgnjn_tumu ();     /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
+
+  __riscv_vfslide1down ();      /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
+  __riscv_vfslide1down_tu ();   /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
+  __riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
+
+  __riscv_vfwmul ();            /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
+  __riscv_vfwmul_tu ();         /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
+  __riscv_vfwmul_tumu ();       /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
+
+  __riscv_vle32 ();             /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
+  __riscv_vle32_tu ();          /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
+  __riscv_vle32_tumu ();        /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
+
+  __riscv_vlse64 ();            /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
+  __riscv_vlse64_tu ();         /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
+  __riscv_vlse64_tumu ();       /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
+
+  __riscv_vmfeq ();             /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
+
+  __riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
+
+  __riscv_vfredosum ();         /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
+  __riscv_vfredosum_tu ();      /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
new file mode 100644
index 00000000000..621fb9f1b08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
+{
+  __riscv_vand (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
+
+  __riscv_vcompress (vi32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
+
+  __riscv_vcpop (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
+
+  __riscv_vdiv (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
+
+  __riscv_vfabs (vf32m1);            /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
+
+  __riscv_vfadd (vf32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
+
+  __riscv_vfcvt_x (vf32m1);          /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
+
+  __riscv_vfirst (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
+
+  __riscv_vfmadd (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
+
+  __riscv_vfmerge (vf32m1, vl);      /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
+
+  __riscv_vfncvt_x (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
+
+  __riscv_vfrec7 (vf32m1);           /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
+
+  __riscv_vfrsqrt7 (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
+
+  __riscv_vfsgnjn (vf32m1, vl);      /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
+
+  __riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
+
+  __riscv_vfwmul (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
+
+  __riscv_vle32 (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vle32'} } */
+
+  __riscv_vlse64 (vi64m1, vl);       /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
+
+  __riscv_vmfeq (vf32m1, vl);        /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
+
+  __riscv_vfredosum (vf32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
+}
-- 
2.34.1
 
 

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

* RE: RE: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
  2024-02-07  1:11       ` juzhe.zhong
@ 2024-02-07  1:20         ` Li, Pan2
  2024-02-10  8:47           ` Andreas Schwab
  0 siblings, 1 reply; 7+ messages in thread
From: Li, Pan2 @ 2024-02-07  1:20 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

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

Committed, thanks Juzhe.

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Wednesday, February 7, 2024 9:12 AM
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 RVV overloaded intrinisc ICE when empty args

OK。 LGTM。 Thanks.

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

From: Li, Pan2<mailto:pan2.li@intel.com>
Date: 2024-02-06 20:46
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 RVV overloaded intrinisc ICE when empty args
All passed, include overloaded and non-overloaded.

# of expected passes            10885

Pan

From: Li, Pan2
Sent: Tuesday, February 6, 2024 4:17 PM
To: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>; 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: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args

Not yet. It is long time since last round run, will make sure there is no surprises from that.

Pan

From: juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai> <juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>
Sent: Tuesday, February 6, 2024 4:11 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 RVV overloaded intrinisc ICE when empty args

Did you run the C compiler compile C++ intrinsic test ?

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

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2024-02-06 16:09
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 RVV overloaded intrinisc ICE when empty args
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

There is one corn case when similar as below example:

void test (void)
{
  __riscv_vfredosum_tu ();
}

It will meet ICE because of the implement details of overloaded function
in gcc.  According to the rvv intrinisc doc, we have no such overloaded
function with empty args.  Unfortunately, we register the empty args
function as overloaded for avoiding conflict.  Thus, there will be actual
one register function after return NULL_TREE back to the middle-end,
and finally result in ICE when expanding.  For example:

1. First we registered void __riscv_vfredmax () as the overloaded function.
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
3. The functions register in step 1 bypass the args check as empty args.
4. Finally, fall into expand_builtin with empty args and meet ICE.

Here we report error when overloaded function with empty args.  For example:

test.c: In function 'foo':
test.c:8:3: error: no matching function call to '__riscv_vfredosum_tu' with empty args
    8 |   __riscv_vfredosum_tu();
      |   ^~~~~~~~~~~~~~~~~~~~

Below test are passed for this patch.

* The riscv regression tests.

PR target/113766

gcc/ChangeLog:

* config/riscv/riscv-protos.h (resolve_overloaded_builtin): Adjust
the signature of func.
* config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Ditto.
* config/riscv/riscv-vector-builtins.cc (resolve_overloaded_builtin): Make
overloaded func with empty args error.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv-c.cc                   |  3 +-
gcc/config/riscv/riscv-protos.h               |  2 +-
gcc/config/riscv/riscv-vector-builtins.cc     | 23 ++++-
.../gcc.target/riscv/rvv/base/pr113766-1.c    | 85 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/pr113766-2.c    | 48 +++++++++++
5 files changed, 155 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 2e306057347..94c3871c760 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
     case RISCV_BUILTIN_GENERAL:
       break;
     case RISCV_BUILTIN_VECTOR:
-      new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
+      new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
+      fndecl, arglist);
       break;
     default:
       gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index b3f0bdb9924..ae1685850ac 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
rtx expand_builtin (unsigned int, tree, rtx);
bool check_builtin_call (location_t, vec<location_t>, unsigned int,
   tree, unsigned int, tree *);
-tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
+tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
bool legitimize_move (rtx, rtx *);
void emit_vlmax_vsetvl (machine_mode, rtx);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 403e1021fd1..efcdc8f1767 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
}
tree
-resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
+     vec<tree, va_gc> *arglist)
{
   if (code >= vec_safe_length (registered_functions))
     return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
   if (!rfun || !rfun->overloaded_p)
     return NULL_TREE;
+  /* According to the rvv intrinisc doc, we have no such overloaded function
+     with empty args.  Unfortunately, we register the empty args function as
+     overloaded for avoiding conflict.  Thus, there will actual one register
+     function after return NULL_TREE back to the middle-end, and finally result
+     in ICE when expanding.  For example:
+
+     1. First we registered void __riscv_vfredmax () as the overloaded function.
+     2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
+     3. The functions register in step 1 bypass the args check as empty args.
+     4. Finally, fall into expand_builtin with empty args and meet ICE.
+
+     Here we report error when overloaded function with empty args.  */
+  if (rfun->overloaded_p && arglist->length () == 0)
+    error_at (loc, "no matching function call to %qE with empty args", fndecl);
+
   hashval_t hash = rfun->overloaded_hash (*arglist);
   registered_function *rfn
     = non_overloaded_function_table->find_with_hash (rfun, hash);
-  if (rfn)
-    return rfn->decl;
-  return NULL_TREE;
+
+  return rfn ? rfn->decl : NULL_TREE;
}
function_instance
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
new file mode 100644
index 00000000000..bd4943b0b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test ()
+{
+  __riscv_vand ();              /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
+  __riscv_vand_tu ();           /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
+  __riscv_vand_tumu ();         /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
+
+  __riscv_vcompress ();         /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
+  __riscv_vcompress_tu ();      /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
+
+  __riscv_vcpop ();             /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
+
+  __riscv_vdiv ();              /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
+  __riscv_vdiv_tu ();           /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
+  __riscv_vdiv_tumu ();         /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
+
+  __riscv_vfabs ();             /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
+  __riscv_vfabs_tu ();          /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
+  __riscv_vfabs_tumu ();        /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
+
+  __riscv_vfadd ();             /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
+  __riscv_vfadd_tu ();          /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
+  __riscv_vfadd_tumu ();        /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
+
+  __riscv_vfclass ();           /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
+  __riscv_vfclass_tu ();        /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
+  __riscv_vfclass_tumu ();      /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
+
+  __riscv_vfcvt_x ();           /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
+  __riscv_vfcvt_x_tu ();        /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
+  __riscv_vfcvt_x_tumu ();      /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
+
+  __riscv_vfirst ();            /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
+
+  __riscv_vfmadd ();            /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
+  __riscv_vfmadd_tu ();         /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
+  __riscv_vfmadd_tumu ();       /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
+
+  __riscv_vfmerge ();           /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
+  __riscv_vfmerge_tu ();        /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
+
+  __riscv_vfncvt_x ();          /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
+  __riscv_vfncvt_x_tu ();       /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
+  __riscv_vfncvt_x_tumu ();     /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
+
+  __riscv_vfrec7 ();            /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
+  __riscv_vfrec7_tu ();         /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
+  __riscv_vfrec7_tumu ();       /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
+
+  __riscv_vfrsqrt7 ();          /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
+  __riscv_vfrsqrt7_tu ();       /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
+  __riscv_vfrsqrt7_tumu ();     /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
+
+  __riscv_vfsgnjn ();           /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
+  __riscv_vfsgnjn_tu ();        /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
+  __riscv_vfsgnjn_tumu ();     /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
+
+  __riscv_vfslide1down ();      /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
+  __riscv_vfslide1down_tu ();   /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
+  __riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
+
+  __riscv_vfwmul ();            /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
+  __riscv_vfwmul_tu ();         /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
+  __riscv_vfwmul_tumu ();       /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
+
+  __riscv_vle32 ();             /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
+  __riscv_vle32_tu ();          /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
+  __riscv_vle32_tumu ();        /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
+
+  __riscv_vlse64 ();            /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
+  __riscv_vlse64_tu ();         /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
+  __riscv_vlse64_tumu ();       /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
+
+  __riscv_vmfeq ();             /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
+
+  __riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
+
+  __riscv_vfredosum ();         /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
+  __riscv_vfredosum_tu ();      /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
new file mode 100644
index 00000000000..621fb9f1b08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr113766-2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
+{
+  __riscv_vand (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
+
+  __riscv_vcompress (vi32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
+
+  __riscv_vcpop (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
+
+  __riscv_vdiv (vi32m1, vl);         /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
+
+  __riscv_vfabs (vf32m1);            /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
+
+  __riscv_vfadd (vf32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
+
+  __riscv_vfcvt_x (vf32m1);          /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
+
+  __riscv_vfirst (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
+
+  __riscv_vfmadd (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
+
+  __riscv_vfmerge (vf32m1, vl);      /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
+
+  __riscv_vfncvt_x (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
+
+  __riscv_vfrec7 (vf32m1);           /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
+
+  __riscv_vfrsqrt7 (vf32m1);         /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
+
+  __riscv_vfsgnjn (vf32m1, vl);      /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
+
+  __riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
+
+  __riscv_vfwmul (vf32m1, vl);       /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
+
+  __riscv_vle32 (vi32m1, vl);        /* { dg-error {too many arguments to function '__riscv_vle32'} } */
+
+  __riscv_vlse64 (vi64m1, vl);       /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
+
+  __riscv_vmfeq (vf32m1, vl);        /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
+
+  __riscv_vfredosum (vf32m1, vl);    /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
+}
--
2.34.1



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

* Re: [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
  2024-02-07  1:20         ` Li, Pan2
@ 2024-02-10  8:47           ` Andreas Schwab
  0 siblings, 0 replies; 7+ messages in thread
From: Andreas Schwab @ 2024-02-10  8:47 UTC (permalink / raw)
  To: Li, Pan2; +Cc: juzhe.zhong, gcc-patches, Wang, Yanzhang, kito.cheng

WTF?

../../gcc/config/riscv/riscv-vector-builtins.cc: In function 'tree_node* riscv_vector::resolve_overloaded_builtin(location_t, unsigned int, tree, vec<tree_node*, va_gc>*)':
../../gcc/config/riscv/riscv-vector-builtins.cc:4633:65: error: misspelled term 'args' in format; use 'arguments' instead [-Werror=format-diag]
 4633 |     error_at (loc, "no matching function call to %qE with empty args", fndecl);
      |                                                                 ^~~

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

end of thread, other threads:[~2024-02-10  8:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-06  8:09 [PATCH v1] RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args pan2.li
2024-02-06  8:11 ` juzhe.zhong
2024-02-06  8:16   ` Li, Pan2
2024-02-06 12:46     ` Li, Pan2
2024-02-07  1:11       ` juzhe.zhong
2024-02-07  1:20         ` Li, Pan2
2024-02-10  8:47           ` Andreas Schwab

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