Patchwork vector pointer handling fix (PR tree-optimization/45633)

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 15, 2010, 1:08 p.m.
Message ID <20100915130839.GK1269@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/64812/
State New
Headers show

Comments

Jakub Jelinek - Sept. 15, 2010, 1:08 p.m.
Hi!

This patch handles 2 issues:
1) we don't use POINTER_PLUS_EXPR for vector pointer arithmetic,
   but PLUS_EXPR where one size is a vector pointer and another
   size vector sizetype.  forwprop can change that
   PLUS_EXPR into MINUS_EXPR with the same operand types,
   but while we have an exception for PLUS_EXPR in the type verifier,
   we don't have it for MINUS_EXPR.  The first 2 hunks just
   make the verifier accept even that.
2) POINTER_PLUS_EXPR unnecessarily forces for subtraction of a variable
   from a pointer a NEG insn separate from PLUS insn and usually combiner
   can fix that up.  The expr.c hunks use TER to optimize this into
   subtraction right away.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-09-14  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/45633
	* tree-cfg.c (verify_gimple_assign_binary): Allow
	MINUS_EXPR with lhs and rhs1 pointer vector and
	rhs2 sizetype vector.
	* expr.c (expand_expr_real_2) <case PLUS_EXPR>: For pointer
	or vector pointer use TER to optimize pointer subtraction.

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


	Jakub
Richard Guenther - Sept. 15, 2010, 2:01 p.m.
On Wed, 15 Sep 2010, Jakub Jelinek wrote:

> Hi!
> 
> This patch handles 2 issues:
> 1) we don't use POINTER_PLUS_EXPR for vector pointer arithmetic,
>    but PLUS_EXPR where one size is a vector pointer and another
>    size vector sizetype.  forwprop can change that
>    PLUS_EXPR into MINUS_EXPR with the same operand types,
>    but while we have an exception for PLUS_EXPR in the type verifier,
>    we don't have it for MINUS_EXPR.  The first 2 hunks just
>    make the verifier accept even that.
> 2) POINTER_PLUS_EXPR unnecessarily forces for subtraction of a variable
>    from a pointer a NEG insn separate from PLUS insn and usually combiner
>    can fix that up.  The expr.c hunks use TER to optimize this into
>    subtraction right away.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2010-09-14  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/45633
> 	* tree-cfg.c (verify_gimple_assign_binary): Allow
> 	MINUS_EXPR with lhs and rhs1 pointer vector and
> 	rhs2 sizetype vector.
> 	* expr.c (expand_expr_real_2) <case PLUS_EXPR>: For pointer
> 	or vector pointer use TER to optimize pointer subtraction.
> 
> 	* gcc.dg/vect/pr45633.c: New test.
> 
> --- gcc/tree-cfg.c.jj	2010-09-09 10:17:42.000000000 +0200
> +++ gcc/tree-cfg.c	2010-09-14 17:49:49.000000000 +0200
> @@ -3448,8 +3448,9 @@ verify_gimple_assign_binary (gimple stmt
>        }
>  
>      case PLUS_EXPR:
> +    case MINUS_EXPR:
>        {
> -	/* We use regular PLUS_EXPR for vectors.
> +	/* We use regular PLUS_EXPR and MINUS_EXPR for vectors.
>  	   ???  This just makes the checker happy and may not be what is
>  	   intended.  */
>  	if (TREE_CODE (lhs_type) == VECTOR_TYPE
> @@ -3474,10 +3475,6 @@ verify_gimple_assign_binary (gimple stmt
>  	      }
>  	    goto do_pointer_plus_expr_check;
>  	  }
> -      }
> -    /* Fallthru.  */
> -    case MINUS_EXPR:
> -      {
>  	if (POINTER_TYPE_P (lhs_type)
>  	    || POINTER_TYPE_P (rhs1_type)
>  	    || POINTER_TYPE_P (rhs2_type))
> --- gcc/expr.c.jj	2010-09-09 10:17:41.000000000 +0200
> +++ gcc/expr.c	2010-09-14 20:39:38.000000000 +0200
> @@ -7572,6 +7572,24 @@ expand_expr_real_2 (sepops ops, rtx targ
>  	    }
>  	}
>  
> +      /* Use TER to expand pointer addition of a negated value
> +	 as pointer subtraction.  */
> +      if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
> +	   || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
> +	       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
> +	  && TREE_CODE (treeop1) == SSA_NAME
> +	  && TYPE_MODE (TREE_TYPE (treeop0))
> +	     == TYPE_MODE (TREE_TYPE (treeop1)))
> +	{
> +	  gimple def = get_def_for_expr (treeop1, NEGATE_EXPR);
> +	  if (def)
> +	    {
> +	      treeop1 = gimple_assign_rhs1 (def);
> +	      code = MINUS_EXPR;
> +	      goto do_minus;
> +	    }
> +	}
> +
>        /* No sense saving up arithmetic to be done
>  	 if it's all in the wrong mode to form part of an address.
>  	 And force_operand won't know whether to sign-extend or
> @@ -7593,6 +7611,7 @@ expand_expr_real_2 (sepops ops, rtx targ
>        return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
>  
>      case MINUS_EXPR:
> +    do_minus:
>        /* For initializers, we are allowed to return a MINUS of two
>  	 symbolic constants.  Here we handle all cases when both operands
>  	 are constant.  */
> --- gcc/testsuite/gcc.dg/vect/pr45633.c.jj	2010-06-11 06:09:31.366700544 +0200
> +++ gcc/testsuite/gcc.dg/vect/pr45633.c	2010-09-15 12:24:14.813377673 +0200
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/45633 */
> +/* { dg-do compile } */
> +
> +int s[32];
> +unsigned char *t[32];
> +
> +void
> +foo (void)
> +{
> +  int i;
> +  for (i = 0; i < 32; i++)
> +    t[i] -= s[i];
> +}
> +
> +/* { dg-final { cleanup-tree-dump "vect" } } */
> 
> 	Jakub
> 
>

Patch

--- gcc/tree-cfg.c.jj	2010-09-09 10:17:42.000000000 +0200
+++ gcc/tree-cfg.c	2010-09-14 17:49:49.000000000 +0200
@@ -3448,8 +3448,9 @@  verify_gimple_assign_binary (gimple stmt
       }
 
     case PLUS_EXPR:
+    case MINUS_EXPR:
       {
-	/* We use regular PLUS_EXPR for vectors.
+	/* We use regular PLUS_EXPR and MINUS_EXPR for vectors.
 	   ???  This just makes the checker happy and may not be what is
 	   intended.  */
 	if (TREE_CODE (lhs_type) == VECTOR_TYPE
@@ -3474,10 +3475,6 @@  verify_gimple_assign_binary (gimple stmt
 	      }
 	    goto do_pointer_plus_expr_check;
 	  }
-      }
-    /* Fallthru.  */
-    case MINUS_EXPR:
-      {
 	if (POINTER_TYPE_P (lhs_type)
 	    || POINTER_TYPE_P (rhs1_type)
 	    || POINTER_TYPE_P (rhs2_type))
--- gcc/expr.c.jj	2010-09-09 10:17:41.000000000 +0200
+++ gcc/expr.c	2010-09-14 20:39:38.000000000 +0200
@@ -7572,6 +7572,24 @@  expand_expr_real_2 (sepops ops, rtx targ
 	    }
 	}
 
+      /* Use TER to expand pointer addition of a negated value
+	 as pointer subtraction.  */
+      if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
+	   || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
+	       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
+	  && TREE_CODE (treeop1) == SSA_NAME
+	  && TYPE_MODE (TREE_TYPE (treeop0))
+	     == TYPE_MODE (TREE_TYPE (treeop1)))
+	{
+	  gimple def = get_def_for_expr (treeop1, NEGATE_EXPR);
+	  if (def)
+	    {
+	      treeop1 = gimple_assign_rhs1 (def);
+	      code = MINUS_EXPR;
+	      goto do_minus;
+	    }
+	}
+
       /* No sense saving up arithmetic to be done
 	 if it's all in the wrong mode to form part of an address.
 	 And force_operand won't know whether to sign-extend or
@@ -7593,6 +7611,7 @@  expand_expr_real_2 (sepops ops, rtx targ
       return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
 
     case MINUS_EXPR:
+    do_minus:
       /* For initializers, we are allowed to return a MINUS of two
 	 symbolic constants.  Here we handle all cases when both operands
 	 are constant.  */
--- gcc/testsuite/gcc.dg/vect/pr45633.c.jj	2010-06-11 06:09:31.366700544 +0200
+++ gcc/testsuite/gcc.dg/vect/pr45633.c	2010-09-15 12:24:14.813377673 +0200
@@ -0,0 +1,15 @@ 
+/* PR tree-optimization/45633 */
+/* { dg-do compile } */
+
+int s[32];
+unsigned char *t[32];
+
+void
+foo (void)
+{
+  int i;
+  for (i = 0; i < 32; i++)
+    t[i] -= s[i];
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */