Skip to content

Commit db5c3f6

Browse files
RISC-V: Bugfix for RVV overloaded intrinisc ICE when empty args
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 <[email protected]>
1 parent 3e4c4c5 commit db5c3f6

File tree

5 files changed

+155
-6
lines changed

5 files changed

+155
-6
lines changed

gcc/config/riscv/riscv-c.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,8 @@ riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl,
250250
case RISCV_BUILTIN_GENERAL:
251251
break;
252252
case RISCV_BUILTIN_VECTOR:
253-
new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist);
253+
new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
254+
fndecl, arglist);
254255
break;
255256
default:
256257
gcc_unreachable ();

gcc/config/riscv/riscv-protos.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *);
560560
rtx expand_builtin (unsigned int, tree, rtx);
561561
bool check_builtin_call (location_t, vec<location_t>, unsigned int,
562562
tree, unsigned int, tree *);
563-
tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
563+
tree resolve_overloaded_builtin (location_t, unsigned int, tree, vec<tree, va_gc> *);
564564
bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
565565
bool legitimize_move (rtx, rtx *);
566566
void emit_vlmax_vsetvl (machine_mode, rtx);

gcc/config/riscv/riscv-vector-builtins.cc

+19-4
Original file line numberDiff line numberDiff line change
@@ -4606,7 +4606,8 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
46064606
}
46074607

46084608
tree
4609-
resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
4609+
resolve_overloaded_builtin (location_t loc, unsigned int code, tree fndecl,
4610+
vec<tree, va_gc> *arglist)
46104611
{
46114612
if (code >= vec_safe_length (registered_functions))
46124613
return NULL_TREE;
@@ -4616,12 +4617,26 @@ resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
46164617
if (!rfun || !rfun->overloaded_p)
46174618
return NULL_TREE;
46184619

4620+
/* According to the rvv intrinisc doc, we have no such overloaded function
4621+
with empty args. Unfortunately, we register the empty args function as
4622+
overloaded for avoiding conflict. Thus, there will actual one register
4623+
function after return NULL_TREE back to the middle-end, and finally result
4624+
in ICE when expanding. For example:
4625+
4626+
1. First we registered void __riscv_vfredmax () as the overloaded function.
4627+
2. Then resolve_overloaded_builtin (this func) return NULL_TREE.
4628+
3. The functions register in step 1 bypass the args check as empty args.
4629+
4. Finally, fall into expand_builtin with empty args and meet ICE.
4630+
4631+
Here we report error when overloaded function with empty args. */
4632+
if (rfun->overloaded_p && arglist->length () == 0)
4633+
error_at (loc, "no matching function call to %qE with empty args", fndecl);
4634+
46194635
hashval_t hash = rfun->overloaded_hash (*arglist);
46204636
registered_function *rfn
46214637
= non_overloaded_function_table->find_with_hash (rfun, hash);
4622-
if (rfn)
4623-
return rfn->decl;
4624-
return NULL_TREE;
4638+
4639+
return rfn ? rfn->decl : NULL_TREE;
46254640
}
46264641

46274642
function_instance
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
3+
4+
#include "riscv_vector.h"
5+
6+
void
7+
test ()
8+
{
9+
__riscv_vand (); /* { dg-error {no matching function call to '__riscv_vand' with empty args} } */
10+
__riscv_vand_tu (); /* { dg-error {no matching function call to '__riscv_vand_tu' with empty args} } */
11+
__riscv_vand_tumu (); /* { dg-error {no matching function call to '__riscv_vand_tumu' with empty args} } */
12+
13+
__riscv_vcompress (); /* { dg-error {no matching function call to '__riscv_vcompress' with empty args} } */
14+
__riscv_vcompress_tu (); /* { dg-error {no matching function call to '__riscv_vcompress_tu' with empty args} } */
15+
16+
__riscv_vcpop (); /* { dg-error {no matching function call to '__riscv_vcpop' with empty args} } */
17+
18+
__riscv_vdiv (); /* { dg-error {no matching function call to '__riscv_vdiv' with empty args} } */
19+
__riscv_vdiv_tu (); /* { dg-error {no matching function call to '__riscv_vdiv_tu' with empty args} } */
20+
__riscv_vdiv_tumu (); /* { dg-error {no matching function call to '__riscv_vdiv_tumu' with empty args} } */
21+
22+
__riscv_vfabs (); /* { dg-error {no matching function call to '__riscv_vfabs' with empty args} } */
23+
__riscv_vfabs_tu (); /* { dg-error {no matching function call to '__riscv_vfabs_tu' with empty args} } */
24+
__riscv_vfabs_tumu (); /* { dg-error {no matching function call to '__riscv_vfabs_tumu' with empty args} } */
25+
26+
__riscv_vfadd (); /* { dg-error {no matching function call to '__riscv_vfadd' with empty args} } */
27+
__riscv_vfadd_tu (); /* { dg-error {no matching function call to '__riscv_vfadd_tu' with empty args} } */
28+
__riscv_vfadd_tumu (); /* { dg-error {no matching function call to '__riscv_vfadd_tumu' with empty args} } */
29+
30+
__riscv_vfclass (); /* { dg-error {no matching function call to '__riscv_vfclass' with empty args} } */
31+
__riscv_vfclass_tu (); /* { dg-error {no matching function call to '__riscv_vfclass_tu' with empty args} } */
32+
__riscv_vfclass_tumu (); /* { dg-error {no matching function call to '__riscv_vfclass_tumu' with empty args} } */
33+
34+
__riscv_vfcvt_x (); /* { dg-error {no matching function call to '__riscv_vfcvt_x' with empty args} } */
35+
__riscv_vfcvt_x_tu (); /* { dg-error {no matching function call to '__riscv_vfcvt_x_tu' with empty args} } */
36+
__riscv_vfcvt_x_tumu (); /* { dg-error {no matching function call to '__riscv_vfcvt_x_tumu' with empty args} } */
37+
38+
__riscv_vfirst (); /* { dg-error {no matching function call to '__riscv_vfirst' with empty args} } */
39+
40+
__riscv_vfmadd (); /* { dg-error {no matching function call to '__riscv_vfmadd' with empty args} } */
41+
__riscv_vfmadd_tu (); /* { dg-error {no matching function call to '__riscv_vfmadd_tu' with empty args} } */
42+
__riscv_vfmadd_tumu (); /* { dg-error {no matching function call to '__riscv_vfmadd_tumu' with empty args} } */
43+
44+
__riscv_vfmerge (); /* { dg-error {no matching function call to '__riscv_vfmerge' with empty args} } */
45+
__riscv_vfmerge_tu (); /* { dg-error {no matching function call to '__riscv_vfmerge_tu' with empty args} } */
46+
47+
__riscv_vfncvt_x (); /* { dg-error {no matching function call to '__riscv_vfncvt_x' with empty args} } */
48+
__riscv_vfncvt_x_tu (); /* { dg-error {no matching function call to '__riscv_vfncvt_x_tu' with empty args} } */
49+
__riscv_vfncvt_x_tumu (); /* { dg-error {no matching function call to '__riscv_vfncvt_x_tumu' with empty args} } */
50+
51+
__riscv_vfrec7 (); /* { dg-error {no matching function call to '__riscv_vfrec7' with empty args} } */
52+
__riscv_vfrec7_tu (); /* { dg-error {no matching function call to '__riscv_vfrec7_tu' with empty args} } */
53+
__riscv_vfrec7_tumu (); /* { dg-error {no matching function call to '__riscv_vfrec7_tumu' with empty args} } */
54+
55+
__riscv_vfrsqrt7 (); /* { dg-error {no matching function call to '__riscv_vfrsqrt7' with empty args} } */
56+
__riscv_vfrsqrt7_tu (); /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tu' with empty args} } */
57+
__riscv_vfrsqrt7_tumu (); /* { dg-error {no matching function call to '__riscv_vfrsqrt7_tumu' with empty args} } */
58+
59+
__riscv_vfsgnjn (); /* { dg-error {no matching function call to '__riscv_vfsgnjn' with empty args} } */
60+
__riscv_vfsgnjn_tu (); /* { dg-error {no matching function call to '__riscv_vfsgnjn_tu' with empty args} } */
61+
__riscv_vfsgnjn_tumu (); /* { dg-error {no matching function call to '__riscv_vfsgnjn_tumu' with empty args} } */
62+
63+
__riscv_vfslide1down (); /* { dg-error {no matching function call to '__riscv_vfslide1down' with empty args} } */
64+
__riscv_vfslide1down_tu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tu' with empty args} } */
65+
__riscv_vfslide1down_tumu (); /* { dg-error {no matching function call to '__riscv_vfslide1down_tumu' with empty args} } */
66+
67+
__riscv_vfwmul (); /* { dg-error {no matching function call to '__riscv_vfwmul' with empty args} } */
68+
__riscv_vfwmul_tu (); /* { dg-error {no matching function call to '__riscv_vfwmul_tu' with empty args} } */
69+
__riscv_vfwmul_tumu (); /* { dg-error {no matching function call to '__riscv_vfwmul_tumu' with empty args} } */
70+
71+
__riscv_vle32 (); /* { dg-error {no matching function call to '__riscv_vle32' with empty args} } */
72+
__riscv_vle32_tu (); /* { dg-error {no matching function call to '__riscv_vle32_tu' with empty args} } */
73+
__riscv_vle32_tumu (); /* { dg-error {no matching function call to '__riscv_vle32_tumu' with empty args} } */
74+
75+
__riscv_vlse64 (); /* { dg-error {no matching function call to '__riscv_vlse64' with empty args} } */
76+
__riscv_vlse64_tu (); /* { dg-error {no matching function call to '__riscv_vlse64_tu' with empty args} } */
77+
__riscv_vlse64_tumu (); /* { dg-error {no matching function call to '__riscv_vlse64_tumu' with empty args} } */
78+
79+
__riscv_vmfeq (); /* { dg-error {no matching function call to '__riscv_vmfeq' with empty args} } */
80+
81+
__riscv_vreinterpret_u8m1 (); /* { dg-error {no matching function call to '__riscv_vreinterpret_u8m1' with empty args} } */
82+
83+
__riscv_vfredosum (); /* { dg-error {no matching function call to '__riscv_vfredosum' with empty args} } */
84+
__riscv_vfredosum_tu (); /* { dg-error {no matching function call to '__riscv_vfredosum_tu' with empty args} } */
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3" } */
3+
4+
#include "riscv_vector.h"
5+
6+
void
7+
test (vint32m1_t vi32m1, vint64m1_t vi64m1, vfloat32m1_t vf32m1, unsigned vl)
8+
{
9+
__riscv_vand (vi32m1, vl); /* { dg-error {too few arguments to function '__riscv_vand_vx_i32m1'} } */
10+
11+
__riscv_vcompress (vi32m1, vl); /* { dg-error {too many arguments to function '__riscv_vcompress'} } */
12+
13+
__riscv_vcpop (vi32m1, vl); /* { dg-error {too many arguments to function '__riscv_vcpop'} } */
14+
15+
__riscv_vdiv (vi32m1, vl); /* { dg-error {too few arguments to function '__riscv_vdiv_vx_i32m1'} } */
16+
17+
__riscv_vfabs (vf32m1); /* { dg-error {too many arguments to function '__riscv_vfabs'} } */
18+
19+
__riscv_vfadd (vf32m1, vl); /* { dg-error {too many arguments to function '__riscv_vfadd'} } */
20+
21+
__riscv_vfcvt_x (vf32m1); /* { dg-error {too many arguments to function '__riscv_vfcvt_x'} } */
22+
23+
__riscv_vfirst (vf32m1, vl); /* { dg-error {too many arguments to function '__riscv_vfirst'} } */
24+
25+
__riscv_vfmadd (vf32m1, vl); /* { dg-error {too many arguments to function '__riscv_vfmadd'} } */
26+
27+
__riscv_vfmerge (vf32m1, vl); /* { dg-error {too many arguments to function '__riscv_vfmerge'} } */
28+
29+
__riscv_vfncvt_x (vf32m1); /* { dg-error {too many arguments to function '__riscv_vfncvt_x'} } */
30+
31+
__riscv_vfrec7 (vf32m1); /* { dg-error {too many arguments to function '__riscv_vfrec7'} } */
32+
33+
__riscv_vfrsqrt7 (vf32m1); /* { dg-error {too many arguments to function '__riscv_vfrsqrt7'} } */
34+
35+
__riscv_vfsgnjn (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfsgnjn_vf_f32m1'} } */
36+
37+
__riscv_vfslide1down (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vfslide1down_vf_f32m1'} } */
38+
39+
__riscv_vfwmul (vf32m1, vl); /* { dg-error {too many arguments to function '__riscv_vfwmul'} } */
40+
41+
__riscv_vle32 (vi32m1, vl); /* { dg-error {too many arguments to function '__riscv_vle32'} } */
42+
43+
__riscv_vlse64 (vi64m1, vl); /* { dg-error {too many arguments to function '__riscv_vlse64'} } */
44+
45+
__riscv_vmfeq (vf32m1, vl); /* { dg-error {too few arguments to function '__riscv_vmfeq_vf_f32m1_b32'} } */
46+
47+
__riscv_vfredosum (vf32m1, vl); /* { dg-error {too many arguments to function '__riscv_vfredosum'} } */
48+
}

0 commit comments

Comments
 (0)