Since XTheadvector does not support vsetivli, vl needs to be put into registers during the expand phase.
PR 116593 gcc/ChangeLog: * config/riscv/riscv-vector-builtins.cc (function_expander::add_input_operand): Put const to GPR for vl. * config/riscv/thead-vector.md (@th_pred_vl_mov<mode>): New. gcc/testsuite/ChangeLog: * g++.target/riscv/xtheadvector/pr116593.C: New test. * g++.target/riscv/xtheadvector/xtheadvector.exp: New test. Reported-by: nihui <shuizhuyuan...@gmail.com> --- gcc/config/riscv/riscv-vector-builtins.cc | 18 +++++++- gcc/config/riscv/thead-vector.md | 13 ++++++ .../g++.target/riscv/xtheadvector/pr116593.C | 45 +++++++++++++++++++ .../riscv/xtheadvector/xtheadvector.exp | 37 +++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index b9b9d33adab6..cced0461a7bb 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -4089,7 +4089,23 @@ function_expander::add_input_operand (unsigned argno) { tree arg = CALL_EXPR_ARG (exp, argno); rtx x = expand_normal (arg); - add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x); + + /* Since the parameter vl of XTheadVector does not support + immediate numbers, we need to put it in the register + in advance. */ + if (TARGET_XTHEADVECTOR + && CONST_INT_P (x) + && base->apply_vl_p () + && argno == (unsigned) (call_expr_nargs (exp) - 1) + && x != CONST0_RTX (GET_MODE (x))) + { + rtx tmp = gen_reg_rtx (word_mode); + /* Use UNSPEC to avoid being optimized before vsetvl pass. */ + emit_insn (gen_th_pred_vl_mov (word_mode, tmp, x)); + add_input_operand (TYPE_MODE (TREE_TYPE (arg)), tmp); + } + else + add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x); } /* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter. diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md index 5fe9ba08c4eb..0e00514c6b2d 100644 --- a/gcc/config/riscv/thead-vector.md +++ b/gcc/config/riscv/thead-vector.md @@ -25,6 +25,7 @@ (define_c_enum "unspec" [ UNSPEC_TH_VSUXW UNSPEC_TH_VWLDST + UNSPEC_TH_VL_MOV ]) (define_int_iterator UNSPEC_TH_VLMEM_OP [ @@ -93,6 +94,18 @@ (define_int_iterator UNSPEC_TH_VSXMEM_OP [ (define_mode_iterator V_VLS_VT [V VLS VT]) (define_mode_iterator V_VB_VLS_VT [V VB VLS VT]) +(define_insn_and_split "@th_pred_vl_mov<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P + [(match_operand:P 1 "const_int_operand" " i")] + UNSPEC_TH_VL_MOV))] + "TARGET_XTHEADVECTOR" + "li\t%0,%1" + "&& epilogue_completed" + [(set (match_dup 0) (match_dup 1))] + {} + [(set_attr "type" "arith")]) + (define_split [(set (match_operand:V_VB_VLS_VT 0 "reg_or_mem_operand") (match_operand:V_VB_VLS_VT 1 "reg_or_mem_operand"))] diff --git a/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C b/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C new file mode 100644 index 000000000000..e44e7437ad70 --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C @@ -0,0 +1,45 @@ +/* Test that we do not have ice when compile */ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2" { target { rv64 } } } */ + +#include <math.h> +#include <riscv_vector.h> +#include <vector> + +static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl) +{ + std::vector<float> tmpx(vl); + std::vector<float> tmpy(vl); + __riscv_vse32_v_f32m8(tmpx.data(), a, vl); + __riscv_vse32_v_f32m8(tmpy.data(), b, vl); + for (size_t i = 0; i < vl; i++) + { + tmpx[i] = atan2(tmpx[i], tmpy[i]); + } + return __riscv_vle32_v_f32m8(tmpx.data(), vl); +} + +void atan2(const float *x, const float *y, float *out, int size, int ch) +{ + for (int i = 0; i < ch; i++) + { + const float *xx = x + size * i; + const float *yy = y + size * i; + float *zz = out + size * i; + + int n = size; + while (n > 0) + { + size_t vl = __riscv_vsetvl_e32m8(n); + vfloat32m8_t _xx = __riscv_vle32_v_f32m8(xx, vl); + vfloat32m8_t _yy = __riscv_vle32_v_f32m8(yy, vl); + vfloat32m8_t _zz = atan2_ps(_xx, _yy, vl); + __riscv_vse32_v_f32m8(zz, _zz, vl); + n -= vl; + xx += vl; + yy += vl; + zz += vl; + } + } +} diff --git a/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp b/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp new file mode 100644 index 000000000000..551fd9c92670 --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp @@ -0,0 +1,37 @@ +# Copyright (C) 2023-2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Test the front-end for C++. +# We don't need to test back-end code-gen in RV32 system for C++ +# Because it is already tested in C. +# Exit immediately if this isn't a RISC-V target. +if ![istarget riscv*-*-*] then { + return +} + +# Load support procs. +load_lib g++-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" "" + +# All done. +dg-finish -- 2.25.1