[PATCH] Fix folding of (X | C1) & C2 (PR c/37261)

Richard Guenther richard.guenther@gmail.com
Sat Aug 30 16:31:00 GMT 2008


On Fri, Aug 29, 2008 at 2:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This bug got introduced by PR33691 fix, which fixed the folding to use
> the same type, but unfortunately not the right one as the following
> testcase shows.  TREE_TYPE (arg0) is int and TREE_TYPE (arg1) is unsigned
> int and it has the uppermost bit set, so overflow is set when it is
> fold_converted.  The right fix is to do all the BIT_AND_EXPRs and
> BIT_IOR_EXPRs in the resulting type, which in case of mixing signed with
> unsigned arguments will be unsigned.
>
> Starting bootstrap on x86_64-linux, ok for trunk/4.3 if it succeeds?

This looks bogus from the start.  We shouldn't ever have created
BIT_AND_EXPR or BIT_IOR_EXPR with mismatched types.

The type verifier seems to have lost all checking of binary operations
during tuplification it seems ...

Richard.

> 2008-08-29  Jakub Jelinek  <jakub@redhat.com>
>
>        PR c/37261
>        * fold-const.c (fold_binary): In (X | C1) & C2 canonicalization
>        compute new & and | in type rather than TREE_TYPE (arg0).
>
>        * gcc.dg/pr37261.c: New test.
>
> --- gcc/fold-const.c.jj 2008-08-22 19:49:36.000000000 +0200
> +++ gcc/fold-const.c    2008-08-29 13:54:30.000000000 +0200
> @@ -10726,14 +10726,13 @@ fold_binary (enum tree_code code, tree t
>          && TREE_CODE (arg1) == INTEGER_CST
>          && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
>        {
> -         tree tmp1 = fold_convert (TREE_TYPE (arg0), arg1);
> -         tree tmp2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
> -                                  TREE_OPERAND (arg0, 0), tmp1);
> -         tree tmp3 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
> -                                  TREE_OPERAND (arg0, 1), tmp1);
> +         tree tmp1 = fold_convert (type, arg1);
> +         tree tmp2 = fold_convert (type, TREE_OPERAND (arg0, 0));
> +         tree tmp3 = fold_convert (type, TREE_OPERAND (arg0, 1));
> +         tmp2 = fold_build2 (BIT_AND_EXPR, type, tmp2, tmp1);
> +         tmp3 = fold_build2 (BIT_AND_EXPR, type, tmp3, tmp1);
>          return fold_convert (type,
> -                              fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0),
> -                                           tmp2, tmp3));
> +                              fold_build2 (BIT_IOR_EXPR, type, tmp2, tmp3));
>        }
>
>       /* (X | Y) & Y is (X, Y).  */
> --- gcc/testsuite/gcc.dg/pr37261.c.jj   2008-08-29 14:07:17.000000000 +0200
> +++ gcc/testsuite/gcc.dg/pr37261.c      2008-08-29 14:06:56.000000000 +0200
> @@ -0,0 +1,15 @@
> +/* PR c/37261 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +unsigned
> +foo (int x)
> +{
> +  unsigned a = ((x & 1) | 2) & 0x80000000;     /* { dg-bogus "integer overflow in expression" } */
> +  unsigned b = ((x & 2) | 2) & 0x80000000;     /* { dg-bogus "integer overflow in expression" } */
> +  unsigned c = ((x & 4) | 2) & 0x80000000;     /* { dg-bogus "integer overflow in expression" } */
> +  return a + b + c;
> +}
> +
> +/* { dg-final { scan-tree-dump "return 0" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
>
>        Jakub
>



More information about the Gcc-patches mailing list