diff mbox

Fix bool vs. unsigned:1 vectorization (PR tree-optimization/79284)

Message ID 20170206153242.GG1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 6, 2017, 3:32 p.m. UTC
On Mon, Feb 06, 2017 at 03:26:01PM +0100, Richard Biener wrote:
> Works for me.  Like VECT_SCALAR_BOOLEAN_TYPE_P () to not confuse it
> with VECTOR_BOOLEAN_TYPE_P?

So like this if it passes bootstrap/regtest?

2017-02-06  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/79284
	* tree-vectorizer.h (VECT_SCALAR_BOOLEAN_TYPE_P): Define.
	* tree-vect-stmts.c (vect_get_vec_def_for_operand,
	vectorizable_mask_load_store, vectorizable_operation,
	vect_is_simple_cond, get_same_sized_vectype): Use it instead
	of comparing TREE_CODE of a type against BOOLEAN_TYPE.
	* tree-vect-patterns.c (check_bool_pattern, search_type_for_mask_1,
	vect_recog_bool_pattern, vect_recog_mask_conversion_pattern): Likewise.
	* tree-vect-slp.c (vect_get_constant_vectors): Likewise.
	* tree-vect-loop.c (vect_determine_vectorization_factor): Likewise.
	Remove redundant gimple_code (stmt) == GIMPLE_ASSIGN test after
	is_gimple_assign (stmt).  Replace another such test with
	is_gimple_assign (stmt).
testsuite/
	* gcc.c-torture/compile/pr79284.c: New test.



	Jakub

Comments

Richard Biener Feb. 6, 2017, 3:36 p.m. UTC | #1
On Mon, 6 Feb 2017, Jakub Jelinek wrote:

> On Mon, Feb 06, 2017 at 03:26:01PM +0100, Richard Biener wrote:
> > Works for me.  Like VECT_SCALAR_BOOLEAN_TYPE_P () to not confuse it
> > with VECTOR_BOOLEAN_TYPE_P?
> 
> So like this if it passes bootstrap/regtest?

Ok.

Richard.

> 2017-02-06  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/79284
> 	* tree-vectorizer.h (VECT_SCALAR_BOOLEAN_TYPE_P): Define.
> 	* tree-vect-stmts.c (vect_get_vec_def_for_operand,
> 	vectorizable_mask_load_store, vectorizable_operation,
> 	vect_is_simple_cond, get_same_sized_vectype): Use it instead
> 	of comparing TREE_CODE of a type against BOOLEAN_TYPE.
> 	* tree-vect-patterns.c (check_bool_pattern, search_type_for_mask_1,
> 	vect_recog_bool_pattern, vect_recog_mask_conversion_pattern): Likewise.
> 	* tree-vect-slp.c (vect_get_constant_vectors): Likewise.
> 	* tree-vect-loop.c (vect_determine_vectorization_factor): Likewise.
> 	Remove redundant gimple_code (stmt) == GIMPLE_ASSIGN test after
> 	is_gimple_assign (stmt).  Replace another such test with
> 	is_gimple_assign (stmt).
> testsuite/
> 	* gcc.c-torture/compile/pr79284.c: New test.
> 
> --- gcc/tree-vectorizer.h.jj	2017-01-01 12:45:36.000000000 +0100
> +++ gcc/tree-vectorizer.h	2017-02-06 16:17:41.850539082 +0100
> @@ -784,6 +784,18 @@ struct dataref_aux {
>  /* The maximum vectorization factor supported by any target (V64QI).  */
>  #define MAX_VECTORIZATION_FACTOR 64
>  
> +/* Nonzero if TYPE represents a (scalar) boolean type or type
> +   in the middle-end compatible with it (unsigned precision 1 integral
> +   types).  Used to determine which types should be vectorized as
> +   VECTOR_BOOLEAN_TYPE_P.  */
> +
> +#define VECT_SCALAR_BOOLEAN_TYPE_P(TYPE) \
> +  (TREE_CODE (TYPE) == BOOLEAN_TYPE		\
> +   || ((TREE_CODE (TYPE) == INTEGER_TYPE	\
> +	|| TREE_CODE (TYPE) == ENUMERAL_TYPE)	\
> +       && TYPE_PRECISION (TYPE) == 1		\
> +       && TYPE_UNSIGNED (TYPE)))
> +
>  extern vec<stmt_vec_info> stmt_vec_info_vec;
>  
>  void init_stmt_vec_info_vec (void);
> --- gcc/tree-vect-stmts.c.jj	2017-01-31 22:36:31.719323924 +0100
> +++ gcc/tree-vect-stmts.c	2017-02-06 16:20:25.435433608 +0100
> @@ -1420,7 +1420,7 @@ vect_get_vec_def_for_operand (tree op, g
>  
>        if (vectype)
>  	vector_type = vectype;
> -      else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
> +      else if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
>  	       && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
>  	vector_type = build_same_sized_truth_vector_type (stmt_vectype);
>        else
> @@ -2029,7 +2029,7 @@ vectorizable_mask_load_store (gimple *st
>  
>    mask = gimple_call_arg (stmt, 2);
>  
> -  if (TREE_CODE (TREE_TYPE (mask)) != BOOLEAN_TYPE)
> +  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (mask)))
>      return false;
>  
>    /* FORNOW. This restriction should be relaxed.  */
> @@ -5275,9 +5275,9 @@ vectorizable_operation (gimple *stmt, gi
>  	 of booleans or vector of integers).  We use output
>  	 vectype because operations on boolean don't change
>  	 type.  */
> -      if (TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE)
> +      if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op0)))
>  	{
> -	  if (TREE_CODE (TREE_TYPE (scalar_dest)) != BOOLEAN_TYPE)
> +	  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (scalar_dest)))
>  	    {
>  	      if (dump_enabled_p ())
>  		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -7666,7 +7666,7 @@ vect_is_simple_cond (tree cond, vec_info
>  
>    /* Mask case.  */
>    if (TREE_CODE (cond) == SSA_NAME
> -      && TREE_CODE (TREE_TYPE (cond)) == BOOLEAN_TYPE)
> +      && VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (cond)))
>      {
>        gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (cond);
>        if (!vect_is_simple_use (cond, vinfo, &lhs_def_stmt,
> @@ -9059,7 +9059,7 @@ get_mask_type_for_scalar_type (tree scal
>  tree
>  get_same_sized_vectype (tree scalar_type, tree vector_type)
>  {
> -  if (TREE_CODE (scalar_type) == BOOLEAN_TYPE)
> +  if (VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type))
>      return build_same_sized_truth_vector_type (vector_type);
>  
>    return get_vectype_for_scalar_type_and_size
> --- gcc/tree-vect-patterns.c.jj	2017-01-31 22:36:29.933346731 +0100
> +++ gcc/tree-vect-patterns.c	2017-02-06 16:20:09.636636952 +0100
> @@ -3158,9 +3158,7 @@ check_bool_pattern (tree var, vec_info *
>        break;
>  
>      CASE_CONVERT:
> -      if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1
> -	   || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
> -	  && TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE)
> +      if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
>  	return false;
>        if (! check_bool_pattern (rhs1, vinfo, stmts))
>  	return false;
> @@ -3474,9 +3472,7 @@ search_type_for_mask_1 (tree var, vec_in
>    if (TREE_CODE (var) != SSA_NAME)
>      return NULL_TREE;
>  
> -  if ((TYPE_PRECISION (TREE_TYPE (var)) != 1
> -       || !TYPE_UNSIGNED (TREE_TYPE (var)))
> -      && TREE_CODE (TREE_TYPE (var)) != BOOLEAN_TYPE)
> +  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
>      return NULL_TREE;
>  
>    if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
> @@ -3518,7 +3514,7 @@ search_type_for_mask_1 (tree var, vec_in
>  	{
>  	  tree comp_vectype, mask_type;
>  
> -	  if (TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE)
> +	  if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
>  	    {
>  	      res = search_type_for_mask_1 (rhs1, vinfo, cache);
>  	      res2 = search_type_for_mask_1 (gimple_assign_rhs2 (def_stmt),
> @@ -3637,9 +3633,7 @@ vect_recog_bool_pattern (vec<gimple *> *
>    var = gimple_assign_rhs1 (last_stmt);
>    lhs = gimple_assign_lhs (last_stmt);
>  
> -  if ((TYPE_PRECISION (TREE_TYPE (var)) != 1
> -       || !TYPE_UNSIGNED (TREE_TYPE (var)))
> -      && TREE_CODE (TREE_TYPE (var)) != BOOLEAN_TYPE)
> +  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
>      return NULL;
>  
>    hash_set<gimple *> bool_stmts;
> @@ -4023,7 +4017,7 @@ vect_recog_mask_conversion_pattern (vec<
>  
>    /* Now check for binary boolean operations requiring conversion for
>       one of operands.  */
> -  if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE)
> +  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
>      return NULL;
>  
>    if (rhs_code != BIT_IOR_EXPR
> --- gcc/tree-vect-slp.c.jj	2017-01-31 22:36:31.636324984 +0100
> +++ gcc/tree-vect-slp.c	2017-02-06 16:20:14.145578918 +0100
> @@ -2949,7 +2949,7 @@ vect_get_constant_vectors (tree op, slp_
>    gimple_seq ctor_seq = NULL;
>  
>    /* Check if vector type is a boolean vector.  */
> -  if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
> +  if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
>        && vect_mask_constant_operand_p (stmt, op_num))
>      vector_type
>        = build_same_sized_truth_vector_type (STMT_VINFO_VECTYPE (stmt_vinfo));
> --- gcc/tree-vect-loop.c.jj	2017-02-03 23:35:51.418955816 +0100
> +++ gcc/tree-vect-loop.c	2017-02-06 16:19:53.856840051 +0100
> @@ -433,7 +433,7 @@ vect_determine_vectorization_factor (loo
>  	      /* Bool ops don't participate in vectorization factor
>  		 computation.  For comparison use compared types to
>  		 compute a factor.  */
> -	      if (TREE_CODE (scalar_type) == BOOLEAN_TYPE
> +	      if (VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type)
>  		  && is_gimple_assign (stmt)
>  		  && gimple_assign_rhs_code (stmt) != COND_EXPR)
>  		{
> @@ -442,11 +442,10 @@ vect_determine_vectorization_factor (loo
>  		    mask_producers.safe_push (stmt_info);
>  		  bool_result = true;
>  
> -		  if (gimple_code (stmt) == GIMPLE_ASSIGN
> -		      && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
> -			 == tcc_comparison
> -		      && TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (stmt)))
> -			 != BOOLEAN_TYPE)
> +		  if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
> +		      == tcc_comparison
> +		      && !VECT_SCALAR_BOOLEAN_TYPE_P
> +			    (TREE_TYPE (gimple_assign_rhs1 (stmt))))
>  		    scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
>  		  else
>  		    {
> @@ -585,9 +584,10 @@ vect_determine_vectorization_factor (loo
>  
>        stmt = STMT_VINFO_STMT (mask_producers[i]);
>  
> -      if (gimple_code (stmt) == GIMPLE_ASSIGN
> +      if (is_gimple_assign (stmt)
>  	  && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison
> -	  && TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (stmt))) != BOOLEAN_TYPE)
> +	  && !VECT_SCALAR_BOOLEAN_TYPE_P
> +				      (TREE_TYPE (gimple_assign_rhs1 (stmt))))
>  	{
>  	  scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
>  	  mask_type = get_mask_type_for_scalar_type (scalar_type);
> --- gcc/testsuite/gcc.c-torture/compile/pr79284.c.jj	2017-02-06 16:14:35.127942358 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr79284.c	2017-02-06 16:14:35.127942358 +0100
> @@ -0,0 +1,13 @@
> +/* PR tree-optimization/79284 */
> +
> +struct S { unsigned a : 1; } b;
> +int c[64];
> +
> +int
> +foo (int x)
> +{ 
> +  char e, f;
> +  for (e = 63; e; e--)
> +    f = (c[e] && ~0) != b.a;
> +  return f;
> +}
> 
> 
> 	Jakub
> 
>
Jeff Law Feb. 6, 2017, 3:39 p.m. UTC | #2
On 02/06/2017 08:36 AM, Richard Biener wrote:
> On Mon, 6 Feb 2017, Jakub Jelinek wrote:
>
>> On Mon, Feb 06, 2017 at 03:26:01PM +0100, Richard Biener wrote:
>>> Works for me.  Like VECT_SCALAR_BOOLEAN_TYPE_P () to not confuse it
>>> with VECTOR_BOOLEAN_TYPE_P?
>>
>> So like this if it passes bootstrap/regtest?
>
> Ok.
No objections from me either.

jeff
diff mbox

Patch

--- gcc/tree-vectorizer.h.jj	2017-01-01 12:45:36.000000000 +0100
+++ gcc/tree-vectorizer.h	2017-02-06 16:17:41.850539082 +0100
@@ -784,6 +784,18 @@  struct dataref_aux {
 /* The maximum vectorization factor supported by any target (V64QI).  */
 #define MAX_VECTORIZATION_FACTOR 64
 
+/* Nonzero if TYPE represents a (scalar) boolean type or type
+   in the middle-end compatible with it (unsigned precision 1 integral
+   types).  Used to determine which types should be vectorized as
+   VECTOR_BOOLEAN_TYPE_P.  */
+
+#define VECT_SCALAR_BOOLEAN_TYPE_P(TYPE) \
+  (TREE_CODE (TYPE) == BOOLEAN_TYPE		\
+   || ((TREE_CODE (TYPE) == INTEGER_TYPE	\
+	|| TREE_CODE (TYPE) == ENUMERAL_TYPE)	\
+       && TYPE_PRECISION (TYPE) == 1		\
+       && TYPE_UNSIGNED (TYPE)))
+
 extern vec<stmt_vec_info> stmt_vec_info_vec;
 
 void init_stmt_vec_info_vec (void);
--- gcc/tree-vect-stmts.c.jj	2017-01-31 22:36:31.719323924 +0100
+++ gcc/tree-vect-stmts.c	2017-02-06 16:20:25.435433608 +0100
@@ -1420,7 +1420,7 @@  vect_get_vec_def_for_operand (tree op, g
 
       if (vectype)
 	vector_type = vectype;
-      else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
+      else if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
 	       && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
 	vector_type = build_same_sized_truth_vector_type (stmt_vectype);
       else
@@ -2029,7 +2029,7 @@  vectorizable_mask_load_store (gimple *st
 
   mask = gimple_call_arg (stmt, 2);
 
-  if (TREE_CODE (TREE_TYPE (mask)) != BOOLEAN_TYPE)
+  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (mask)))
     return false;
 
   /* FORNOW. This restriction should be relaxed.  */
@@ -5275,9 +5275,9 @@  vectorizable_operation (gimple *stmt, gi
 	 of booleans or vector of integers).  We use output
 	 vectype because operations on boolean don't change
 	 type.  */
-      if (TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE)
+      if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op0)))
 	{
-	  if (TREE_CODE (TREE_TYPE (scalar_dest)) != BOOLEAN_TYPE)
+	  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (scalar_dest)))
 	    {
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -7666,7 +7666,7 @@  vect_is_simple_cond (tree cond, vec_info
 
   /* Mask case.  */
   if (TREE_CODE (cond) == SSA_NAME
-      && TREE_CODE (TREE_TYPE (cond)) == BOOLEAN_TYPE)
+      && VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (cond)))
     {
       gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (cond);
       if (!vect_is_simple_use (cond, vinfo, &lhs_def_stmt,
@@ -9059,7 +9059,7 @@  get_mask_type_for_scalar_type (tree scal
 tree
 get_same_sized_vectype (tree scalar_type, tree vector_type)
 {
-  if (TREE_CODE (scalar_type) == BOOLEAN_TYPE)
+  if (VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type))
     return build_same_sized_truth_vector_type (vector_type);
 
   return get_vectype_for_scalar_type_and_size
--- gcc/tree-vect-patterns.c.jj	2017-01-31 22:36:29.933346731 +0100
+++ gcc/tree-vect-patterns.c	2017-02-06 16:20:09.636636952 +0100
@@ -3158,9 +3158,7 @@  check_bool_pattern (tree var, vec_info *
       break;
 
     CASE_CONVERT:
-      if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1
-	   || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
-	  && TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE)
+      if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
 	return false;
       if (! check_bool_pattern (rhs1, vinfo, stmts))
 	return false;
@@ -3474,9 +3472,7 @@  search_type_for_mask_1 (tree var, vec_in
   if (TREE_CODE (var) != SSA_NAME)
     return NULL_TREE;
 
-  if ((TYPE_PRECISION (TREE_TYPE (var)) != 1
-       || !TYPE_UNSIGNED (TREE_TYPE (var)))
-      && TREE_CODE (TREE_TYPE (var)) != BOOLEAN_TYPE)
+  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
     return NULL_TREE;
 
   if (!vect_is_simple_use (var, vinfo, &def_stmt, &dt))
@@ -3518,7 +3514,7 @@  search_type_for_mask_1 (tree var, vec_in
 	{
 	  tree comp_vectype, mask_type;
 
-	  if (TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE)
+	  if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)))
 	    {
 	      res = search_type_for_mask_1 (rhs1, vinfo, cache);
 	      res2 = search_type_for_mask_1 (gimple_assign_rhs2 (def_stmt),
@@ -3637,9 +3633,7 @@  vect_recog_bool_pattern (vec<gimple *> *
   var = gimple_assign_rhs1 (last_stmt);
   lhs = gimple_assign_lhs (last_stmt);
 
-  if ((TYPE_PRECISION (TREE_TYPE (var)) != 1
-       || !TYPE_UNSIGNED (TREE_TYPE (var)))
-      && TREE_CODE (TREE_TYPE (var)) != BOOLEAN_TYPE)
+  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
     return NULL;
 
   hash_set<gimple *> bool_stmts;
@@ -4023,7 +4017,7 @@  vect_recog_mask_conversion_pattern (vec<
 
   /* Now check for binary boolean operations requiring conversion for
      one of operands.  */
-  if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE)
+  if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
     return NULL;
 
   if (rhs_code != BIT_IOR_EXPR
--- gcc/tree-vect-slp.c.jj	2017-01-31 22:36:31.636324984 +0100
+++ gcc/tree-vect-slp.c	2017-02-06 16:20:14.145578918 +0100
@@ -2949,7 +2949,7 @@  vect_get_constant_vectors (tree op, slp_
   gimple_seq ctor_seq = NULL;
 
   /* Check if vector type is a boolean vector.  */
-  if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
+  if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
       && vect_mask_constant_operand_p (stmt, op_num))
     vector_type
       = build_same_sized_truth_vector_type (STMT_VINFO_VECTYPE (stmt_vinfo));
--- gcc/tree-vect-loop.c.jj	2017-02-03 23:35:51.418955816 +0100
+++ gcc/tree-vect-loop.c	2017-02-06 16:19:53.856840051 +0100
@@ -433,7 +433,7 @@  vect_determine_vectorization_factor (loo
 	      /* Bool ops don't participate in vectorization factor
 		 computation.  For comparison use compared types to
 		 compute a factor.  */
-	      if (TREE_CODE (scalar_type) == BOOLEAN_TYPE
+	      if (VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type)
 		  && is_gimple_assign (stmt)
 		  && gimple_assign_rhs_code (stmt) != COND_EXPR)
 		{
@@ -442,11 +442,10 @@  vect_determine_vectorization_factor (loo
 		    mask_producers.safe_push (stmt_info);
 		  bool_result = true;
 
-		  if (gimple_code (stmt) == GIMPLE_ASSIGN
-		      && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
-			 == tcc_comparison
-		      && TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (stmt)))
-			 != BOOLEAN_TYPE)
+		  if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
+		      == tcc_comparison
+		      && !VECT_SCALAR_BOOLEAN_TYPE_P
+			    (TREE_TYPE (gimple_assign_rhs1 (stmt))))
 		    scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
 		  else
 		    {
@@ -585,9 +584,10 @@  vect_determine_vectorization_factor (loo
 
       stmt = STMT_VINFO_STMT (mask_producers[i]);
 
-      if (gimple_code (stmt) == GIMPLE_ASSIGN
+      if (is_gimple_assign (stmt)
 	  && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison
-	  && TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (stmt))) != BOOLEAN_TYPE)
+	  && !VECT_SCALAR_BOOLEAN_TYPE_P
+				      (TREE_TYPE (gimple_assign_rhs1 (stmt))))
 	{
 	  scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
 	  mask_type = get_mask_type_for_scalar_type (scalar_type);
--- gcc/testsuite/gcc.c-torture/compile/pr79284.c.jj	2017-02-06 16:14:35.127942358 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr79284.c	2017-02-06 16:14:35.127942358 +0100
@@ -0,0 +1,13 @@ 
+/* PR tree-optimization/79284 */
+
+struct S { unsigned a : 1; } b;
+int c[64];
+
+int
+foo (int x)
+{ 
+  char e, f;
+  for (e = 63; e; e--)
+    f = (c[e] && ~0) != b.a;
+  return f;
+}