On Mon, May 21, 2012 at 3:55 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > As the following testcases show, some places in fold_binary_loc > (haven't checked other routines) can attempt to optimize even vector > expressions, but in that case build_int_cst can't be used. > Instead, for zeros build_zero_cst can be used, for the two places > which need to build 1 I'm just folding the original one argument.
There is build_one_cst, too. > On the 4.7 branch (patch attached after the 4.8 version) there are fewer > spots that need changing, because integer_zerop/integer_onep don't return > true for vectors. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.7? Ok. Thanks, Richard. > 2012-05-21 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/53410 > * fold-const.c (fold_binary_loc): Use build_zero_cst (type) > instead of build_int_cst (type, 0) where vector types might be > involved. Instead of build_int_cst (type, 1) convert the original > integer_onep argument to the desired type. > > * gcc.c-torture/compile/pr53410-1.c: New test. > * gcc.c-torture/compile/pr53410-2.c: New test. > > --- gcc/fold-const.c.jj 2012-05-12 10:21:06.000000000 +0200 > +++ gcc/fold-const.c 2012-05-21 10:38:36.928229511 +0200 > @@ -11245,7 +11245,7 @@ fold_binary_loc (location_t loc, > && integer_onep (TREE_OPERAND (arg0, 1)) > && integer_onep (arg1)) > return fold_build2_loc (loc, EQ_EXPR, type, arg0, > - build_int_cst (TREE_TYPE (arg0), 0)); > + build_zero_cst (TREE_TYPE (arg0))); > > /* Fold (X & Y) ^ Y as ~X & Y. */ > if (TREE_CODE (arg0) == BIT_AND_EXPR > @@ -11355,21 +11355,25 @@ fold_binary_loc (location_t loc, > && integer_onep (TREE_OPERAND (arg0, 1)) > && integer_onep (arg1)) > { > + tree tem2; > tem = TREE_OPERAND (arg0, 0); > - return fold_build2_loc (loc, EQ_EXPR, type, > - fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE > (tem), tem, > - build_int_cst (TREE_TYPE (tem), > 1)), > - build_int_cst (TREE_TYPE (tem), 0)); > + tem2 = fold_convert_loc (loc, TREE_TYPE (tem), arg1); > + tem2 = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (tem), > + tem, tem2); > + return fold_build2_loc (loc, EQ_EXPR, type, tem2, > + build_zero_cst (TREE_TYPE (tem))); > } > /* Fold ~X & 1 as (X & 1) == 0. */ > if (TREE_CODE (arg0) == BIT_NOT_EXPR > && integer_onep (arg1)) > { > + tree tem2; > tem = TREE_OPERAND (arg0, 0); > - return fold_build2_loc (loc, EQ_EXPR, type, > - fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE > (tem), tem, > - build_int_cst (TREE_TYPE (tem), > 1)), > - build_int_cst (TREE_TYPE (tem), 0)); > + tem2 = fold_convert_loc (loc, TREE_TYPE (tem), arg1); > + tem2 = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (tem), > + tem, tem2); > + return fold_build2_loc (loc, EQ_EXPR, type, tem2, > + build_zero_cst (TREE_TYPE (tem))); > } > /* Fold !X & 1 as X == 0. */ > if (TREE_CODE (arg0) == TRUTH_NOT_EXPR > @@ -11377,7 +11381,7 @@ fold_binary_loc (location_t loc, > { > tem = TREE_OPERAND (arg0, 0); > return fold_build2_loc (loc, EQ_EXPR, type, tem, > - build_int_cst (TREE_TYPE (tem), 0)); > + build_zero_cst (TREE_TYPE (tem))); > } > > /* Fold (X ^ Y) & Y as ~X & Y. */ > @@ -12893,13 +12897,13 @@ fold_binary_loc (location_t loc, > if (TREE_CODE (arg0) == BIT_XOR_EXPR > && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)) > return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), > - build_int_cst (TREE_TYPE (arg0), 0)); > + build_zero_cst (TREE_TYPE (arg0))); > /* Likewise (X ^ Y) == X becomes Y == 0. X has no side-effects. */ > if (TREE_CODE (arg0) == BIT_XOR_EXPR > && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) > && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1)) > return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 1), > - build_int_cst (TREE_TYPE (arg0), 0)); > + build_zero_cst (TREE_TYPE (arg0))); > > /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ > if (TREE_CODE (arg0) == BIT_XOR_EXPR > @@ -12987,7 +12991,7 @@ fold_binary_loc (location_t loc, > BIT_XOR_EXPR, itype, > arg00, arg10), > arg01), > - build_int_cst (itype, 0)); > + build_zero_cst (itype)); > > if (operand_equal_p (arg01, arg10, 0)) > return fold_build2_loc (loc, code, type, > @@ -12996,7 +13000,7 @@ fold_binary_loc (location_t loc, > BIT_XOR_EXPR, itype, > arg00, arg11), > arg01), > - build_int_cst (itype, 0)); > + build_zero_cst (itype)); > > if (operand_equal_p (arg00, arg11, 0)) > return fold_build2_loc (loc, code, type, > @@ -13005,7 +13009,7 @@ fold_binary_loc (location_t loc, > BIT_XOR_EXPR, itype, > arg01, arg10), > arg00), > - build_int_cst (itype, 0)); > + build_zero_cst (itype)); > > if (operand_equal_p (arg00, arg10, 0)) > return fold_build2_loc (loc, code, type, > @@ -13014,7 +13018,7 @@ fold_binary_loc (location_t loc, > BIT_XOR_EXPR, itype, > arg01, arg11), > arg00), > - build_int_cst (itype, 0)); > + build_zero_cst (itype)); > } > > if (TREE_CODE (arg0) == BIT_XOR_EXPR > @@ -13492,7 +13496,7 @@ fold_binary_loc (location_t loc, > return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type, > build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0, > TREE_OPERAND (arg1, 1)), > - build_int_cst (TREE_TYPE (arg0), 0)); > + build_zero_cst (TREE_TYPE (arg0))); > > if ((code == LT_EXPR || code == GE_EXPR) > && TYPE_UNSIGNED (TREE_TYPE (arg0)) > @@ -13504,7 +13508,7 @@ fold_binary_loc (location_t loc, > TREE_OPERAND (TREE_OPERAND (arg1, 0), 1)); > return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type, > fold_convert_loc (loc, TREE_TYPE (arg0), tem), > - build_int_cst (TREE_TYPE (arg0), 0)); > + build_zero_cst (TREE_TYPE (arg0))); > } > > return NULL_TREE; > --- gcc/testsuite/gcc.c-torture/compile/pr53410-1.c.jj 2012-05-21 > 10:44:19.180235126 +0200 > +++ gcc/testsuite/gcc.c-torture/compile/pr53410-1.c 2012-05-21 > 09:58:40.000000000 +0200 > @@ -0,0 +1,10 @@ > +/* PR tree-optimization/53410 */ > + > +int *a, b, c, d; > + > +void > +foo (void) > +{ > + for (; d <= 0; d++) > + b &= ((a || d) ^ c) == 1; > +} > --- gcc/testsuite/gcc.c-torture/compile/pr53410-2.c.jj 2012-05-21 > 10:44:22.072217996 +0200 > +++ gcc/testsuite/gcc.c-torture/compile/pr53410-2.c 2012-05-21 > 10:45:53.692684063 +0200 > @@ -0,0 +1,64 @@ > +/* PR tree-optimization/53410 */ > + > +typedef int V __attribute__((vector_size (4 * sizeof (int)))); > +typedef unsigned int W __attribute__((vector_size (4 * sizeof (int)))); > + > +void > +f1 (V *p) > +{ > + *p = (*p & ((V) { 1, 1, 1, 1 })) ^ ((V) { 1, 1, 1, 1}); > +} > + > +void > +f2 (V *p) > +{ > + *p = (*p ^ ((V) { 1, 1, 1, 1 })) & ((V) { 1, 1, 1, 1}); > +} > + > +void > +f3 (V *p) > +{ > + *p = (~*p) & ((V) { 1, 1, 1, 1 }); > +} > + > +void > +f4 (V *p, V *q) > +{ > + *p = (*p ^ *q) == *q; > +} > + > +void > +f5 (V *p, V *q) > +{ > + *p = (*p ^ *q) == *p; > +} > + > +void > +f6 (V *p, V *q, V *r) > +{ > + *p = (*p & *r) == (*q & *r); > +} > + > +void > +f7 (V *p, V *q, V *r) > +{ > + *p = (*p & *r) == (*r & *q); > +} > + > +void > +f8 (V *p, V *q, V *r) > +{ > + *p = (*r & *p) == (*q & *r); > +} > + > +void > +f9 (V *p, V *q, V *r) > +{ > + *p = (*r & *p) == (*r & *q); > +} > + > +void > +f10 (W *p, W *q) > +{ > + *p = *p < (((const W) { 1U, 1U, 1U, 1U }) << *q); > +} > > Jakub