aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/tree-vect-loop.c18
-rw-r--r--gcc/tree-vect-stmts.c45
-rw-r--r--gcc/tree-vectorizer.h1
3 files changed, 56 insertions, 8 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 37c7daa..995d143 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -7234,6 +7234,14 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
dump_printf (MSG_NOTE, "proceeding using word mode.\n");
}
+ if (vect_emulated_vector_p (vectype_in)
+ && !vect_can_vectorize_without_simd_p (code))
+ {
+ if (dump_enabled_p ())
+ dump_printf (MSG_NOTE, "using word mode not possible.\n");
+ return false;
+ }
+
/* lane-reducing operations have to go through vect_transform_reduction.
For the other cases try without the single cycle optimization. */
if (!ok)
@@ -7936,6 +7944,16 @@ vectorizable_phi (vec_info *,
return true;
}
+/* Return true if VECTYPE represents a vector that requires lowering
+ by the vector lowering pass. */
+
+bool
+vect_emulated_vector_p (tree vectype)
+{
+ return (!VECTOR_MODE_P (TYPE_MODE (vectype))
+ && (!VECTOR_BOOLEAN_TYPE_P (vectype)
+ || TYPE_PRECISION (TREE_TYPE (vectype)) != 1));
+}
/* Return true if we can emulate CODE on an integer mode representation
of a vector. */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 5b94d41..5a5a4da 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -5682,15 +5682,11 @@ vectorizable_shift (vec_info *vinfo,
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"op not supported by target.\n");
- /* Check only during analysis. */
- if (maybe_ne (GET_MODE_SIZE (vec_mode), UNITS_PER_WORD)
- || (!vec_stmt
- && !vect_can_vectorize_without_simd_p (code)))
- return false;
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "proceeding using word mode.\n");
+ return false;
}
+ /* vector lowering cannot optimize vector shifts using word arithmetic. */
+ if (vect_emulated_vector_p (vectype))
+ return false;
if (!vec_stmt) /* transformation not required. */
{
@@ -6076,6 +6072,7 @@ vectorizable_operation (vec_info *vinfo,
!= CODE_FOR_nothing);
}
+ bool using_emulated_vectors_p = vect_emulated_vector_p (vectype);
if (!target_support_p)
{
if (dump_enabled_p ())
@@ -6088,6 +6085,15 @@ vectorizable_operation (vec_info *vinfo,
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"proceeding using word mode.\n");
+ using_emulated_vectors_p = true;
+ }
+
+ if (using_emulated_vectors_p
+ && !vect_can_vectorize_without_simd_p (code))
+ {
+ if (dump_enabled_p ())
+ dump_printf (MSG_NOTE, "using word mode not possible.\n");
+ return false;
}
int reduc_idx = STMT_VINFO_REDUC_IDX (stmt_info);
@@ -6134,6 +6140,29 @@ vectorizable_operation (vec_info *vinfo,
DUMP_VECT_SCOPE ("vectorizable_operation");
vect_model_simple_cost (vinfo, stmt_info,
ncopies, dt, ndts, slp_node, cost_vec);
+ if (using_emulated_vectors_p)
+ {
+ /* The above vect_model_simple_cost call handles constants
+ in the prologue and (mis-)costs one of the stmts as
+ vector stmt. See tree-vect-generic.c:do_plus_minus/do_negate
+ for the actual lowering that will be applied. */
+ unsigned n
+ = slp_node ? SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) : ncopies;
+ switch (code)
+ {
+ case PLUS_EXPR:
+ n *= 5;
+ break;
+ case MINUS_EXPR:
+ n *= 6;
+ break;
+ case NEGATE_EXPR:
+ n *= 4;
+ break;
+ default:;
+ }
+ record_stmt_cost (cost_vec, n, scalar_stmt, stmt_info, 0, vect_body);
+ }
return true;
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index de0ecf8..9c2c29d 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -2061,6 +2061,7 @@ extern bool vectorizable_lc_phi (loop_vec_info, stmt_vec_info,
gimple **, slp_tree);
extern bool vectorizable_phi (vec_info *, stmt_vec_info, gimple **, slp_tree,
stmt_vector_for_cost *);
+extern bool vect_emulated_vector_p (tree);
extern bool vect_can_vectorize_without_simd_p (tree_code);
extern int vect_get_known_peeling_cost (loop_vec_info, int, int *,
stmt_vector_for_cost *,