+2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * tree-vect-patterns.c (vect_recog_mask_conversion_pattern): When
+ handling COND_EXPRs with boolean comparisons, try to find a better
+ basis for the mask type than the boolean itself.
+
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
* doc/rtl.texi (MAX_BITSIZE_MODE_ANY_MODE): Describe how the default
return NULL;
}
else if (COMPARISON_CLASS_P (rhs1))
- rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
+ {
+ /* Check whether we're comparing scalar booleans and (if so)
+ whether a better mask type exists than the mask associated
+ with boolean-sized elements. This avoids unnecessary packs
+ and unpacks if the booleans are set from comparisons of
+ wider types. E.g. in:
+
+ int x1, x2, x3, x4, y1, y1;
+ ...
+ bool b1 = (x1 == x2);
+ bool b2 = (x3 == x4);
+ ... = b1 == b2 ? y1 : y2;
+
+ it is better for b1 and b2 to use the mask type associated
+ with int elements rather bool (byte) elements. */
+ rhs1_type = search_type_for_mask (TREE_OPERAND (rhs1, 0), vinfo);
+ if (!rhs1_type)
+ rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
+ }
else
return NULL;
vectype2 = get_mask_type_for_scalar_type (rhs1_type);
- if (!vectype1 || !vectype2
- || known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
- TYPE_VECTOR_SUBPARTS (vectype2)))
+ if (!vectype1 || !vectype2)
+ return NULL;
+
+ /* Continue if a conversion is needed. Also continue if we have
+ a comparison whose vector type would normally be different from
+ VECTYPE2 when considered in isolation. In that case we'll
+ replace the comparison with an SSA name (so that we can record
+ its vector type) and behave as though the comparison was an SSA
+ name from the outset. */
+ if (known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
+ TYPE_VECTOR_SUBPARTS (vectype2))
+ && (TREE_CODE (rhs1) == SSA_NAME
+ || rhs1_type == TREE_TYPE (TREE_OPERAND (rhs1, 0))))
return NULL;
/* If rhs1 is invariant and we can promote it leave the COND_EXPR
append_pattern_def_seq (stmt_vinfo, pattern_stmt);
}
- tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
+ if (maybe_ne (TYPE_VECTOR_SUBPARTS (vectype1),
+ TYPE_VECTOR_SUBPARTS (vectype2)))
+ tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
+ else
+ tmp = rhs1;
lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
pattern_stmt = gimple_build_assign (lhs, COND_EXPR, tmp,