diff options
author | Yuliang Wang <yuliang.wang@arm.com> | 2019-09-30 16:55:45 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-09-30 16:55:45 +0000 |
commit | c0c2f013906a695b8a02226f119649a370d9e083 (patch) | |
tree | 6743c5d13bf23522c114e0de5e187c1dade8a1c4 /gcc/tree-vect-patterns.c | |
parent | dcdd0f055731a8c960a15e5de8715d041d9a7876 (diff) | |
download | gcc-c0c2f013906a695b8a02226f119649a370d9e083.zip gcc-c0c2f013906a695b8a02226f119649a370d9e083.tar.gz gcc-c0c2f013906a695b8a02226f119649a370d9e083.tar.bz2 |
[AArch64][SVE] Utilize ASRD instruction for division and remainder
2019-09-30 Yuliang Wang <yuliang.wang@arm.com>
gcc/
* config/aarch64/aarch64-sve.md (sdiv_pow2<mode>3):
New pattern for ASRD.
* config/aarch64/iterators.md (UNSPEC_ASRD): New unspec.
* internal-fn.def (IFN_DIV_POW2): New internal function.
* optabs.def (sdiv_pow2_optab): New optab.
* tree-vect-patterns.c (vect_recog_divmod_pattern):
Modify pattern to support new operation.
* doc/md.texi (sdiv_pow2$var{m3}): Documentation for the above.
* doc/sourcebuild.texi (vect_sdiv_pow2_si):
Document new target selector.
gcc/testsuite/
* gcc.dg/vect/vect-sdiv-pow2-1.c: New test.
* gcc.target/aarch64/sve/asrdiv_1.c: As above.
* lib/target-supports.exp (check_effective_target_vect_sdiv_pow2_si):
Return true for AArch64 with SVE.
From-SVN: r276343
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r-- | gcc/tree-vect-patterns.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index baa9a4c..4dfebbe 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -2927,6 +2927,37 @@ vect_recog_divmod_pattern (stmt_vec_info stmt_vinfo, tree *type_out) /* Pattern detected. */ vect_pattern_detected ("vect_recog_divmod_pattern", last_stmt); + *type_out = vectype; + + /* Check if the target supports this internal function. */ + internal_fn ifn = IFN_DIV_POW2; + if (direct_internal_fn_supported_p (ifn, vectype, OPTIMIZE_FOR_SPEED)) + { + tree shift = build_int_cst (itype, tree_log2 (oprnd1)); + + tree var_div = vect_recog_temp_ssa_var (itype, NULL); + gimple *div_stmt = gimple_build_call_internal (ifn, 2, oprnd0, shift); + gimple_call_set_lhs (div_stmt, var_div); + + if (rhs_code == TRUNC_MOD_EXPR) + { + append_pattern_def_seq (stmt_vinfo, div_stmt); + def_stmt + = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL), + LSHIFT_EXPR, var_div, shift); + append_pattern_def_seq (stmt_vinfo, def_stmt); + pattern_stmt + = gimple_build_assign (vect_recog_temp_ssa_var (itype, NULL), + MINUS_EXPR, oprnd0, + gimple_assign_lhs (def_stmt)); + } + else + pattern_stmt = div_stmt; + gimple_set_location (pattern_stmt, gimple_location (last_stmt)); + + return pattern_stmt; + } + cond = build2 (LT_EXPR, boolean_type_node, oprnd0, build_int_cst (itype, 0)); if (rhs_code == TRUNC_DIV_EXPR @@ -3003,7 +3034,6 @@ vect_recog_divmod_pattern (stmt_vec_info stmt_vinfo, tree *type_out) signmask); } - *type_out = vectype; return pattern_stmt; } |