On Tue, Mar 15, 2011 at 8:41 PM, Jakub Jelinek <ja...@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  <ja...@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
>

Reply via email to