internal-fn.c (expand_MASK_LOAD): Adjust to maskload optab changes.
authorIlya Enkovich <enkovich.gnu@gmail.com>
Tue, 10 Nov 2015 12:06:05 +0000 (12:06 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Tue, 10 Nov 2015 12:06:05 +0000 (12:06 +0000)
gcc/

* internal-fn.c (expand_MASK_LOAD): Adjust to maskload optab changes.
(expand_MASK_STORE): Adjust to maskstore optab changes.
* optabs-query.c (can_vec_mask_load_store_p): Add MASK_MODE arg.
 Adjust to maskload, maskstore optab changes.
* optabs-query.h (can_vec_mask_load_store_p): Add MASK_MODE arg.
* optabs.def (maskload_optab): Transform into convert optab.
(maskstore_optab): Likewise.
* tree-if-conv.c (ifcvt_can_use_mask_load_store): Adjust to
can_vec_mask_load_store_p signature change.
(predicate_mem_writes): Use boolean mask.
* tree-vect-stmts.c (vectorizable_mask_load_store): Adjust to
can_vec_mask_load_store_p signature change.  Allow invariant masks.
(vectorizable_operation): Ignore type precision for boolean vectors.

gcc/testsuite/

* gcc.target/i386/avx2-vec-mask-bit-not.c: New test.

From-SVN: r230099

gcc/ChangeLog
gcc/internal-fn.c
gcc/optabs-query.c
gcc/optabs-query.h
gcc/optabs.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/avx2-vec-mask-bit-not.c [new file with mode: 0644]
gcc/tree-if-conv.c
gcc/tree-vect-stmts.c

index 0141553d30799ac5e3fda72ab8b716f794eda3f8..a7421a995debad9323f1deb3126d12d23cd02864 100644 (file)
@@ -1,3 +1,19 @@
+2015-11-10  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       * internal-fn.c (expand_MASK_LOAD): Adjust to maskload optab changes.
+       (expand_MASK_STORE): Adjust to maskstore optab changes.
+       * optabs-query.c (can_vec_mask_load_store_p): Add MASK_MODE arg.
+        Adjust to maskload, maskstore optab changes.
+       * optabs-query.h (can_vec_mask_load_store_p): Add MASK_MODE arg.
+       * optabs.def (maskload_optab): Transform into convert optab.
+       (maskstore_optab): Likewise.
+       * tree-if-conv.c (ifcvt_can_use_mask_load_store): Adjust to
+       can_vec_mask_load_store_p signature change.
+       (predicate_mem_writes): Use boolean mask.
+       * tree-vect-stmts.c (vectorizable_mask_load_store): Adjust to
+       can_vec_mask_load_store_p signature change.  Allow invariant masks.
+       (vectorizable_operation): Ignore type precision for boolean vectors.
+
 2015-11-10  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        * expr.c (do_store_flag): Use expand_vec_cmp_expr for mask results.
index afbfae815e5318ef10dfdc0daf7746b3b715e2d2..79425ea6a0ff4d5e2a1b225f33fe6caca790b34d 100644 (file)
@@ -1889,7 +1889,9 @@ expand_MASK_LOAD (gcall *stmt)
   create_output_operand (&ops[0], target, TYPE_MODE (type));
   create_fixed_operand (&ops[1], mem);
   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
-  expand_insn (optab_handler (maskload_optab, TYPE_MODE (type)), 3, ops);
+  expand_insn (convert_optab_handler (maskload_optab, TYPE_MODE (type),
+                                     TYPE_MODE (TREE_TYPE (maskt))),
+              3, ops);
 }
 
 static void
@@ -1912,7 +1914,9 @@ expand_MASK_STORE (gcall *stmt)
   create_fixed_operand (&ops[0], mem);
   create_input_operand (&ops[1], reg, TYPE_MODE (type));
   create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt)));
-  expand_insn (optab_handler (maskstore_optab, TYPE_MODE (type)), 3, ops);
+  expand_insn (convert_optab_handler (maskstore_optab, TYPE_MODE (type),
+                                     TYPE_MODE (TREE_TYPE (maskt))),
+              3, ops);
 }
 
 static void
index 254089fec7e6d1d2e1f22ca285676880fff41b6c..c20597c7bcba480ff40783f565671ad8ccc6f59f 100644 (file)
@@ -466,7 +466,9 @@ can_mult_highpart_p (machine_mode mode, bool uns_p)
 /* Return true if target supports vector masked load/store for mode.  */
 
 bool
-can_vec_mask_load_store_p (machine_mode mode, bool is_load)
+can_vec_mask_load_store_p (machine_mode mode,
+                          machine_mode mask_mode,
+                          bool is_load)
 {
   optab op = is_load ? maskload_optab : maskstore_optab;
   machine_mode vmode;
@@ -474,7 +476,7 @@ can_vec_mask_load_store_p (machine_mode mode, bool is_load)
 
   /* If mode is vector mode, check it directly.  */
   if (VECTOR_MODE_P (mode))
-    return optab_handler (op, mode) != CODE_FOR_nothing;
+    return convert_optab_handler (op, mode, mask_mode) != CODE_FOR_nothing;
 
   /* Otherwise, return true if there is some vector mode with
      the mask load/store supported.  */
@@ -485,7 +487,12 @@ can_vec_mask_load_store_p (machine_mode mode, bool is_load)
   if (!VECTOR_MODE_P (vmode))
     return false;
 
-  if (optab_handler (op, vmode) != CODE_FOR_nothing)
+  mask_mode = targetm.vectorize.get_mask_mode (GET_MODE_NUNITS (vmode),
+                                              GET_MODE_SIZE (vmode));
+  if (mask_mode == VOIDmode)
+    return false;
+
+  if (convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
     return true;
 
   vector_sizes = targetm.vectorize.autovectorize_vector_sizes ();
@@ -496,8 +503,10 @@ can_vec_mask_load_store_p (machine_mode mode, bool is_load)
       if (cur <= GET_MODE_SIZE (mode))
        continue;
       vmode = mode_for_vector (mode, cur / GET_MODE_SIZE (mode));
+      mask_mode = targetm.vectorize.get_mask_mode (GET_MODE_NUNITS (vmode),
+                                                  cur);
       if (VECTOR_MODE_P (vmode)
-         && optab_handler (op, vmode) != CODE_FOR_nothing)
+         && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
        return true;
     }
   return false;
index 81ac3627c512f7c933a0269d8fe7bc502cff6386..162d2e9a7c3ee58deec3983be4b757b57ec558e7 100644 (file)
@@ -140,7 +140,7 @@ enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode,
                                                     machine_mode, int,
                                                     machine_mode *);
 int can_mult_highpart_p (machine_mode, bool);
-bool can_vec_mask_load_store_p (machine_mode, bool);
+bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool);
 bool can_compare_and_swap_p (machine_mode, bool);
 bool can_atomic_exchange_p (machine_mode, bool);
 bool lshift_cheap_p (bool);
index c057186c07abd19b7b09d891712bd1878b18cfa5..c9e52a96a2578050786c547d3fc852daa918c024 100644 (file)
@@ -63,6 +63,8 @@ OPTAB_CD(vcond_optab, "vcond$a$b")
 OPTAB_CD(vcondu_optab, "vcondu$a$b")
 OPTAB_CD(vec_cmp_optab, "vec_cmp$a$b")
 OPTAB_CD(vec_cmpu_optab, "vec_cmpu$a$b")
+OPTAB_CD(maskload_optab, "maskload$a$b")
+OPTAB_CD(maskstore_optab, "maskstore$a$b")
 
 OPTAB_NL(add_optab, "add$P$a3", PLUS, "add", '3', gen_int_fp_fixed_libfunc)
 OPTAB_NX(add_optab, "add$F$a3")
@@ -268,8 +270,6 @@ OPTAB_D (udot_prod_optab, "udot_prod$I$a")
 OPTAB_D (usum_widen_optab, "widen_usum$I$a3")
 OPTAB_D (usad_optab, "usad$I$a")
 OPTAB_D (ssad_optab, "ssad$I$a")
-OPTAB_D (maskload_optab, "maskload$a")
-OPTAB_D (maskstore_optab, "maskstore$a")
 OPTAB_D (vec_extract_optab, "vec_extract$a")
 OPTAB_D (vec_init_optab, "vec_init$a")
 OPTAB_D (vec_pack_sfix_trunc_optab, "vec_pack_sfix_trunc_$a")
index cc81cc409f8b0ff97f7fbb342063186f7d8e9193..1ac009f261305218c8a6dc5f588d5f7ad177bf08 100644 (file)
@@ -1,3 +1,7 @@
+2015-11-10  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       * gcc.target/i386/avx2-vec-mask-bit-not.c: New test.
+
 2015-11-10  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        * gcc.dg/vect/slp-cond-5.c: New test.
diff --git a/gcc/testsuite/gcc.target/i386/avx2-vec-mask-bit-not.c b/gcc/testsuite/gcc.target/i386/avx2-vec-mask-bit-not.c
new file mode 100644 (file)
index 0000000..0c946ca
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target avx2 } */
+/* { dg-options "-mavx2 -O3 -fopenmp-simd -fdump-tree-vect-details" } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+
+#define N 1024
+
+int a[N], b[N], c[N], d[N], e[N];
+
+void
+test (void)
+{
+  int i;
+  #pragma omp simd
+  for (i = 0; i < N; i++)
+    if (!(a[i] > b[i] && c[i] < d[i]))
+      e[i] = 0;
+}
index 61ec39040f6ac0c15de58ebc93148f29d33f9337..88b6405a7be355242a306f1d7768cba49ed7da31 100644 (file)
@@ -799,7 +799,7 @@ ifcvt_can_use_mask_load_store (gimple *stmt)
       || VECTOR_MODE_P (mode))
     return false;
 
-  if (can_vec_mask_load_store_p (mode, is_load))
+  if (can_vec_mask_load_store_p (mode, VOIDmode, is_load))
     return true;
 
   return false;
@@ -2056,8 +2056,9 @@ predicate_mem_writes (loop_p loop)
          {
            tree lhs = gimple_assign_lhs (stmt);
            tree rhs = gimple_assign_rhs1 (stmt);
-           tree ref, addr, ptr, masktype, mask_op0, mask_op1, mask;
+           tree ref, addr, ptr, mask;
            gimple *new_stmt;
+           gimple_seq stmts = NULL;
            int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
            ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
            mark_addressable (ref);
@@ -2070,16 +2071,27 @@ predicate_mem_writes (loop_p loop)
              mask = vect_masks[index];
            else
              {
-               masktype = build_nonstandard_integer_type (bitsize, 1);
-               mask_op0 = build_int_cst (masktype, swap ? 0 : -1);
-               mask_op1 = build_int_cst (masktype, swap ? -1 : 0);
-               cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
-                                                  is_gimple_condexpr,
-                                                  NULL_TREE,
-                                                  true, GSI_SAME_STMT);
-               mask = fold_build_cond_expr (masktype, unshare_expr (cond),
-                                            mask_op0, mask_op1);
-               mask = ifc_temp_var (masktype, mask, &gsi);
+               if (COMPARISON_CLASS_P (cond))
+                 mask = gimple_build (&stmts, TREE_CODE (cond),
+                                      boolean_type_node,
+                                      TREE_OPERAND (cond, 0),
+                                      TREE_OPERAND (cond, 1));
+               else
+                 {
+                   gcc_assert (TREE_CODE (cond) == SSA_NAME);
+                   mask = cond;
+                 }
+
+               if (swap)
+                 {
+                   tree true_val
+                     = constant_boolean_node (true, TREE_TYPE (mask));
+                   mask = gimple_build (&stmts, BIT_XOR_EXPR,
+                                        TREE_TYPE (mask), mask, true_val);
+                 }
+               gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
+
+               mask = ifc_temp_var (TREE_TYPE (mask), mask, &gsi);
                /* Save mask and its size for further use.  */
                vect_sizes.safe_push (bitsize);
                vect_masks.safe_push (mask);
index af203ab438ceb7abfa6d6a6ed5a9ff5f9683faec..bdf16faff79e141adca335034ac864ab9ba9bcfb 100644 (file)
@@ -1688,6 +1688,7 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
   bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  tree mask_vectype;
   tree elem_type;
   gimple *new_stmt;
   tree dummy;
@@ -1714,8 +1715,8 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
 
   is_store = gimple_call_internal_fn (stmt) == IFN_MASK_STORE;
   mask = gimple_call_arg (stmt, 2);
-  if (TYPE_PRECISION (TREE_TYPE (mask))
-      != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype))))
+
+  if (TREE_CODE (TREE_TYPE (mask)) != BOOLEAN_TYPE)
     return false;
 
   /* FORNOW. This restriction should be relaxed.  */
@@ -1744,6 +1745,18 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
   if (STMT_VINFO_STRIDED_P (stmt_info))
     return false;
 
+  if (TREE_CODE (mask) != SSA_NAME)
+    return false;
+
+  if (!vect_is_simple_use (mask, loop_vinfo, &def_stmt, &dt, &mask_vectype))
+    return false;
+
+  if (!mask_vectype)
+    mask_vectype = get_mask_type_for_scalar_type (TREE_TYPE (vectype));
+
+  if (!mask_vectype)
+    return false;
+
   if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
     {
       gimple *def_stmt;
@@ -1775,13 +1788,9 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
                                 : DR_STEP (dr), size_zero_node) <= 0)
     return false;
   else if (!VECTOR_MODE_P (TYPE_MODE (vectype))
-          || !can_vec_mask_load_store_p (TYPE_MODE (vectype), !is_store))
-    return false;
-
-  if (TREE_CODE (mask) != SSA_NAME)
-    return false;
-
-  if (!vect_is_simple_use (mask, loop_vinfo, &def_stmt, &dt))
+          || !can_vec_mask_load_store_p (TYPE_MODE (vectype),
+                                         TYPE_MODE (mask_vectype),
+                                         !is_store))
     return false;
 
   if (is_store)
@@ -4688,8 +4697,9 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
 
   /* Most operations cannot handle bit-precision types without extra
      truncations.  */
-  if ((TYPE_PRECISION (TREE_TYPE (scalar_dest))
-       != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
+  if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
+      && (TYPE_PRECISION (TREE_TYPE (scalar_dest))
+         != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
       /* Exception are bitwise binary operations.  */
       && code != BIT_IOR_EXPR
       && code != BIT_XOR_EXPR