Message ID | 20100915130839.GK1269@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
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 > >
--- 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" } } */