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

Reply via email to