tree-optimization/97706 - handle PHIs in pattern recog mask precison
authorRichard Biener <rguenther@suse.de>
Thu, 5 Nov 2020 11:34:42 +0000 (12:34 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 6 Nov 2020 14:00:37 +0000 (15:00 +0100)
This adds handling of PHIs to mask precision compute which is
eventually needed to detect a bool pattern when the def chain
contains such a PHI node.

2020-11-06  Richard Biener  <rguenther@suse.de>

PR tree-optimization/97706
* tree-vect-patterns.c (possible_vector_mask_operation_p):
PHIs are possible mask operations.
(vect_determine_mask_precision): Handle PHIs.
(vect_determine_precisions): Walk PHIs in BB analysis.

* gcc.dg/vect/bb-slp-pr97706.c: New testcase.

gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c [new file with mode: 0644]
gcc/tree-vect-patterns.c

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c
new file mode 100644 (file)
index 0000000..228ae70
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+
+_Bool arr[16];
+void bar();
+void foo(int n, char *p)
+{
+  _Bool b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
+  do
+    {
+      b0 = p[0] != 0;
+      b1 = p[1] != 0;
+      b2 = p[2] != 0;
+      b3 = p[3] != 0;
+      b4 = p[4] != 0;
+      b5 = p[5] != 0;
+      b6 = p[6] != 0;
+      b7 = p[7] != 0;
+      b8 = p[8] != 0;
+      b9 = p[9] != 0;
+      b10 = p[10] != 0;
+      b11 = p[11] != 0;
+      b12 = p[12] != 0;
+      b13 = p[13] != 0;
+      b14 = p[14] != 0;
+      b15 = p[15] != 0;
+      arr[0] = b0;
+      arr[1] = b1;
+      arr[2] = b2;
+      arr[3] = b3;
+      arr[4] = b4;
+      arr[5] = b5;
+      arr[6] = b6;
+      arr[7] = b7;
+      arr[8] = b8;
+      arr[9] = b9;
+      arr[10] = b10;
+      arr[11] = b11;
+      arr[12] = b12;
+      arr[13] = b13;
+      arr[14] = b14;
+      arr[15] = b15;
+      bar ();
+    }
+  while (--n);
+  arr[0] = b0;
+  arr[1] = b1;
+  arr[2] = b2;
+  arr[3] = b3;
+  arr[4] = b4;
+  arr[5] = b5;
+  arr[6] = b6;
+  arr[7] = b7;
+  arr[8] = b8;
+  arr[9] = b9;
+  arr[10] = b10;
+  arr[11] = b11;
+  arr[12] = b12;
+  arr[13] = b13;
+  arr[14] = b14;
+  arr[15] = b15;
+}
index 47d9fce594f2b6315a3a560fe7d17bc40906d670..eefa7cf6799a7d846303aa6274d28bcc0a841158 100644 (file)
@@ -5007,6 +5007,8 @@ possible_vector_mask_operation_p (stmt_vec_info stmt_info)
          return TREE_CODE_CLASS (rhs_code) == tcc_comparison;
        }
     }
+  else if (is_a <gphi *> (stmt_info->stmt))
+    return true;
   return false;
 }
 
@@ -5049,41 +5051,63 @@ vect_determine_mask_precision (vec_info *vinfo, stmt_vec_info stmt_info)
      The number of operations are equal, but M16 would have given
      a shorter dependency chain and allowed more ILP.  */
   unsigned int precision = ~0U;
-  gassign *assign = as_a <gassign *> (stmt_info->stmt);
-  unsigned int nops = gimple_num_ops (assign);
-  for (unsigned int i = 1; i < nops; ++i)
+  if (gassign *assign = dyn_cast <gassign *> (stmt_info->stmt))
     {
-      tree rhs = gimple_op (assign, i);
-      if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs)))
-       continue;
+      unsigned int nops = gimple_num_ops (assign);
+      for (unsigned int i = 1; i < nops; ++i)
+       {
+         tree rhs = gimple_op (assign, i);
+         if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs)))
+           continue;
 
-      stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
-      if (!def_stmt_info)
-       /* Don't let external or constant operands influence the choice.
-          We can convert them to whichever vector type we pick.  */
-       continue;
+         stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
+         if (!def_stmt_info)
+           /* Don't let external or constant operands influence the choice.
+              We can convert them to whichever vector type we pick.  */
+           continue;
+
+         if (def_stmt_info->mask_precision)
+           {
+             if (precision > def_stmt_info->mask_precision)
+               precision = def_stmt_info->mask_precision;
+           }
+       }
 
-      if (def_stmt_info->mask_precision)
+      /* If the statement compares two values that shouldn't use vector masks,
+        try comparing the values as normal scalars instead.  */
+      tree_code rhs_code = gimple_assign_rhs_code (assign);
+      if (precision == ~0U
+         && TREE_CODE_CLASS (rhs_code) == tcc_comparison)
        {
-         if (precision > def_stmt_info->mask_precision)
-           precision = def_stmt_info->mask_precision;
+         tree rhs1_type = TREE_TYPE (gimple_assign_rhs1 (assign));
+         scalar_mode mode;
+         tree vectype, mask_type;
+         if (is_a <scalar_mode> (TYPE_MODE (rhs1_type), &mode)
+             && (vectype = get_vectype_for_scalar_type (vinfo, rhs1_type))
+             && (mask_type = get_mask_type_for_scalar_type (vinfo, rhs1_type))
+             && expand_vec_cmp_expr_p (vectype, mask_type, rhs_code))
+           precision = GET_MODE_BITSIZE (mode);
        }
     }
-
-  /* If the statement compares two values that shouldn't use vector masks,
-     try comparing the values as normal scalars instead.  */
-  tree_code rhs_code = gimple_assign_rhs_code (assign);
-  if (precision == ~0U
-      && TREE_CODE_CLASS (rhs_code) == tcc_comparison)
+  else
     {
-      tree rhs1_type = TREE_TYPE (gimple_assign_rhs1 (assign));
-      scalar_mode mode;
-      tree vectype, mask_type;
-      if (is_a <scalar_mode> (TYPE_MODE (rhs1_type), &mode)
-         && (vectype = get_vectype_for_scalar_type (vinfo, rhs1_type))
-         && (mask_type = get_mask_type_for_scalar_type (vinfo, rhs1_type))
-         && expand_vec_cmp_expr_p (vectype, mask_type, rhs_code))
-       precision = GET_MODE_BITSIZE (mode);
+      gphi *phi = as_a <gphi *> (stmt_info->stmt);
+      for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
+       {
+         tree rhs = gimple_phi_arg_def (phi, i);
+
+         stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
+         if (!def_stmt_info)
+           /* Don't let external or constant operands influence the choice.
+              We can convert them to whichever vector type we pick.  */
+           continue;
+
+         if (def_stmt_info->mask_precision)
+           {
+             if (precision > def_stmt_info->mask_precision)
+               precision = def_stmt_info->mask_precision;
+           }
+       }
     }
 
   if (dump_enabled_p ())
@@ -5164,15 +5188,30 @@ vect_determine_precisions (vec_info *vinfo)
              if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
                vect_determine_mask_precision (vinfo, stmt_info);
            }
+         for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
+             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+               vect_determine_mask_precision (vinfo, stmt_info);
+           }
        }
       for (int i = bb_vinfo->bbs.length () - 1; i != -1; --i)
-       for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
-            !gsi_end_p (gsi); gsi_prev (&gsi))
-         {
-           stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
-           if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
-             vect_determine_stmt_precisions (vinfo, stmt_info);
-         }
+       {
+         for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
+              !gsi_end_p (gsi); gsi_prev (&gsi))
+           {
+             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
+             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+               vect_determine_stmt_precisions (vinfo, stmt_info);
+           }
+         for (auto gsi = gsi_start_phis (bb_vinfo->bbs[i]);
+              !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
+             if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
+               vect_determine_stmt_precisions (vinfo, stmt_info);
+           }
+       }
     }
 }