z13 supports only non-signaling vector comparisons. This means we cannot vectorize LT, LE, GT, GE and LTGT when compiling for z13. However, we cannot express this restriction today: the code only checks whether vcond$a$b optab, which does not contain information about the operation.
Introduce a hook that tells whether target supports certain vector comparison operations with certain modes. gcc/ChangeLog: 2019-08-09 Ilya Leoshkevich <i...@linux.ibm.com> * doc/tm.texi (TARGET_VCOND_SUPPORTED_P): Document. * doc/tm.texi.in (TARGET_VCOND_SUPPORTED_P): Document. * optabs-tree.c (expand_vec_cond_expr_p): Use vcond_supported_p in addition to get_vcond_icode. * target.def (vcond_supported_p): New hook. * targhooks.c (default_vcond_supported_p): Likewise. * targhooks.h (default_vcond_supported_p): Likewise. --- gcc/doc/tm.texi | 9 +++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/optabs-tree.c | 6 ++++-- gcc/target.def | 11 +++++++++++ gcc/targhooks.c | 12 ++++++++++++ gcc/targhooks.h | 1 + 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 4eadd0c9300..23ccce1d3f4 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4326,6 +4326,15 @@ insns involving vector mode @var{mode}. At the very least, it must have move patterns for this mode. @end deftypefn +@deftypefn {Target Hook} bool TARGET_VCOND_SUPPORTED_P (machine_mode @var{result_mode}, machine_mode @var{op_mode}, int @var{code}) +Define this to restrict which vector comparison operations are supported by +vcond$a$b expander. An operation is represented by its operand machine mode +@code{OP_MODE}, its result machine mode @code{RESULT_MODE} and @code{enum +tree_code CODE}. The main use of this hook is to support machines which +provide only certain vector comparison instructions, e.g. only non-signaling +ones. The default is that all operations are supported. +@end deftypefn + @deftypefn {Target Hook} opt_machine_mode TARGET_ARRAY_MODE (machine_mode @var{mode}, unsigned HOST_WIDE_INT @var{nelems}) Return the mode that GCC should use for an array that has @var{nelems} elements, with each element having mode @var{mode}. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 04f236f611e..a4399cd9d12 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3366,6 +3366,8 @@ stack. @hook TARGET_VECTOR_MODE_SUPPORTED_P +@hook TARGET_VCOND_SUPPORTED_P + @hook TARGET_ARRAY_MODE @hook TARGET_ARRAY_MODE_SUPPORTED_P diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c index 8157798cc71..de62e3d2765 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -347,8 +347,10 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code) || maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode))) return false; - if (get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type), - TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing + if (((get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type), + TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing) + || !targetm.vcond_supported_p (TYPE_MODE (value_type), + TYPE_MODE (cmp_op_type), code)) && ((code != EQ_EXPR && code != NE_EXPR) || get_vcond_eq_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type)) == CODE_FOR_nothing)) diff --git a/gcc/target.def b/gcc/target.def index b2332d8215c..4cd2a964c0e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3379,6 +3379,17 @@ the vector element type.", HOST_WIDE_INT, (const_tree type), default_vector_alignment) +DEFHOOK +(vcond_supported_p, + "Define this to restrict which vector comparison operations are supported by\n\ +vcond$a$b expander. An operation is represented by its operand machine mode\n\ +@code{OP_MODE}, its result machine mode @code{RESULT_MODE} and @code{enum\n\ +tree_code CODE}. The main use of this hook is to support machines which\n\ +provide only certain vector comparison instructions, e.g. only non-signaling\n\ +ones. The default is that all operations are supported.", + bool, (machine_mode result_mode, machine_mode op_mode, int code), + default_vcond_supported_p) + DEFHOOK (array_mode, "Return the mode that GCC should use for an array that has\n\ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 1d12ec54704..2b9a5d12bab 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -448,6 +448,18 @@ default_scalar_mode_supported_p (scalar_mode mode) } } +/* Return true if vcond$a$b expander supports vector comparisons using the CODE + of type enum tree_code, in which the operands have machine mode OP_MODE and + the result has machine mode RESULT_MODE. */ + +bool +default_vcond_supported_p (machine_mode result_mode ATTRIBUTE_UNUSED, + machine_mode op_mode ATTRIBUTE_UNUSED, + int code ATTRIBUTE_UNUSED) +{ + return true; +} + /* Return true if libgcc supports floating-point mode MODE (known to be supported as a scalar mode). */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 20a6e79d2d2..771a0996567 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -76,6 +76,7 @@ extern tree default_mangle_assembler_name (const char *); extern machine_mode default_translate_mode_attribute (machine_mode); extern bool default_scalar_mode_supported_p (scalar_mode); +extern bool default_vcond_supported_p (machine_mode, machine_mode, int); extern bool default_libgcc_floating_mode_supported_p (scalar_float_mode); extern opt_scalar_float_mode default_floatn_mode (int, bool); extern bool default_floatn_builtin_p (int); -- 2.21.0