+2018-10-15 Renlin Li <renlin.li@arm.com>
+
+ 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 <jakub@redhat.com>
PR target/87572
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;
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. */
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
+2018-10-15 Renlin Li <renlin.li@arm.com>
+
+ PR target/87563
+ * gcc.target/aarch64/sve/pr87563.c: New.
+
2018-10-15 Paul Thomas <pault@gcc.gnu.org>
Tobias Burnus <burnus@gcc.gnu.org>
--- /dev/null
+/* { 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" } } */
#include "attribs.h"
#include "gimple-pretty-print.h"
#include "opt-problem.h"
+#include "internal-fn.h"
/* Loop or bb location, with hotness information. */
&& ! 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 <gcall *> (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");