From 4124119974fd87380de607a6bc9bfdcffe1702d8 Mon Sep 17 00:00:00 2001 From: Renlin Li Date: Mon, 15 Oct 2018 16:49:05 +0000 Subject: [PATCH] [PR87563][AARCH64-SVE]: Don't keep ifcvt loop when COND_ ifn could not be vectorized. ifcvt will created versioned loop and it will permissively generate scalar COND_ ifn. If in the loop vectorize pass, COND_ could not get vectoized, the if-converted loop should be abandoned when the target doesn't support such ifn. gcc/ 2018-10-12 Renlin Li PR target/87563 * tree-vectorizer.c (try_vectorize_loop_1): Don't use if-conversioned loop when it contains ifn with types not supported by backend. * internal-fn.c (expand_direct_optab_fn): Add an assert. (direct_internal_fn_supported_p): New helper function. * internal-fn.h (direct_internal_fn_supported_p): Declare. gcc/testsuite/ 2018-10-12 Renlin Li PR target/87563 * gcc.target/aarch64/sve/pr87563.c: New. From-SVN: r265172 --- gcc/ChangeLog | 10 ++++++++ gcc/internal-fn.c | 12 ++++++++++ gcc/internal-fn.h | 1 + gcc/testsuite/ChangeLog | 5 ++++ .../gcc.target/aarch64/sve/pr87563.c | 18 ++++++++++++++ gcc/tree-vectorizer.c | 24 ++++++++++++------- 6 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr87563.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a2b703b581..0b8c7e555a6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-10-15 Renlin Li + + PR target/87563 + * tree-vectorizer.c (try_vectorize_loop_1): Don't use + if-conversioned loop when it contains ifn with types not + supported by backend. + * internal-fn.c (expand_direct_optab_fn): Add an assert. + (direct_internal_fn_supported_p): New helper function. + * internal-fn.h (direct_internal_fn_supported_p): Declare. + 2018-10-15 Jakub Jelinek PR target/87572 diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 34d4f9efab9..d082dd5054f 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -2890,6 +2890,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, tree_pair types = direct_internal_fn_types (fn, stmt); insn_code icode = direct_optab_handler (optab, TYPE_MODE (types.first)); + gcc_assert (icode != CODE_FOR_nothing); tree lhs = gimple_call_lhs (stmt); rtx lhs_rtx = NULL_RTX; @@ -3183,6 +3184,17 @@ direct_internal_fn_supported_p (internal_fn fn, tree type, return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type); } +/* Return true if the STMT is supported when the optimization type is OPT_TYPE, + given that STMT is a call to a direct internal function. */ + +bool +direct_internal_fn_supported_p (gcall *stmt, optimization_type opt_type) +{ + internal_fn fn = gimple_call_internal_fn (stmt); + tree_pair types = direct_internal_fn_types (fn, stmt); + return direct_internal_fn_supported_p (fn, types, opt_type); +} + /* If FN is commutative in two consecutive arguments, return the index of the first, otherwise return -1. */ diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h index 99765cf407a..ff3bace1ce6 100644 --- a/gcc/internal-fn.h +++ b/gcc/internal-fn.h @@ -187,6 +187,7 @@ extern bool direct_internal_fn_supported_p (internal_fn, tree_pair, optimization_type); extern bool direct_internal_fn_supported_p (internal_fn, tree, optimization_type); +extern bool direct_internal_fn_supported_p (gcall *, optimization_type); /* Return true if FN is supported for types TYPE0 and TYPE1 when the optimization type is OPT_TYPE. The types are those associated with diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f08abb18189..7f8b0852e90 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-10-15 Renlin Li + + PR target/87563 + * gcc.target/aarch64/sve/pr87563.c: New. + 2018-10-15 Paul Thomas Tobias Burnus diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr87563.c b/gcc/testsuite/gcc.target/aarch64/sve/pr87563.c new file mode 100644 index 00000000000..83553b7ceea --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr87563.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-ifcvt-details -fdump-tree-vect" } */ + +int a, b, c, *e; +int d[2]; + +void f () +{ + while (c) + { + d[0] = 4; + d[1] = 4; + *e = b == 0 ? 0 : a / b; + } +} + +/* { dg-final { scan-tree-dump "COND_DIV" "ifcvt" } } */ +/* { dg-final { scan-tree-dump-not "COND_DIV" "vect" } } */ diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 60ee7f6380c..12bf0fcd5bd 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -80,6 +80,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "gimple-pretty-print.h" #include "opt-problem.h" +#include "internal-fn.h" /* Loop or bb location, with hotness information. */ @@ -899,23 +900,30 @@ try_vectorize_loop_1 (hash_table *&simduid_to_vf_htab, && ! loop->inner) { basic_block bb = loop->header; - bool has_mask_load_store = false; + bool require_loop_vectorize = false; for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); - if (is_gimple_call (stmt) - && gimple_call_internal_p (stmt) - && (gimple_call_internal_fn (stmt) == IFN_MASK_LOAD - || gimple_call_internal_fn (stmt) == IFN_MASK_STORE)) + gcall *call = dyn_cast (stmt); + if (call && gimple_call_internal_p (call)) { - has_mask_load_store = true; - break; + internal_fn ifn = gimple_call_internal_fn (call); + if (ifn == IFN_MASK_LOAD || ifn == IFN_MASK_STORE + /* Don't keep the if-converted parts when the ifn with + specifc type is not supported by the backend. */ + || (direct_internal_fn_p (ifn) + && !direct_internal_fn_supported_p + (call, OPTIMIZE_FOR_SPEED))) + { + require_loop_vectorize = true; + break; + } } gimple_set_uid (stmt, -1); gimple_set_visited (stmt, false); } - if (! has_mask_load_store && vect_slp_bb (bb)) + if (!require_loop_vectorize && vect_slp_bb (bb)) { dump_printf_loc (MSG_NOTE, vect_location, "basic block vectorized\n"); -- 2.30.2