From 96592eeda1f5cb381d91ef78dea3e2666bbdb7b5 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 25 Oct 2016 18:26:12 +0200 Subject: re PR target/78102 (GCC refuses to generate PCMPEQQ instruction for SSE4.1) PR target/78102 * optabs.def (vcondeq_optab, vec_cmpeq_optab): New optabs. * optabs.c (expand_vec_cond_expr): For comparison codes EQ_EXPR and NE_EXPR, attempt vcondeq_optab as fallback. (expand_vec_cmp_expr): For comparison codes EQ_EXPR and NE_EXPR, attempt vec_cmpeq_optab as fallback. * optabs-tree.h (expand_vec_cmp_expr_p, expand_vec_cond_expr_p): Add enum tree_code argument. * optabs-query.h (get_vec_cmp_eq_icode, get_vcond_eq_icode): New inline functions. * optabs-tree.c (expand_vec_cmp_expr_p): Add CODE argument. For CODE EQ_EXPR or NE_EXPR, attempt to use vec_cmpeq_optab as fallback. (expand_vec_cond_expr_p): Add CODE argument. For CODE EQ_EXPR or NE_EXPR, attempt to use vcondeq_optab as fallback. * tree-vect-generic.c (expand_vector_comparison, expand_vector_divmod, expand_vector_condition): Adjust expand_vec_cmp_expr_p and expand_vec_cond_expr_p callers. * tree-vect-stmts.c (vectorizable_condition, vectorizable_comparison): Likewise. * tree-vect-patterns.c (vect_recog_mixed_size_cond_pattern, check_bool_pattern, search_type_for_mask_1): Likewise. * expr.c (do_store_flag): Likewise. * doc/md.texi (@code{vec_cmpeq@var{m}@var{n}}, @code{vcondeq@var{m}@var{n}}): Document. * config/i386/sse.md (vec_cmpeqv2div2di, vcondeqv2di): New expanders. testsuite/ * gcc.target/i386/pr78102.c: New test. From-SVN: r241525 --- gcc/optabs-tree.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'gcc/optabs-tree.c') diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c index faac087..28f5344 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -305,12 +305,16 @@ supportable_convert_operation (enum tree_code code, and resulting mask with MASK_TYPE. */ bool -expand_vec_cmp_expr_p (tree value_type, tree mask_type) +expand_vec_cmp_expr_p (tree value_type, tree mask_type, enum tree_code code) { - enum insn_code icode = get_vec_cmp_icode (TYPE_MODE (value_type), - TYPE_MODE (mask_type), - TYPE_UNSIGNED (value_type)); - return (icode != CODE_FOR_nothing); + if (get_vec_cmp_icode (TYPE_MODE (value_type), TYPE_MODE (mask_type), + TYPE_UNSIGNED (value_type)) != CODE_FOR_nothing) + return true; + if ((code == EQ_EXPR || code == NE_EXPR) + && (get_vec_cmp_eq_icode (TYPE_MODE (value_type), TYPE_MODE (mask_type)) + != CODE_FOR_nothing)) + return true; + return false; } /* Return TRUE iff, appropriate vector insns are available @@ -318,7 +322,7 @@ expand_vec_cmp_expr_p (tree value_type, tree mask_type) with operand vector types in CMP_OP_TYPE. */ bool -expand_vec_cond_expr_p (tree value_type, tree cmp_op_type) +expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code) { machine_mode value_mode = TYPE_MODE (value_type); machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type); @@ -328,10 +332,16 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type) return true; if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode) - || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode) - || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type), - TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing) + || 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)) + return false; + return true; } -- cgit v1.1