Ilya Leoshkevich <i...@linux.ibm.com> writes: > 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 exists, which does not contain information about > the operation. > > Introduce a function that checks whether back-end supports vector > comparisons with individual rtx codes by matching vcond expander's third > argument with a fake comparison with the corresponding rtx code. > > gcc/ChangeLog: > > 2019-08-27 Ilya Leoshkevich <i...@linux.ibm.com> > > PR target/77918 > * optabs-tree.c (vcond_icode_p): New function. > (vcond_eq_icode_p): New function. > (expand_vec_cond_expr_p): Use vcond_icode_p and > vcond_eq_icode_p. > * optabs.c (can_vcond_compare_p): New function. > (get_rtx_code): Use get_rtx_code_safe. > (get_rtx_code_safe): New function. > * optabs.h (can_vcond_compare_p): New function. > (get_rtx_code_safe): Likewise. > --- > gcc/optabs-tree.c | 37 +++++++++++++++++++++++++++++++------ > gcc/optabs.c | 38 ++++++++++++++++++++++++++++++++++---- > gcc/optabs.h | 7 +++++++ > 3 files changed, 72 insertions(+), 10 deletions(-) > > diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c > index 8157798cc71..7f505c9cdee 100644 > --- a/gcc/optabs-tree.c > +++ b/gcc/optabs-tree.c > @@ -23,7 +23,10 @@ along with GCC; see the file COPYING3. If not see > #include "coretypes.h" > #include "target.h" > #include "insn-codes.h" > +#include "rtl.h" > #include "tree.h" > +#include "memmodel.h" > +#include "optabs.h" > #include "optabs-tree.h" > #include "stor-layout.h" > > @@ -329,6 +332,28 @@ expand_vec_cmp_expr_p (tree value_type, tree mask_type, > enum tree_code code) > return false; > } > > +/* Return true iff vcond_optab/vcondu_optab support the given tree > + comparison. */
Realise it's a bit repetitive in the context of this patch, but... /* Return true iff vcond_optab/vcondu_optab can handle a vector comparison for code CODE, comparing operands of type CMP_OP_TYPE and producing a result of type VALUE_TYPE. */ > + > +static bool > +vcond_icode_p (tree value_type, tree cmp_op_type, enum tree_code code) > +{ > + return can_vcond_compare_p (get_rtx_code (code, TYPE_UNSIGNED > (cmp_op_type)), > + TYPE_MODE (value_type), TYPE_MODE (cmp_op_type)); > +} > + > +/* Return true iff vcondeq_optab supports the given tree comparison. */ Same idea here. > + > +static bool > +vcond_eq_icode_p (tree value_type, tree cmp_op_type, enum tree_code code) > +{ > + if (code != EQ_EXPR && code != NE_EXPR) > + return false; > + > + return get_vcond_eq_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type)) > + != CODE_FOR_nothing; > +} > + > /* Return TRUE iff, appropriate vector insns are available > for vector cond expr with vector type VALUE_TYPE and a comparison > with operand vector types in CMP_OP_TYPE. */ > @@ -347,14 +372,14 @@ 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 > - && ((code != EQ_EXPR && code != NE_EXPR) > - || get_vcond_eq_icode (TYPE_MODE (value_type), > - TYPE_MODE (cmp_op_type)) == CODE_FOR_nothing)) > + if (get_rtx_code_safe (code, TYPE_UNSIGNED (cmp_op_type)) > + == LAST_AND_UNUSED_RTX_CODE) > + /* This may happen, for example, if code == SSA_NAME, in which case we > + cannot be certain whether a vector insn is available. */ > return false; I think this should just be: if (TREE_CODE_CLASS (tcode) != tcc_comparison) return false; OK with those changes and without the introduction of get_rtx_code_safe. Thanks, Richard