Patchwork Fix PR56695 + adjust verify_gimple_comparison

login
register
mail settings
Submitter Marek Polacek
Date March 27, 2013, 3:38 p.m.
Message ID <20130327153841.GE9072@redhat.com>
Download mbox | patch
Permalink /patch/231733/
State New
Headers show

Comments

Marek Polacek - March 27, 2013, 3:38 p.m.
This fixes PR56695 where we ICEd because expand_vec_cond_expr
doesn't expect that the result of a vector comparison is of
TYPE_UNSIGNED type.  So we unconditionally build a signed type now.
We know that the result of vec comparison is e.g. { -1, 0, -1}
and that all elements have to be SI types.

This patch does one more thing - in verify_gimple_comparison we now
explicitly check whether the result of a vec comparison is signed.

Regtested/bootstrapped on x86_64-unknown-linux-gnu, ok for trunk?

2013-03-27  Marek Polacek  <polacek@redhat.com>
	    Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56695
	* tree-vect-stmts.c (vectorizable_condition): Unconditionally
	build signed result of a vector comparison.
	* tree-cfg.c (verify_gimple_comparison): Check that a result
	of a vector comparison has signed type.

	* gcc.dg/vect/pr56695.c: New test.


	Marek
Richard Guenther - March 28, 2013, 9:07 a.m.
On Wed, 27 Mar 2013, Marek Polacek wrote:

> This fixes PR56695 where we ICEd because expand_vec_cond_expr
> doesn't expect that the result of a vector comparison is of
> TYPE_UNSIGNED type.  So we unconditionally build a signed type now.
> We know that the result of vec comparison is e.g. { -1, 0, -1}
> and that all elements have to be SI types.
> 
> This patch does one more thing - in verify_gimple_comparison we now
> explicitly check whether the result of a vec comparison is signed.
> 
> Regtested/bootstrapped on x86_64-unknown-linux-gnu, ok for trunk?

Ok.

Thanks,
Richard.

> 2013-03-27  Marek Polacek  <polacek@redhat.com>
> 	    Richard Biener  <rguenther@suse.de>
> 
> 	PR tree-optimization/56695
> 	* tree-vect-stmts.c (vectorizable_condition): Unconditionally
> 	build signed result of a vector comparison.
> 	* tree-cfg.c (verify_gimple_comparison): Check that a result
> 	of a vector comparison has signed type.
> 
> 	* gcc.dg/vect/pr56695.c: New test.
> 
> --- gcc/tree-vect-stmts.c.mp	2013-03-27 15:19:43.928738801 +0100
> +++ gcc/tree-vect-stmts.c	2013-03-27 15:20:12.485832946 +0100
> @@ -5265,7 +5265,7 @@ vectorizable_condition (gimple stmt, gim
>    vec<tree> vec_oprnds1 = vNULL;
>    vec<tree> vec_oprnds2 = vNULL;
>    vec<tree> vec_oprnds3 = vNULL;
> -  tree vec_cmp_type = vectype;
> +  tree vec_cmp_type;
>  
>    if (slp_node || PURE_SLP_STMT (stmt_info))
>      ncopies = 1;
> @@ -5338,14 +5338,12 @@ vectorizable_condition (gimple stmt, gim
>  	   && TREE_CODE (else_clause) != FIXED_CST)
>      return false;
>  
> -  if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype)))
> -    {
> -      unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
> -      tree cmp_type = build_nonstandard_integer_type (prec, 1);
> -      vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
> -      if (vec_cmp_type == NULL_TREE)
> -	return false;
> -    }
> +  unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
> +  /* The result of a vector comparison should be signed type.  */
> +  tree cmp_type = build_nonstandard_integer_type (prec, 0);
> +  vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
> +  if (vec_cmp_type == NULL_TREE)
> +    return false;
>  
>    if (!vec_stmt)
>      {
> --- gcc/tree-cfg.c.mp	2013-03-27 15:19:59.144788303 +0100
> +++ gcc/tree-cfg.c	2013-03-27 15:20:12.475832906 +0100
> @@ -3191,7 +3191,10 @@ verify_gimple_comparison (tree type, tre
>  
>        if (TYPE_VECTOR_SUBPARTS (type) != TYPE_VECTOR_SUBPARTS (op0_type)
>  	  || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)))
> -	      != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0_type)))))
> +	      != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0_type))))
> +	  /* The result of a vector comparison is of signed
> +	     integral type.  */
> +	  || TYPE_UNSIGNED (TREE_TYPE (type)))
>          {
>            error ("invalid vector comparison resulting type");
>            debug_generic_expr (type);
> --- gcc/testsuite/gcc.dg/vect/pr56695.c.mp	2013-03-27 15:19:06.901618407 +0100
> +++ gcc/testsuite/gcc.dg/vect/pr56695.c	2013-03-27 15:19:00.132596666 +0100
> @@ -0,0 +1,14 @@
> +/* PR tree-optimization/56695 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftree-vectorize" } */
> +
> +int a, b, i;
> +
> +void
> +f (void)
> +{
> +  for (i = 0; i < 8; ++i)
> +    a |= !(i |= b %= 1);
> +}
> +
> +/* { dg-final { cleanup-tree-dump "vect" } } */
> 
> 	Marek
> 
>

Patch

--- gcc/tree-vect-stmts.c.mp	2013-03-27 15:19:43.928738801 +0100
+++ gcc/tree-vect-stmts.c	2013-03-27 15:20:12.485832946 +0100
@@ -5265,7 +5265,7 @@  vectorizable_condition (gimple stmt, gim
   vec<tree> vec_oprnds1 = vNULL;
   vec<tree> vec_oprnds2 = vNULL;
   vec<tree> vec_oprnds3 = vNULL;
-  tree vec_cmp_type = vectype;
+  tree vec_cmp_type;
 
   if (slp_node || PURE_SLP_STMT (stmt_info))
     ncopies = 1;
@@ -5338,14 +5338,12 @@  vectorizable_condition (gimple stmt, gim
 	   && TREE_CODE (else_clause) != FIXED_CST)
     return false;
 
-  if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype)))
-    {
-      unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
-      tree cmp_type = build_nonstandard_integer_type (prec, 1);
-      vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
-      if (vec_cmp_type == NULL_TREE)
-	return false;
-    }
+  unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype)));
+  /* The result of a vector comparison should be signed type.  */
+  tree cmp_type = build_nonstandard_integer_type (prec, 0);
+  vec_cmp_type = get_same_sized_vectype (cmp_type, vectype);
+  if (vec_cmp_type == NULL_TREE)
+    return false;
 
   if (!vec_stmt)
     {
--- gcc/tree-cfg.c.mp	2013-03-27 15:19:59.144788303 +0100
+++ gcc/tree-cfg.c	2013-03-27 15:20:12.475832906 +0100
@@ -3191,7 +3191,10 @@  verify_gimple_comparison (tree type, tre
 
       if (TYPE_VECTOR_SUBPARTS (type) != TYPE_VECTOR_SUBPARTS (op0_type)
 	  || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)))
-	      != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0_type)))))
+	      != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0_type))))
+	  /* The result of a vector comparison is of signed
+	     integral type.  */
+	  || TYPE_UNSIGNED (TREE_TYPE (type)))
         {
           error ("invalid vector comparison resulting type");
           debug_generic_expr (type);
--- gcc/testsuite/gcc.dg/vect/pr56695.c.mp	2013-03-27 15:19:06.901618407 +0100
+++ gcc/testsuite/gcc.dg/vect/pr56695.c	2013-03-27 15:19:00.132596666 +0100
@@ -0,0 +1,14 @@ 
+/* PR tree-optimization/56695 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+int a, b, i;
+
+void
+f (void)
+{
+  for (i = 0; i < 8; ++i)
+    a |= !(i |= b %= 1);
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */