From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 3C32E3850425 for ; Mon, 20 Jul 2020 08:16:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3C32E3850425 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rguenther@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 21BE1ADC1; Mon, 20 Jul 2020 08:16:42 +0000 (UTC) Date: Mon, 20 Jul 2020 10:16:36 +0200 (CEST) From: Richard Biener To: Jakub Jelinek cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] gimple-fold: Handle bitfields in fold_const_aggregate_ref_1 [PR93121] In-Reply-To: <20200718081738.GJ2363@tucnak> Message-ID: References: <20200718081738.GJ2363@tucnak> User-Agent: Alpine 2.21 (LSU 202 2017-01-01) MIME-Version: 1.0 X-Spam-Status: No, score=-5.3 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8BIT X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Jul 2020 08:16:38 -0000 On Sat, 18 Jul 2020, Jakub Jelinek wrote: > Hi! > > When working on __builtin_bit_cast that needs to handle bitfields too, > I've made the following change to handle at least some bitfields in > fold_const_aggregate_ref_1 (those that have integral representative). > It already handles some, but only those that start and end at byte > boundaries. > > Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, ok for trunk? OK. Richard. > 2020-07-18 Jakub Jelinek > > PR libstdc++/93121 > * gimple-fold.c (fold_const_aggregate_ref_1): For COMPONENT_REF > of a bitfield not aligned on byte boundaries try to > fold_ctor_reference DECL_BIT_FIELD_REPRESENTATIVE if any and > adjust it depending on endianity. > > * gcc.dg/tree-ssa/pr93121-2.c: New test. > > --- gcc/gimple-fold.c.jj 2020-07-13 19:09:33.218871556 +0200 > +++ gcc/gimple-fold.c 2020-07-17 19:17:59.694537680 +0200 > @@ -7189,8 +7189,64 @@ fold_const_aggregate_ref_1 (tree t, tree > if (maybe_lt (offset, 0)) > return NULL_TREE; > > - return fold_ctor_reference (TREE_TYPE (t), ctor, offset, size, > - base); > + tem = fold_ctor_reference (TREE_TYPE (t), ctor, offset, size, base); > + if (tem) > + return tem; > + > + /* For bit field reads try to read the representative and > + adjust. */ > + if (TREE_CODE (t) == COMPONENT_REF > + && DECL_BIT_FIELD (TREE_OPERAND (t, 1)) > + && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1))) > + { > + HOST_WIDE_INT csize, coffset; > + tree field = TREE_OPERAND (t, 1); > + tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field); > + if (INTEGRAL_TYPE_P (TREE_TYPE (repr)) > + && size.is_constant (&csize) > + && offset.is_constant (&coffset) > + && (coffset % BITS_PER_UNIT != 0 > + || csize % BITS_PER_UNIT != 0) > + && !reverse > + && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN) > + { > + poly_int64 bitoffset; > + poly_uint64 field_offset, repr_offset; > + if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset) > + && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset)) > + bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT; > + else > + bitoffset = 0; > + bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)) > + - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr))); > + HOST_WIDE_INT bitoff; > + int diff = (TYPE_PRECISION (TREE_TYPE (repr)) > + - TYPE_PRECISION (TREE_TYPE (field))); > + if (bitoffset.is_constant (&bitoff) > + && bitoff >= 0 > + && bitoff <= diff) > + { > + offset -= bitoff; > + size = tree_to_uhwi (DECL_SIZE (repr)); > + > + tem = fold_ctor_reference (TREE_TYPE (repr), ctor, offset, > + size, base); > + if (tem && TREE_CODE (tem) == INTEGER_CST) > + { > + if (!BYTES_BIG_ENDIAN) > + tem = wide_int_to_tree (TREE_TYPE (field), > + wi::lrshift (wi::to_wide (tem), > + bitoff)); > + else > + tem = wide_int_to_tree (TREE_TYPE (field), > + wi::lrshift (wi::to_wide (tem), > + diff - bitoff)); > + return tem; > + } > + } > + } > + } > + break; > > case REALPART_EXPR: > case IMAGPART_EXPR: > --- gcc/testsuite/gcc.dg/tree-ssa/pr93121-2.c.jj 2020-07-17 19:47:31.842426096 +0200 > +++ gcc/testsuite/gcc.dg/tree-ssa/pr93121-2.c 2020-07-17 19:48:24.551649910 +0200 > @@ -0,0 +1,22 @@ > +/* PR libstdc++/93121 */ > +/* { dg-do compile { target { ilp32 || lp64 } } } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +union U { int a[3]; struct S { int d; int a : 3; int b : 24; int c : 5; int e; } b; }; > +const union U u = { .a = { 0x7efa3412, 0x5a876543, 0x1eeffeed } }; > +int a, b, c; > + > +void > +foo () > +{ > + a = u.b.a; > + b = u.b.b; > + c = u.b.c; > +} > + > +/* { dg-final { scan-tree-dump-times "a = 3;" 1 "optimized" { target le } } } */ > +/* { dg-final { scan-tree-dump-times "b = 5303464;" 1 "optimized" { target le } } } */ > +/* { dg-final { scan-tree-dump-times "c = 11;" 1 "optimized" { target le } } } */ > +/* { dg-final { scan-tree-dump-times "a = 2;" 1 "optimized" { target be } } } */ > +/* { dg-final { scan-tree-dump-times "b = -2868438;" 1 "optimized" { target be } } } */ > +/* { dg-final { scan-tree-dump-times "c = 3;" 1 "optimized" { target be } } } */ > > > Jakub > > -- Richard Biener SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)