Message ID | 20110315194138.GC30899@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Tue, Mar 15, 2011 at 8:41 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > The addition of STRIP_NOPS for EQ_EXPR/NE_EXPR revealed a bunch of cases > which rely on arg0 and arg1 having the same type. Only the last hunk > fixes the testcase, the rest is what I saw and it was possible the > types wouldn't match. Tried to construct testcases for the other cases, > but didn't succeed, earlier folding already modified the operands so it > didn't look like what the code was expecting. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Ok. Thanks, Richard. > 2011-03-15 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/48136 > * fold-const.c (fold_binary_loc) <case EQ_EXPR, NE_EXPR>: Make sure > arg0/arg1 or their arguments are always fold converted to matching > types. > > * gcc.c-torture/compile/pr48136.c: New test. > > --- gcc/fold-const.c.jj 2011-03-15 09:47:12.000000000 +0100 > +++ gcc/fold-const.c 2011-03-15 17:13:29.000000000 +0100 > @@ -12342,7 +12342,8 @@ fold_binary_loc (location_t loc, > { > tem = fold_build2_loc (loc, LSHIFT_EXPR, itype, arg01, arg001); > tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, arg000, tem); > - return fold_build2_loc (loc, code, type, tem, arg1); > + return fold_build2_loc (loc, code, type, tem, > + fold_convert_loc (loc, itype, arg1)); > } > /* Otherwise, for signed (arithmetic) shifts, > ((X >> C1) & C2) != 0 is rewritten as X < 0, and > @@ -12393,8 +12394,10 @@ fold_binary_loc (location_t loc, > tree notc = fold_build1_loc (loc, BIT_NOT_EXPR, > TREE_TYPE (TREE_OPERAND (arg0, 1)), > TREE_OPERAND (arg0, 1)); > - tree dandnotc = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), > - arg1, notc); > + tree dandnotc > + = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), > + fold_convert_loc (loc, TREE_TYPE (arg0), arg1), > + notc); > tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; > if (integer_nonzerop (dandnotc)) > return omit_one_operand_loc (loc, type, rslt, arg0); > @@ -12407,8 +12410,10 @@ fold_binary_loc (location_t loc, > && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) > { > tree notd = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1), arg1); > - tree candnotd = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), > - TREE_OPERAND (arg0, 1), notd); > + tree candnotd > + = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), > + TREE_OPERAND (arg0, 1), > + fold_convert_loc (loc, TREE_TYPE (arg0), notd)); > tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; > if (integer_nonzerop (candnotd)) > return omit_one_operand_loc (loc, type, rslt, arg0); > @@ -12483,13 +12488,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 (arg1), 0)); > + build_int_cst (TREE_TYPE (arg0), 0)); > /* 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 (arg1), 0)); > + build_int_cst (TREE_TYPE (arg0), 0)); > > /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ > if (TREE_CODE (arg0) == BIT_XOR_EXPR > @@ -12507,10 +12512,12 @@ fold_binary_loc (location_t loc, > && integer_pow2p (TREE_OPERAND (arg0, 1))) > { > tem = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), > - TREE_OPERAND (TREE_OPERAND (arg0, 0), 0), > - TREE_OPERAND (arg0, 1)); > + TREE_OPERAND (TREE_OPERAND (arg0, 0), 0), > + TREE_OPERAND (arg0, 1)); > return fold_build2_loc (loc, code == EQ_EXPR ? NE_EXPR : EQ_EXPR, > - type, tem, arg1); > + type, tem, > + fold_convert_loc (loc, TREE_TYPE (arg0), > + arg1)); > } > > /* Fold ((X & C) ^ C) eq/ne 0 into (X & C) ne/eq 0, when the > @@ -12554,8 +12561,9 @@ fold_binary_loc (location_t loc, > if (TREE_CODE (arg0) == NEGATE_EXPR > && TREE_CODE (arg1) == NEGATE_EXPR) > return fold_build2_loc (loc, code, type, > - TREE_OPERAND (arg0, 0), > - TREE_OPERAND (arg1, 0)); > + TREE_OPERAND (arg0, 0), > + fold_convert_loc (loc, TREE_TYPE (arg0), > + TREE_OPERAND (arg1, 0))); > > /* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries. */ > if (TREE_CODE (arg0) == BIT_AND_EXPR > @@ -12628,12 +12636,13 @@ fold_binary_loc (location_t loc, > /* Optimize (X ^ C1) op (Y ^ C2) as (X ^ (C1 ^ C2)) op Y. */ > if (TREE_CODE (arg01) == INTEGER_CST > && TREE_CODE (arg11) == INTEGER_CST) > - return fold_build2_loc (loc, code, type, > - fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, > - fold_build2_loc (loc, > - BIT_XOR_EXPR, itype, > - arg01, arg11)), > - arg10); > + { > + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01, > + fold_convert_loc (loc, itype, arg11)); > + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem); > + return fold_build2_loc (loc, code, type, tem, > + fold_convert_loc (loc, itype, arg10)); > + } > } > > /* Attempt to simplify equality/inequality comparisons of complex > --- gcc/testsuite/gcc.c-torture/compile/pr48136.c.jj 2011-03-15 17:27:43.000000000 +0100 > +++ gcc/testsuite/gcc.c-torture/compile/pr48136.c 2011-03-15 17:27:23.000000000 +0100 > @@ -0,0 +1,7 @@ > +/* PR middle-end/48136 */ > + > +int > +foo (int x, int y) > +{ > + return (x ^ 5U) == (y ^ 1); > +} > > Jakub >
--- gcc/fold-const.c.jj 2011-03-15 09:47:12.000000000 +0100 +++ gcc/fold-const.c 2011-03-15 17:13:29.000000000 +0100 @@ -12342,7 +12342,8 @@ fold_binary_loc (location_t loc, { tem = fold_build2_loc (loc, LSHIFT_EXPR, itype, arg01, arg001); tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, arg000, tem); - return fold_build2_loc (loc, code, type, tem, arg1); + return fold_build2_loc (loc, code, type, tem, + fold_convert_loc (loc, itype, arg1)); } /* Otherwise, for signed (arithmetic) shifts, ((X >> C1) & C2) != 0 is rewritten as X < 0, and @@ -12393,8 +12394,10 @@ fold_binary_loc (location_t loc, tree notc = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (TREE_OPERAND (arg0, 1)), TREE_OPERAND (arg0, 1)); - tree dandnotc = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), - arg1, notc); + tree dandnotc + = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), + fold_convert_loc (loc, TREE_TYPE (arg0), arg1), + notc); tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; if (integer_nonzerop (dandnotc)) return omit_one_operand_loc (loc, type, rslt, arg0); @@ -12407,8 +12410,10 @@ fold_binary_loc (location_t loc, && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) { tree notd = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1), arg1); - tree candnotd = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), - TREE_OPERAND (arg0, 1), notd); + tree candnotd + = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), + TREE_OPERAND (arg0, 1), + fold_convert_loc (loc, TREE_TYPE (arg0), notd)); tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; if (integer_nonzerop (candnotd)) return omit_one_operand_loc (loc, type, rslt, arg0); @@ -12483,13 +12488,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 (arg1), 0)); + build_int_cst (TREE_TYPE (arg0), 0)); /* 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 (arg1), 0)); + build_int_cst (TREE_TYPE (arg0), 0)); /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ if (TREE_CODE (arg0) == BIT_XOR_EXPR @@ -12507,10 +12512,12 @@ fold_binary_loc (location_t loc, && integer_pow2p (TREE_OPERAND (arg0, 1))) { tem = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), - TREE_OPERAND (TREE_OPERAND (arg0, 0), 0), - TREE_OPERAND (arg0, 1)); + TREE_OPERAND (TREE_OPERAND (arg0, 0), 0), + TREE_OPERAND (arg0, 1)); return fold_build2_loc (loc, code == EQ_EXPR ? NE_EXPR : EQ_EXPR, - type, tem, arg1); + type, tem, + fold_convert_loc (loc, TREE_TYPE (arg0), + arg1)); } /* Fold ((X & C) ^ C) eq/ne 0 into (X & C) ne/eq 0, when the @@ -12554,8 +12561,9 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR) return fold_build2_loc (loc, code, type, - TREE_OPERAND (arg0, 0), - TREE_OPERAND (arg1, 0)); + TREE_OPERAND (arg0, 0), + fold_convert_loc (loc, TREE_TYPE (arg0), + TREE_OPERAND (arg1, 0))); /* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries. */ if (TREE_CODE (arg0) == BIT_AND_EXPR @@ -12628,12 +12636,13 @@ fold_binary_loc (location_t loc, /* Optimize (X ^ C1) op (Y ^ C2) as (X ^ (C1 ^ C2)) op Y. */ if (TREE_CODE (arg01) == INTEGER_CST && TREE_CODE (arg11) == INTEGER_CST) - return fold_build2_loc (loc, code, type, - fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, - fold_build2_loc (loc, - BIT_XOR_EXPR, itype, - arg01, arg11)), - arg10); + { + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01, + fold_convert_loc (loc, itype, arg11)); + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem); + return fold_build2_loc (loc, code, type, tem, + fold_convert_loc (loc, itype, arg10)); + } } /* Attempt to simplify equality/inequality comparisons of complex --- gcc/testsuite/gcc.c-torture/compile/pr48136.c.jj 2011-03-15 17:27:43.000000000 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr48136.c 2011-03-15 17:27:23.000000000 +0100 @@ -0,0 +1,7 @@ +/* PR middle-end/48136 */ + +int +foo (int x, int y) +{ + return (x ^ 5U) == (y ^ 1); +}