This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Restore bitfield comparison optimization (PR middle-end/37248)
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: "Jakub Jelinek" <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 5 Dec 2008 14:37:29 -0800
- Subject: Re: [PATCH] Restore bitfield comparison optimization (PR middle-end/37248)
- References: <20081205162733.GZ17496@tyan-ft48-01.lab.bos.redhat.com>
On Fri, Dec 5, 2008 at 8:27 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> After discussions on IRC how to solve this, I'm proposing to restore
> this optimization similarly how it has been restored for 4.3,
> as trunk still generates BIT_FIELD_REFs with struct/union bases
> anyway (in SRA) and so the compiler supports them anyway.
>
> The only difference from 4.4 here is that BIT_FIELD_REF_UNSIGNED
> is gone, so we have to make sure the type on the BIT_FIELD_REF is
> the right width and signedness (but it usually is even without
> build_nonstandard_integer_type, because optimize_bit_field_compare
> uses types with TYPE_PRECISION the same as TYPE_SIZE.
>
> Bootstrapped/regtested on x86_64-linux (2 extra patches are needed),
> ok for trunk?
>
> 2008-12-05 Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/37248
> * fold-const.c (make_bit_field_ref): Change bitpos and bitsize
> arguments to HOST_WIDE_INT. If type has different signedness
> than unsignedp or different precision from bitsize, create
> the right type for BIT_FIELD_REF and cast to type.
> (fold_truthop): Change first_bit and end_bit to HOST_WIDE_INT.
>
> Revert:
> 2008-03-05 Richard Guenther <rguenther@suse.de>
> PR c++/35336
> * fold-const.c (fold_truthop): Remove code generating
> BIT_FIELD_REFs of structure bases.
> (fold_binary): Likewise.
> (make_bit_field_ref): Remove.
> (optimize_bit_field_compare): Remove.
> (all_ones_mask_p): Remove.
>
> * gcc.target/i386/pr37248-1.c: New test.
> * gcc.target/i386/pr37248-2.c: New test.
> * gcc.target/i386/pr37248-3.c: New test.
>
> --- gcc/testsuite/gcc.target/i386/pr37248-2.c.jj 2008-12-04 15:37:38.000000000 +0100
> +++ gcc/testsuite/gcc.target/i386/pr37248-2.c 2008-12-04 15:28:18.000000000 +0100
> @@ -0,0 +1,23 @@
> +/* PR middle-end/37248 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +struct S
> +{
> + unsigned char a : 1;
> + unsigned char b : 1;
> + unsigned char c : 1;
> + unsigned int d : 26;
> + unsigned char e : 1;
> + unsigned char f : 1;
> + unsigned char g : 1;
> +} s;
> +
> +int
> +foo (struct S x)
> +{
> + return x.a && x.g && x.b && x.f && x.c && x.e;
> +}
> +
> +/* { dg-final { scan-tree-dump "& 3758096391\[^\n\t\]*== 3758096391" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> --- gcc/testsuite/gcc.target/i386/pr37248-3.c.jj 2008-12-04 15:40:39.000000000 +0100
> +++ gcc/testsuite/gcc.target/i386/pr37248-3.c 2008-12-04 15:39:12.000000000 +0100
> @@ -0,0 +1,25 @@
> +/* PR middle-end/37248 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +struct S
> +{
> + unsigned char a : 1;
> + unsigned char b : 1;
> + unsigned char c : 1;
> + unsigned int d : 6;
> + unsigned int e : 14;
> + unsigned int f : 6;
> + unsigned char g : 1;
> + unsigned char h : 1;
> + unsigned char i : 1;
> +} s;
> +
> +int
> +foo (struct S x)
> +{
> + return x.a && x.i && x.b && x.h && x.c && x.g && x.e == 131;
> +}
> +
> +/* { dg-final { scan-tree-dump "& 3766484487\[^\n\t\]*== 3758163463" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
>
I got
+FAIL: gcc.target/i386/pr37248-2.c scan-tree-dump optimized "& 3758096391[^
+FAIL: gcc.target/i386/pr37248-3.c scan-tree-dump optimized "& 3766484487[^
on Fedora 9/ia32. I saw
;; Function foo (foo)
Analyzing Edge Insertions.
foo (struct S x)
{
<bb 2>:
return (BIT_FIELD_REF <x, 32, 0> & 0x0e0000007) == 0x0e0000007;
}
0x0e0000007 is the same as 3758096391
--
H.J.