diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-11-16 11:14:51 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-11-16 11:14:51 +0000 |
commit | 2d56600c8de397d09a16dedd33d310a763a832ae (patch) | |
tree | 56564f83914ac39ee039165188613c4b2820732e /gcc/config | |
parent | 217ccab8f46ca5b260319e7b71b421daec6d11c8 (diff) | |
download | gcc-2d56600c8de397d09a16dedd33d310a763a832ae.zip gcc-2d56600c8de397d09a16dedd33d310a763a832ae.tar.gz gcc-2d56600c8de397d09a16dedd33d310a763a832ae.tar.bz2 |
[AArch64] Add truncation for partial SVE modes
This patch adds support for "truncating" to a partial SVE vector from
either a full SVE vector or a wider partial vector. This truncation is
actually a no-op and so should have zero cost in the vector cost model.
2019-11-16 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* config/aarch64/aarch64-sve.md
(trunc<SVE_HSDI:mode><SVE_PARTIAL_I:mode>2): New pattern.
* config/aarch64/aarch64.c (aarch64_integer_truncation_p): New
function.
(aarch64_sve_adjust_stmt_cost): Call it.
gcc/testsuite/
* gcc.target/aarch64/sve/mask_struct_load_1.c: Add
--param aarch64-sve-compare-costs=0.
* gcc.target/aarch64/sve/mask_struct_load_2.c: Likewise.
* gcc.target/aarch64/sve/mask_struct_load_3.c: Likewise.
* gcc.target/aarch64/sve/mask_struct_load_4.c: Likewise.
* gcc.target/aarch64/sve/mask_struct_load_5.c: Likewise.
* gcc.target/aarch64/sve/pack_1.c: Likewise.
* gcc.target/aarch64/sve/truncate_1.c: New test.
From-SVN: r278344
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/aarch64/aarch64-sve.md | 24 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 20 |
2 files changed, 44 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index ce1bd58..158a178 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -72,6 +72,7 @@ ;; ---- [INT] General unary arithmetic corresponding to rtx codes ;; ---- [INT] General unary arithmetic corresponding to unspecs ;; ---- [INT] Sign and zero extension +;; ---- [INT] Truncation ;; ---- [INT] Logical inverse ;; ---- [FP<-INT] General unary arithmetic that maps to unspecs ;; ---- [FP] General unary arithmetic corresponding to unspecs @@ -2889,6 +2890,29 @@ ) ;; ------------------------------------------------------------------------- +;; ---- [INT] Truncation +;; ------------------------------------------------------------------------- +;; The patterns in this section are synthetic. +;; ------------------------------------------------------------------------- + +;; Truncate to a partial SVE vector from either a full vector or a +;; wider partial vector. This is a no-op, because we can just ignore +;; the unused upper bits of the source. +(define_insn_and_split "trunc<SVE_HSDI:mode><SVE_PARTIAL_I:mode>2" + [(set (match_operand:SVE_PARTIAL_I 0 "register_operand" "=w") + (truncate:SVE_PARTIAL_I + (match_operand:SVE_HSDI 1 "register_operand" "w")))] + "TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 1))] + { + operands[1] = aarch64_replace_reg_mode (operands[1], + <SVE_PARTIAL_I:MODE>mode); + } +) + +;; ------------------------------------------------------------------------- ;; ---- [INT] Logical inverse ;; ------------------------------------------------------------------------- ;; Includes: diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 305c6da..f710aa2 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -12901,6 +12901,21 @@ aarch64_extending_load_p (stmt_vec_info stmt_info) && DR_IS_READ (STMT_VINFO_DATA_REF (def_stmt_info))); } +/* Return true if STMT_INFO is an integer truncation. */ +static bool +aarch64_integer_truncation_p (stmt_vec_info stmt_info) +{ + gassign *assign = dyn_cast <gassign *> (stmt_info->stmt); + if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (assign))) + return false; + + tree lhs_type = TREE_TYPE (gimple_assign_lhs (assign)); + tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (assign)); + return (INTEGRAL_TYPE_P (lhs_type) + && INTEGRAL_TYPE_P (rhs_type) + && TYPE_PRECISION (lhs_type) < TYPE_PRECISION (rhs_type)); +} + /* STMT_COST is the cost calculated by aarch64_builtin_vectorization_cost for STMT_INFO, which has cost kind KIND. Adjust the cost as necessary for SVE targets. */ @@ -12919,6 +12934,11 @@ aarch64_sve_adjust_stmt_cost (vect_cost_for_stmt kind, stmt_vec_info stmt_info, if (kind == vector_stmt && aarch64_extending_load_p (stmt_info)) stmt_cost = 0; + /* For similar reasons, vector_stmt integer truncations are a no-op, + because we can just ignore the unused upper bits of the source. */ + if (kind == vector_stmt && aarch64_integer_truncation_p (stmt_info)) + stmt_cost = 0; + return stmt_cost; } |