From patchwork Wed Sep 15 13:08:39 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: vector pointer handling fix (PR tree-optimization/45633) Date: Wed, 15 Sep 2010 03:08:39 -0000 From: Jakub Jelinek X-Patchwork-Id: 64812 Message-Id: <20100915130839.GK1269@tyan-ft48-01.lab.bos.redhat.com> To: Richard Guenther Cc: gcc-patches@gcc.gnu.org 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 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) : For pointer or vector pointer use TER to optimize pointer subtraction. * gcc.dg/vect/pr45633.c: New test. 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" } } */