From 298e76e6562bb79ed42cb4bc88aca817e6e58417 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 7 Jan 2021 15:00:39 +0000 Subject: [PATCH] gimple-isel: Check whether IFN_VCONDEQ is supported [PR98560] This patch follows on from the previous one for the PR and makes sure that we can handle == as well as <. Previously we assumed without checking that IFN_VCONDEQ was available if IFN_VCOND or IFN_VCONDU wasn't. The patch also fixes the definition of the IFN_VCOND* functions. The optabs are convert optabs in which the first mode is the data mode and the second mode is the comparison or mask mode. gcc/ PR tree-optimization/98560 * internal-fn.def (IFN_VCONDU, IFN_VCONDEQ): Use type vec_cond. * internal-fn.c (vec_cond_mask_direct): Get the data mode from argument 1. (vec_cond_direct): Likewise argument 2. (vec_condu_direct, vec_condeq_direct): Delete. (expand_vect_cond_optab_fn): Rename to... (expand_vec_cond_optab_fn): ...this, replacing old macro. (expand_vec_condu_optab_fn, expand_vec_condeq_optab_fn): Delete. (expand_vect_cond_mask_optab_fn): Rename to... (expand_vec_cond_mask_optab_fn): ...this, replacing old macro. (direct_vec_cond_mask_optab_supported_p): Treat the optab as a convert optab. (direct_vec_cond_optab_supported_p): Likewise. (direct_vec_condu_optab_supported_p): Delete. (direct_vec_condeq_optab_supported_p): Delete. * gimple-isel.cc: Include internal-fn.h. (gimple_expand_vec_cond_expr): Check that IFN_VCONDEQ is supported before using it. gcc/testsuite/ PR tree-optimization/98560 * gcc.dg/vect/pr98560-2.c: New test. --- gcc/gimple-isel.cc | 6 +++++- gcc/internal-fn.c | 22 ++++++---------------- gcc/internal-fn.def | 4 ++-- gcc/testsuite/gcc.dg/vect/pr98560-2.c | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr98560-2.c diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index 0f3d6bba229..2c78a08d3f1 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see #include "memmodel.h" #include "optabs.h" #include "gimple-fold.h" +#include "internal-fn.h" /* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into calls to internal function based on vector type of selected expansion. @@ -250,7 +251,10 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi, Try changing it to NE_EXPR. */ tcode = NE_EXPR; } - if (tcode == EQ_EXPR || tcode == NE_EXPR) + if ((tcode == EQ_EXPR || tcode == NE_EXPR) + && direct_internal_fn_supported_p (IFN_VCONDEQ, TREE_TYPE (lhs), + TREE_TYPE (op0a), + OPTIMIZE_FOR_BOTH)) { tree tcode_tree = build_int_cst (integer_type_node, tcode); return gimple_build_call_internal (IFN_VCONDEQ, 5, op0a, op0b, op1, diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 996f0fb6c67..dd7173126fb 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -110,10 +110,8 @@ init_internal_fns () #define mask_store_direct { 3, 2, false } #define store_lanes_direct { 0, 0, false } #define mask_store_lanes_direct { 0, 0, false } -#define vec_cond_mask_direct { 0, 0, false } -#define vec_cond_direct { 0, 0, false } -#define vec_condu_direct { 0, 0, false } -#define vec_condeq_direct { 0, 0, false } +#define vec_cond_mask_direct { 1, 0, false } +#define vec_cond_direct { 2, 0, false } #define scatter_store_direct { 3, 1, false } #define len_store_direct { 3, 3, false } #define vec_set_direct { 3, 3, false } @@ -2766,7 +2764,7 @@ expand_partial_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab) The expansion of STMT happens based on OPTAB table associated. */ static void -expand_vect_cond_optab_fn (internal_fn, gcall *stmt, convert_optab optab) +expand_vec_cond_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { class expand_operand ops[6]; insn_code icode; @@ -2802,15 +2800,11 @@ expand_vect_cond_optab_fn (internal_fn, gcall *stmt, convert_optab optab) emit_move_insn (target, ops[0].value); } -#define expand_vec_cond_optab_fn expand_vect_cond_optab_fn -#define expand_vec_condu_optab_fn expand_vect_cond_optab_fn -#define expand_vec_condeq_optab_fn expand_vect_cond_optab_fn - /* Expand VCOND_MASK optab internal function. The expansion of STMT happens based on OPTAB table associated. */ static void -expand_vect_cond_mask_optab_fn (internal_fn, gcall *stmt, convert_optab optab) +expand_vec_cond_mask_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { class expand_operand ops[4]; @@ -2844,8 +2838,6 @@ expand_vect_cond_mask_optab_fn (internal_fn, gcall *stmt, convert_optab optab) emit_move_insn (target, ops[0].value); } -#define expand_vec_cond_mask_optab_fn expand_vect_cond_mask_optab_fn - /* Expand VEC_SET internal functions. */ static void @@ -3570,10 +3562,8 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types, #define direct_mask_store_optab_supported_p convert_optab_supported_p #define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p #define direct_mask_store_lanes_optab_supported_p multi_vector_optab_supported_p -#define direct_vec_cond_mask_optab_supported_p multi_vector_optab_supported_p -#define direct_vec_cond_optab_supported_p multi_vector_optab_supported_p -#define direct_vec_condu_optab_supported_p multi_vector_optab_supported_p -#define direct_vec_condeq_optab_supported_p multi_vector_optab_supported_p +#define direct_vec_cond_mask_optab_supported_p convert_optab_supported_p +#define direct_vec_cond_optab_supported_p convert_optab_supported_p #define direct_scatter_store_optab_supported_p convert_optab_supported_p #define direct_len_store_optab_supported_p direct_optab_supported_p #define direct_while_optab_supported_p convert_optab_supported_p diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 9abf8043cca..19016ce109f 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -141,8 +141,8 @@ DEF_INTERNAL_OPTAB_FN (MASK_STORE_LANES, 0, vec_mask_store_lanes, mask_store_lanes) DEF_INTERNAL_OPTAB_FN (VCOND, 0, vcond, vec_cond) -DEF_INTERNAL_OPTAB_FN (VCONDU, 0, vcondu, vec_condu) -DEF_INTERNAL_OPTAB_FN (VCONDEQ, 0, vcondeq, vec_condeq) +DEF_INTERNAL_OPTAB_FN (VCONDU, 0, vcondu, vec_cond) +DEF_INTERNAL_OPTAB_FN (VCONDEQ, 0, vcondeq, vec_cond) DEF_INTERNAL_OPTAB_FN (VCOND_MASK, 0, vcond_mask, vec_cond_mask) DEF_INTERNAL_OPTAB_FN (VEC_SET, 0, vec_set, vec_set) diff --git a/gcc/testsuite/gcc.dg/vect/pr98560-2.c b/gcc/testsuite/gcc.dg/vect/pr98560-2.c new file mode 100644 index 00000000000..7759a5e8202 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr98560-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 -fno-tree-vrp -fno-tree-fre -fno-tree-pre -fno-code-hoisting -fvect-cost-model=dynamic" } */ +/* { dg-additional-options "-msve-vector-bits=128" { target aarch64_sve } } */ + +#include + +void +f (uint16_t *restrict dst, uint32_t *restrict src1, float *restrict src2) +{ + int i = 0; + for (int j = 0; j < 4; ++j) + { + uint16_t tmp = src1[i] >> 1; + dst[i] = (uint16_t) (src2[i] == 0 && i < 4 ? tmp : 1); + i += 1; + } +} -- 2.30.2