[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