aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/aarch64/aarch64.cc59
1 files changed, 57 insertions, 2 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 53fbecb..7cd230c 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -16447,6 +16447,49 @@ aarch64_multiply_add_p (vec_info *vinfo, stmt_vec_info stmt_info,
return false;
}
+/* Return true if STMT_INFO is the second part of a two-statement boolean AND
+ expression sequence that might be suitable for fusing into a
+ single instruction. If VEC_FLAGS is zero, analyze the operation as
+ a scalar one, otherwise analyze it as an operation on vectors with those
+ VEC_* flags. */
+
+static bool
+aarch64_bool_compound_p (vec_info *vinfo, stmt_vec_info stmt_info,
+ unsigned int vec_flags)
+{
+ gassign *assign = dyn_cast<gassign *> (stmt_info->stmt);
+ if (!assign
+ || gimple_assign_rhs_code (assign) != BIT_AND_EXPR
+ || !STMT_VINFO_VECTYPE (stmt_info)
+ || !VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_info)))
+ return false;
+
+ for (int i = 1; i < 3; ++i)
+ {
+ tree rhs = gimple_op (assign, i);
+
+ if (TREE_CODE (rhs) != SSA_NAME)
+ continue;
+
+ stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
+ if (!def_stmt_info
+ || STMT_VINFO_DEF_TYPE (def_stmt_info) != vect_internal_def)
+ continue;
+
+ gassign *rhs_assign = dyn_cast<gassign *> (def_stmt_info->stmt);
+ if (!rhs_assign
+ || TREE_CODE_CLASS (gimple_assign_rhs_code (rhs_assign))
+ != tcc_comparison)
+ continue;
+
+ if (vec_flags & VEC_ADVSIMD)
+ return false;
+
+ return true;
+ }
+ return false;
+}
+
/* We are considering implementing STMT_INFO using SVE. If STMT_INFO is an
in-loop reduction that SVE supports directly, return its latency in cycles,
otherwise return zero. SVE_COSTS specifies the latencies of the relevant
@@ -16744,10 +16787,16 @@ aarch64_adjust_stmt_cost (vec_info *vinfo, vect_cost_for_stmt kind,
}
gassign *assign = dyn_cast<gassign *> (STMT_VINFO_STMT (stmt_info));
- if (assign && !vect_is_reduction (stmt_info))
+ if (assign)
{
/* For MLA we need to reduce the cost since MLA is 1 instruction. */
- if (aarch64_multiply_add_p (vinfo, stmt_info, vec_flags))
+ if (!vect_is_reduction (stmt_info)
+ && aarch64_multiply_add_p (vinfo, stmt_info, vec_flags))
+ return 0;
+
+ /* For vector boolean ANDs with a compare operand we just need
+ one insn. */
+ if (aarch64_bool_compound_p (vinfo, stmt_info, vec_flags))
return 0;
}
@@ -16823,6 +16872,12 @@ aarch64_vector_costs::count_ops (unsigned int count, vect_cost_for_stmt kind,
if (stmt_info && aarch64_multiply_add_p (m_vinfo, stmt_info, m_vec_flags))
return;
+ /* Assume that bool AND with compare operands will become a single
+ operation. */
+ if (stmt_info
+ && aarch64_bool_compound_p (m_vinfo, stmt_info, m_vec_flags))
+ return;
+
/* Count the basic operation cost associated with KIND. */
switch (kind)
{