gimple-isel: Check whether IFN_VCONDEQ is supported [PR98560]
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 7 Jan 2021 15:00:39 +0000 (15:00 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 7 Jan 2021 15:00:39 +0000 (15:00 +0000)
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
gcc/internal-fn.c
gcc/internal-fn.def
gcc/testsuite/gcc.dg/vect/pr98560-2.c [new file with mode: 0644]

index 0f3d6bba2293c31e21aa5bde55122a76b7bd1434..2c78a08d3f18b8a47a20af099695d734eedcbd22 100644 (file)
@@ -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,
index 996f0fb6c67766496f001dba503c96beeb31a8b0..dd7173126fbb99be398cb0c760ab5ebc1a576335 100644 (file)
@@ -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
index 9abf8043cca58be6c4dab2b83df40abf0a871ac6..19016ce109f30f54f545162c2947a3bdca9ef02c 100644 (file)
@@ -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 (file)
index 0000000..7759a5e
--- /dev/null
@@ -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 <stdint.h>
+
+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;
+    }
+}