diff --git a/gcc/config/riscv/autovec-vls.md b/gcc/config/riscv/autovec-vls.md deleted file mode 100644 index 3488f452e5d..00000000000 --- a/gcc/config/riscv/autovec-vls.md +++ /dev/null @@ -1,196 +0,0 @@ -;; Machine description for VLS of RVV auto-vectorization. -;; Copyright (C) 2023 Free Software Foundation, Inc. -;; Contributed by Juzhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies Ltd. - -;; This file is part of GCC. - -;; GCC 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, or (at your option) -;; any later version. - -;; GCC 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 -;; . - -;; We define VLS modes as 'define_insn_and_split' with normal -;; RTX_CODE operation, so we can gain benefits from Combine optimizations. - -;; ----------------------------------------------------------------- -;; ---- Moves Operations -;; ----------------------------------------------------------------- - -(define_expand "mov" - [(set (match_operand:VLS_AVL_IMM 0 "reg_or_mem_operand") - (match_operand:VLS_AVL_IMM 1 "general_operand"))] - "TARGET_VECTOR" -{ - if (riscv_vector::legitimize_move (operands[0], operands[1])) - DONE; -}) - -(define_insn_and_split "*mov_mem_to_mem" - [(set (match_operand:VLS_AVL_IMM 0 "memory_operand") - (match_operand:VLS_AVL_IMM 1 "memory_operand"))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - if (GET_MODE_BITSIZE (mode).to_constant () <= MAX_BITS_PER_WORD) - { - /* Opitmize the following case: - - typedef int8_t v2qi __attribute__ ((vector_size (2))); - v2qi v = *(v2qi*)in; - *(v2qi*)out = v; - - We prefer scalar load/store instead of vle.v/vse.v when - the VLS modes size is smaller scalar mode. */ - machine_mode mode; - unsigned size = GET_MODE_BITSIZE (mode).to_constant (); - if (FLOAT_MODE_P (mode)) - mode = mode_for_size (size, MODE_FLOAT, 0).require (); - else - mode = mode_for_size (size, MODE_INT, 0).require (); - emit_move_insn (gen_lowpart (mode, operands[0]), - gen_lowpart (mode, operands[1])); - } - else - { - operands[1] = force_reg (mode, operands[1]); - emit_move_insn (operands[0], operands[1]); - } - DONE; - } - [(set_attr "type" "vmov")] -) - -(define_insn_and_split "*mov" - [(set (match_operand:VLS_AVL_IMM 0 "reg_or_mem_operand" "=vr, m, vr") - (match_operand:VLS_AVL_IMM 1 "reg_or_mem_operand" " m,vr, vr"))] - "TARGET_VECTOR - && (register_operand (operands[0], mode) - || register_operand (operands[1], mode))" - "@ - # - # - vmv%m1r.v\t%0,%1" - "&& reload_completed - && (!register_operand (operands[0], mode) - || !register_operand (operands[1], mode))" - [(const_int 0)] - { - bool ok_p = riscv_vector::legitimize_move (operands[0], operands[1]); - gcc_assert (ok_p); - DONE; - } - [(set_attr "type" "vmov")] -) - -(define_expand "mov" - [(set (match_operand:VLS_AVL_REG 0 "reg_or_mem_operand") - (match_operand:VLS_AVL_REG 1 "general_operand"))] - "TARGET_VECTOR" -{ - bool ok_p = riscv_vector::legitimize_move (operands[0], operands[1]); - gcc_assert (ok_p); - DONE; -}) - -(define_expand "@mov_lra" - [(parallel - [(set (match_operand:VLS_AVL_REG 0 "reg_or_mem_operand") - (match_operand:VLS_AVL_REG 1 "reg_or_mem_operand")) - (clobber (match_scratch:P 2))])] - "TARGET_VECTOR && (lra_in_progress || reload_completed)" -{}) - -(define_insn_and_split "*mov_lra" - [(set (match_operand:VLS_AVL_REG 0 "reg_or_mem_operand" "=vr, m,vr") - (match_operand:VLS_AVL_REG 1 "reg_or_mem_operand" " m,vr,vr")) - (clobber (match_scratch:P 2 "=&r,&r,X"))] - "TARGET_VECTOR && (lra_in_progress || reload_completed) - && (register_operand (operands[0], mode) - || register_operand (operands[1], mode))" - "#" - "&& reload_completed" - [(const_int 0)] -{ - if (REG_P (operands[0]) && REG_P (operands[1])) - emit_insn (gen_rtx_SET (operands[0], operands[1])); - else - { - emit_move_insn (operands[2], gen_int_mode (GET_MODE_NUNITS (mode), - Pmode)); - unsigned insn_flags - = GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL - ? riscv_vector::UNARY_MASK_OP - : riscv_vector::UNARY_OP; - riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (mode), - insn_flags, operands, operands[2]); - } - DONE; -} - [(set_attr "type" "vmov")] -) - -(define_insn "*mov_vls" - [(set (match_operand:VLS 0 "register_operand" "=vr") - (match_operand:VLS 1 "register_operand" " vr"))] - "TARGET_VECTOR" - "vmv%m1r.v\t%0,%1" - [(set_attr "type" "vmov") - (set_attr "mode" "")]) - -(define_insn "*mov_vls" - [(set (match_operand:VLSB 0 "register_operand" "=vr") - (match_operand:VLSB 1 "register_operand" " vr"))] - "TARGET_VECTOR" - "vmv1r.v\t%0,%1" - [(set_attr "type" "vmov") - (set_attr "mode" "")]) - -(define_expand "movmisalign" - [(set (match_operand:VLS 0 "nonimmediate_operand") - (match_operand:VLS 1 "general_operand"))] - "TARGET_VECTOR" - { - /* To support misalign data movement, we should use - minimum element alignment load/store. */ - unsigned int size = GET_MODE_SIZE (GET_MODE_INNER (mode)); - poly_int64 nunits = GET_MODE_NUNITS (mode) * size; - machine_mode mode = riscv_vector::get_vector_mode (QImode, nunits).require (); - operands[0] = gen_lowpart (mode, operands[0]); - operands[1] = gen_lowpart (mode, operands[1]); - if (MEM_P (operands[0]) && !register_operand (operands[1], mode)) - operands[1] = force_reg (mode, operands[1]); - riscv_vector::emit_vlmax_insn (code_for_pred_mov (mode), riscv_vector::UNARY_OP, operands); - DONE; - } -) - -;; ----------------------------------------------------------------- -;; ---- Duplicate Operations -;; ----------------------------------------------------------------- - -(define_insn_and_split "@vec_duplicate" - [(set (match_operand:VLS 0 "register_operand") - (vec_duplicate:VLS - (match_operand: 1 "reg_or_int_operand")))] - "TARGET_VECTOR && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] - { - riscv_vector::emit_vlmax_insn (code_for_pred_broadcast (mode), - riscv_vector::UNARY_OP, operands); - DONE; - } - [(set_attr "type" "vector")] -) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index fb0c8abd995..778ea9922b7 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -25,7 +25,6 @@ ;; - Intrinsics (https://github.com/riscv/rvv-intrinsic-doc) ;; - Auto-vectorization (autovec.md) ;; - Optimization (autovec-opt.md) -;; - VLS patterns (autovec-vls.md) (include "vector-iterators.md") @@ -1210,6 +1209,160 @@ [(set_attr "type" "vmov,vlde,vste") (set_attr "mode" "")]) +;; ----------------------------------------------------------------- +;; ---- VLS Moves Operations +;; ----------------------------------------------------------------- + +(define_expand "mov" + [(set (match_operand:VLS_AVL_IMM 0 "reg_or_mem_operand") + (match_operand:VLS_AVL_IMM 1 "general_operand"))] + "TARGET_VECTOR" +{ + if (riscv_vector::legitimize_move (operands[0], operands[1])) + DONE; +}) + +(define_insn_and_split "*mov_mem_to_mem" + [(set (match_operand:VLS_AVL_IMM 0 "memory_operand") + (match_operand:VLS_AVL_IMM 1 "memory_operand"))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + if (GET_MODE_BITSIZE (mode).to_constant () <= MAX_BITS_PER_WORD) + { + /* Opitmize the following case: + + typedef int8_t v2qi __attribute__ ((vector_size (2))); + v2qi v = *(v2qi*)in; + *(v2qi*)out = v; + + We prefer scalar load/store instead of vle.v/vse.v when + the VLS modes size is smaller scalar mode. */ + machine_mode mode; + unsigned size = GET_MODE_BITSIZE (mode).to_constant (); + if (FLOAT_MODE_P (mode)) + mode = mode_for_size (size, MODE_FLOAT, 0).require (); + else + mode = mode_for_size (size, MODE_INT, 0).require (); + emit_move_insn (gen_lowpart (mode, operands[0]), + gen_lowpart (mode, operands[1])); + } + else + { + operands[1] = force_reg (mode, operands[1]); + emit_move_insn (operands[0], operands[1]); + } + DONE; + } + [(set_attr "type" "vmov")] +) + +(define_insn_and_split "*mov" + [(set (match_operand:VLS_AVL_IMM 0 "reg_or_mem_operand" "=vr, m, vr") + (match_operand:VLS_AVL_IMM 1 "reg_or_mem_operand" " m,vr, vr"))] + "TARGET_VECTOR + && (register_operand (operands[0], mode) + || register_operand (operands[1], mode))" + "@ + # + # + vmv%m1r.v\t%0,%1" + "&& reload_completed + && (!register_operand (operands[0], mode) + || !register_operand (operands[1], mode))" + [(const_int 0)] + { + bool ok_p = riscv_vector::legitimize_move (operands[0], operands[1]); + gcc_assert (ok_p); + DONE; + } + [(set_attr "type" "vmov")] +) + +(define_expand "mov" + [(set (match_operand:VLS_AVL_REG 0 "reg_or_mem_operand") + (match_operand:VLS_AVL_REG 1 "general_operand"))] + "TARGET_VECTOR" +{ + bool ok_p = riscv_vector::legitimize_move (operands[0], operands[1]); + gcc_assert (ok_p); + DONE; +}) + +(define_expand "@mov_lra" + [(parallel + [(set (match_operand:VLS_AVL_REG 0 "reg_or_mem_operand") + (match_operand:VLS_AVL_REG 1 "reg_or_mem_operand")) + (clobber (match_scratch:P 2))])] + "TARGET_VECTOR && (lra_in_progress || reload_completed)" +{}) + +(define_insn_and_split "*mov_lra" + [(set (match_operand:VLS_AVL_REG 0 "reg_or_mem_operand" "=vr, m,vr") + (match_operand:VLS_AVL_REG 1 "reg_or_mem_operand" " m,vr,vr")) + (clobber (match_scratch:P 2 "=&r,&r,X"))] + "TARGET_VECTOR && (lra_in_progress || reload_completed) + && (register_operand (operands[0], mode) + || register_operand (operands[1], mode))" + "#" + "&& reload_completed" + [(const_int 0)] +{ + if (REG_P (operands[0]) && REG_P (operands[1])) + emit_insn (gen_rtx_SET (operands[0], operands[1])); + else + { + emit_move_insn (operands[2], gen_int_mode (GET_MODE_NUNITS (mode), + Pmode)); + unsigned insn_flags + = GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL + ? riscv_vector::UNARY_MASK_OP + : riscv_vector::UNARY_OP; + riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (mode), + insn_flags, operands, operands[2]); + } + DONE; +} + [(set_attr "type" "vmov")] +) + +(define_insn "*mov_vls" + [(set (match_operand:VLS 0 "register_operand" "=vr") + (match_operand:VLS 1 "register_operand" " vr"))] + "TARGET_VECTOR" + "vmv%m1r.v\t%0,%1" + [(set_attr "type" "vmov") + (set_attr "mode" "")]) + +(define_insn "*mov_vls" + [(set (match_operand:VLSB 0 "register_operand" "=vr") + (match_operand:VLSB 1 "register_operand" " vr"))] + "TARGET_VECTOR" + "vmv1r.v\t%0,%1" + [(set_attr "type" "vmov") + (set_attr "mode" "")]) + +(define_expand "movmisalign" + [(set (match_operand:VLS 0 "nonimmediate_operand") + (match_operand:VLS 1 "general_operand"))] + "TARGET_VECTOR" + { + /* To support misalign data movement, we should use + minimum element alignment load/store. */ + unsigned int size = GET_MODE_SIZE (GET_MODE_INNER (mode)); + poly_int64 nunits = GET_MODE_NUNITS (mode) * size; + machine_mode mode = riscv_vector::get_vector_mode (QImode, nunits).require (); + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + if (MEM_P (operands[0]) && !register_operand (operands[1], mode)) + operands[1] = force_reg (mode, operands[1]); + riscv_vector::emit_vlmax_insn (code_for_pred_mov (mode), riscv_vector::UNARY_OP, operands); + DONE; + } +) + ;; ----------------------------------------------------------------- ;; ---- Duplicate Operations ;; ----------------------------------------------------------------- @@ -1230,6 +1383,22 @@ } ) +(define_insn_and_split "@vec_duplicate" + [(set (match_operand:VLS 0 "register_operand") + (vec_duplicate:VLS + (match_operand: 1 "reg_or_int_operand")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + riscv_vector::emit_vlmax_insn (code_for_pred_broadcast (mode), + riscv_vector::UNARY_OP, operands); + DONE; + } + [(set_attr "type" "vector")] +) + ;; ----------------------------------------------------------------- ;; ---- 6. Configuration-Setting Instructions ;; ----------------------------------------------------------------- @@ -8540,4 +8709,3 @@ (include "autovec.md") (include "autovec-opt.md") -(include "autovec-vls.md")