diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 06e9fe7d9249..119a3e4ac8e7 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3785,16 +3785,28 @@ riscv_arg_has_vector (const_tree type) Only check the value type and no checking for vector pointer type. */ static void -riscv_pass_in_vector_p (const_tree type) +riscv_pass_in_vector_p (const tree type, bool pass_by_reference) { static int warned = 0; - if (type && riscv_arg_has_vector (type) && !warned) + if (type) { - warning (OPT_Wpsabi, "ABI for the scalable vector type is currently in " - "experimental stage and may changes in the upcoming version of " - "GCC."); - warned = 1; + + bool has_vector = false; + + if (TREE_CODE (type) == POINTER_TYPE && pass_by_reference) + has_vector = riscv_arg_has_vector (TREE_TYPE (type)); + else + has_vector = riscv_arg_has_vector (type); + + if (has_vector && !warned) + { + + warning (OPT_Wpsabi, "ABI for the scalable vector type is currently " + "in experimental stage and may changes in the upcoming " + "version of GCC."); + warned = 1; + } } } @@ -3882,9 +3894,6 @@ riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum, } } - /* Only check existing of vector type. */ - riscv_pass_in_vector_p (type); - /* Work out the size of the argument. */ num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode).to_constant (); num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; @@ -3915,6 +3924,8 @@ riscv_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) if (arg.end_marker_p ()) return NULL; + riscv_pass_in_vector_p (arg.type, arg.pass_by_reference); + return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false); } @@ -3971,6 +3982,13 @@ riscv_function_value (const_tree type, const_tree func, machine_mode mode) mode = promote_function_mode (type, mode, &unsigned_p, func, 1); } + if (func && DECL_RESULT (func)) + { + tree return_type = TREE_TYPE (DECL_RESULT (func)); + riscv_pass_in_vector_p (const_cast (type), + TREE_CODE (return_type) != POINTER_TYPE); + } + memset (&args, 0, sizeof args); return riscv_get_arg_info (&info, &args, mode, type, true, true); } diff --git a/gcc/testsuite/gcc.target/riscv/vector-abi-1.c b/gcc/testsuite/gcc.target/riscv/vector-abi-1.c index 114ee6de483e..5bbd699a4c22 100644 --- a/gcc/testsuite/gcc.target/riscv/vector-abi-1.c +++ b/gcc/testsuite/gcc.target/riscv/vector-abi-1.c @@ -1,10 +1,11 @@ /* { dg-do compile } */ /* { dg-options "-O0 -march=rv64gcv -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ #include "riscv_vector.h" void -fun (vint32m1_t a) { } /* { dg-warning "the vector type" } */ +fun (vint32m1_t a) { } /* { dg-warning "the scalable vector type" } */ void bar () diff --git a/gcc/testsuite/gcc.target/riscv/vector-abi-2.c b/gcc/testsuite/gcc.target/riscv/vector-abi-2.c index fd4569535cc5..63d97d30fc59 100644 --- a/gcc/testsuite/gcc.target/riscv/vector-abi-2.c +++ b/gcc/testsuite/gcc.target/riscv/vector-abi-2.c @@ -1,10 +1,11 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gcv -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ #include "riscv_vector.h" vint32m1_t -fun (vint32m1_t* a) { return *a; } /* { dg-warning "the vector type" } */ +fun (vint32m1_t* a) { return *a; } /* { dg-warning "the scalable vector type" } */ void bar () diff --git a/gcc/testsuite/gcc.target/riscv/vector-abi-3.c b/gcc/testsuite/gcc.target/riscv/vector-abi-3.c index 844a5db4027e..90ece60cc6fc 100644 --- a/gcc/testsuite/gcc.target/riscv/vector-abi-3.c +++ b/gcc/testsuite/gcc.target/riscv/vector-abi-3.c @@ -4,7 +4,7 @@ #include "riscv_vector.h" vint32m1_t* -fun (vint32m1_t* a) { return a; } /* { dg-bogus "the vector type" } */ +fun (vint32m1_t* a) { return a; } /* { dg-bogus "the scalable vector type" } */ void bar () diff --git a/gcc/testsuite/gcc.target/riscv/vector-abi-4.c b/gcc/testsuite/gcc.target/riscv/vector-abi-4.c index a5dc2dffaac6..ecf6d4cc26bc 100644 --- a/gcc/testsuite/gcc.target/riscv/vector-abi-4.c +++ b/gcc/testsuite/gcc.target/riscv/vector-abi-4.c @@ -6,7 +6,7 @@ typedef int v4si __attribute__ ((vector_size (16))); v4si -fun (v4si a) { return a; } /* { dg-bogus "the vector type" } */ +fun (v4si a) { return a; } /* { dg-bogus "the scalable vector type" } */ void bar () diff --git a/gcc/testsuite/gcc.target/riscv/vector-abi-5.c b/gcc/testsuite/gcc.target/riscv/vector-abi-5.c index 1fe83c8fc87d..6053e0783b6d 100644 --- a/gcc/testsuite/gcc.target/riscv/vector-abi-5.c +++ b/gcc/testsuite/gcc.target/riscv/vector-abi-5.c @@ -5,7 +5,7 @@ typedef int v4si __attribute__ ((vector_size (16))); struct A { int a; v4si b; }; void -fun (struct A a) {} /* { dg-bogus "the vector type" } */ +fun (struct A a) {} /* { dg-bogus "the scalable vector type" } */ void bar () diff --git a/gcc/testsuite/gcc.target/riscv/vector-abi-6.c b/gcc/testsuite/gcc.target/riscv/vector-abi-6.c new file mode 100644 index 000000000000..63bc4a898057 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/vector-abi-6.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ +#include "riscv_vector.h" + +void +foo(int32_t *in1, int32_t *in2, int32_t *in3, int32_t *out, + size_t n, int cond) { + size_t vl; + if (cond) + vl = __riscv_vsetvlmax_e32m1(); + else + vl = __riscv_vsetvlmax_e16mf2(); + for (size_t i = 0; i < n; i += 1) + { + vint32m1_t a = __riscv_vle32_v_i32m1(in1, vl); /* { dg-bogus "the scalable vector type" } */ + vint32m1_t b = __riscv_vle32_v_i32m1_tu(a, in2, vl); + vint32m1_t c = __riscv_vle32_v_i32m1_tu(b, in3, vl); + __riscv_vse32_v_i32m1(out, c, vl); + } +}