public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ilya Enkovich <enkovich.gnu@gmail.com>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH] Fix ICE for boolean comparison
Date: Thu, 12 Nov 2015 15:46:00 -0000	[thread overview]
Message-ID: <20151112154400.GE51435@msticlxl57.ims.intel.com> (raw)

Hi,

Currently compiler may ICE when loaded boolean is compared with vector invariant or another boolean value.  This is because we don't detect mix of bool and non-bool vectypes and incorrectly determine vectype for boolean loop invariant for comparison.  This was fixed for COND_EXP before but also needs to be fixed for comparison.  This patch was bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?

Thanks,
Ilya
--
gcc/

2015-11-12  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* tree-vect-loop.c (vect_determine_vectorization_factor): Check
	mix of boolean and integer vectors in a single statement.
	* tree-vect-slp.c (vect_mask_constant_operand_p): New.
	(vect_get_constant_vectors): Use vect_mask_constant_operand_p to
	determine constant type.
	* tree-vect-stmts.c (vectorizable_comparison): Provide vectype
	for loop invariants.

gcc/testsuite/

2015-11-12  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* g++.dg/vect/simd-bool-comparison-1.cc: New test.
	* g++.dg/vect/simd-bool-comparison-2.cc: New test.


diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc
new file mode 100644
index 0000000..a08362f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-additional-options "-mavx512bw -mavx512dq" { target { i?86-*-* x86_64-*-* } } }
+
+#define N 1024
+
+double a[N];
+bool b[N];
+bool c;
+
+void test ()
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    if (b[i] != c)
+      a[i] = 0.0;
+    else
+      a[i] = 1.0;
+}
+
+// { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc
new file mode 100644
index 0000000..4accf56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-additional-options "-mavx512bw -mavx512dq" { target { i?86-*-* x86_64-*-* } } }
+
+#define N 1024
+
+double a[N];
+bool b[N];
+char c[N];
+
+void test ()
+{
+  int i;
+
+  #pragma omp simd
+  for (i = 0; i < N; i++)
+    if ((c[i] > 0) && b[i])
+      a[i] = 0.0;
+    else
+      a[i] = 1.0;
+}
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 55e5309..6b78b55 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -649,7 +649,32 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
 		    }
 		  return false;
 		}
+	      else if (VECTOR_BOOLEAN_TYPE_P (mask_type)
+		       != VECTOR_BOOLEAN_TYPE_P (vectype))
+		{
+		  if (dump_enabled_p ())
+		    {
+		      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+				       "not vectorized: mixed mask and "
+				       "nonmask vector types in statement, ");
+		      dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+					 mask_type);
+		      dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
+		      dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+					 vectype);
+		      dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
+		    }
+		  return false;
+		}
 	    }
+
+	  /* We may compare boolean value loaded as vector of integers.
+	     Fix mask_type in such case.  */
+	  if (mask_type
+	      && !VECTOR_BOOLEAN_TYPE_P (mask_type)
+	      && gimple_code (stmt) == GIMPLE_ASSIGN
+	      && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+	    mask_type = build_same_sized_truth_vector_type (mask_type);
 	}
 
       /* No mask_type should mean loop invariant predicate.
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 9d97140..f3acb04 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2589,6 +2589,57 @@ vect_slp_bb (basic_block bb)
 }
 
 
+/* Return 1 if vector type of boolean constant which is OPNUM
+   operand in statement STMT is a boolean vector.  */
+
+static bool
+vect_mask_constant_operand_p (gimple *stmt, int opnum)
+{
+  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  enum tree_code code = gimple_expr_code (stmt);
+  tree op, vectype;
+  gimple *def_stmt;
+  enum vect_def_type dt;
+
+  /* For comparison and COND_EXPR type is chosen depending
+     on the other comparison operand.  */
+  if (TREE_CODE_CLASS (code) == tcc_comparison)
+    {
+      if (opnum)
+	op = gimple_assign_rhs1 (stmt);
+      else
+	op = gimple_assign_rhs2 (stmt);
+
+      if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &def_stmt,
+			       &dt, &vectype))
+	gcc_unreachable ();
+
+      return !vectype || VECTOR_BOOLEAN_TYPE_P (vectype);
+    }
+
+  if (code == COND_EXPR)
+    {
+      tree cond = gimple_assign_rhs1 (stmt);
+
+      if (TREE_CODE (cond) == SSA_NAME)
+	return false;
+
+      if (opnum)
+	op = TREE_OPERAND (cond, 1);
+      else
+	op = TREE_OPERAND (cond, 0);
+
+      if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &def_stmt,
+			       &dt, &vectype))
+	gcc_unreachable ();
+
+      return !vectype || VECTOR_BOOLEAN_TYPE_P (vectype);
+    }
+
+  return VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo));
+}
+
+
 /* For constant and loop invariant defs of SLP_NODE this function returns
    (vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts.
    OP_NUM determines if we gather defs for operand 0 or operand 1 of the RHS of
@@ -2625,8 +2676,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
 
   /* Check if vector type is a boolean vector.  */
   if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
-      && (VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo))
-	  || (code == COND_EXPR && op_num < 2)))
+      && vect_mask_constant_operand_p (stmt, op_num))
     vector_type
       = build_same_sized_truth_vector_type (STMT_VINFO_VECTYPE (stmt_vinfo));
   else
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index cfe30e0..c990dfa 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -7642,8 +7642,8 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
 	    }
 	  else
 	    {
-	      vec_rhs1 = vect_get_vec_def_for_operand (rhs1, stmt, NULL);
-	      vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, NULL);
+	      vec_rhs1 = vect_get_vec_def_for_operand (rhs1, stmt, vectype);
+	      vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, vectype);
 	    }
 	}
       else

             reply	other threads:[~2015-11-12 15:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-12 15:46 Ilya Enkovich [this message]
2015-11-13 10:38 ` Richard Biener
2015-11-13 10:52   ` Ilya Enkovich
2015-11-13 11:28     ` Richard Biener
2015-11-13 11:32       ` Ilya Enkovich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151112154400.GE51435@msticlxl57.ims.intel.com \
    --to=enkovich.gnu@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).