return nops == 3 ? ops[2] : ops[0];
}
+/* Implement TARGET_INSTRUCTION_SELECTION. The target hook is used to
+ change generic sequences to a form AArch64 has an easier time expanding
+ instructions for. It's not supposed to be used for generic rewriting that
+ all targets would benefit from. */
+
+static bool
+aarch64_instruction_selection (function * /* fun */, gimple_stmt_iterator *gsi)
+{
+ auto stmt = gsi_stmt (*gsi);
+ gassign *assign = dyn_cast<gassign *> (stmt);
+
+ if (!assign)
+ return false;
+
+ /* Convert
+ p == q ? s1 : s2;
+ to
+ p != q ? s2 : s1;
+ where p and q are svbool_t expr. Due to the absence of predicate
+ comparison instructions, we use bitwise xor for checking inequality.
+ Transforming == to != avoids an extra bitwise inversion to the xor. */
+ if (gimple_assign_rhs_code (assign) != VEC_COND_EXPR)
+ return false;
+
+ tree lhs = gimple_assign_lhs (assign);
+ tree rhs1 = gimple_assign_rhs1 (assign);
+ tree rhs2 = gimple_assign_rhs2 (assign);
+ tree rhs3 = gimple_assign_rhs3 (assign);
+
+ if (TREE_CODE (rhs1) != SSA_NAME || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
+ return false;
+
+ gassign *da = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (rhs1));
+
+ if (!da)
+ return false;
+
+ if (gimple_assign_rhs_code (da) != EQ_EXPR)
+ return false;
+
+ tree eqa = gimple_assign_rhs1 (da);
+ tree eqb = gimple_assign_rhs2 (da);
+
+ if (!VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqa))
+ || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqb)))
+ return false;
+
+ tree ne_expr_var = create_tmp_var (TREE_TYPE (rhs1));
+ gimple *ne_stmt = gimple_build_assign (ne_expr_var, NE_EXPR, eqa, eqb);
+ gsi_safe_insert_before (gsi, ne_stmt);
+
+ gimple *g = gimple_build_call_internal (IFN_VCOND_MASK, 3,
+ ne_expr_var, rhs3, rhs2);
+ if (!g)
+ return false;
+
+ gimple_set_lhs (g, lhs);
+ gsi_replace (gsi, g, false);
+
+ return true;
+}
+
/* Implement TARGET_HARD_REGNO_NREGS. */
static unsigned int
#define TARGET_PREFERRED_ELSE_VALUE \
aarch64_preferred_else_value
+#undef TARGET_INSTRUCTION_SELECTION
+#define TARGET_INSTRUCTION_SELECTION aarch64_instruction_selection
+
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS aarch64_init_libfuncs