public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Andre Vieira (lists)" <andre.simoesdiasvieira@arm.com>
To: Richard Biener <rguenther@suse.de>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
	Richard Sandiford <richard.sandiford@arm.com>
Subject: Re: ifcvt: Fix bitpos calculation in bitfield lowering [PR107229]
Date: Thu, 13 Oct 2022 11:15:53 +0100	[thread overview]
Message-ID: <0e62cd70-b461-7ad8-8d37-a39ed4f4a9cd@arm.com> (raw)
In-Reply-To: <nycvar.YFH.7.77.849.2210130813270.18337@jbgna.fhfr.qr>

[-- Attachment #1: Type: text/plain, Size: 1381 bytes --]

Added some extra comments to describe what is going on there.

On 13/10/2022 09:14, Richard Biener wrote:
> On Wed, 12 Oct 2022, Andre Vieira (lists) wrote:
>
>> Hi,
>>
>> The bitposition calculation for the bitfield lowering in loop if conversion
>> was not
>> taking DECL_FIELD_OFFSET into account, which meant that it would result in
>> wrong bitpositions for bitfields that did not end up having representations
>> starting at the beginning of the struct.
>>
>> Bootstrappend and regression tested on aarch64-none-linux-gnu and
>> x86_64-pc-linux-gnu.
> +    {
> +      tree bf_pos = fold_build2 (MULT_EXPR, bitsizetype,
> +                                DECL_FIELD_OFFSET (field_decl),
> +                                build_int_cst (bitsizetype, 8));
> +      bf_pos = fold_build2 (PLUS_EXPR, bitsizetype, bf_pos,
> +                           DECL_FIELD_BIT_OFFSET (field_decl));
> +      tree rep_pos = fold_build2 (MULT_EXPR, bitsizetype,
> +                                 DECL_FIELD_OFFSET (rep_decl),
> +                                 build_int_cst (bitsizetype, 8));
> +      rep_pos = fold_build2 (PLUS_EXPR, bitsizetype, rep_pos,
> +                            DECL_FIELD_BIT_OFFSET (rep_decl));
>
> you can use the invariant that DECL_FIELD_OFFSET of rep_decl
> and field_decl are always the same.  Also please use BITS_PER_UNIT
> instead of '8'.
>
> Richard.

[-- Attachment #2: PR107229-2.patch --]
[-- Type: text/plain, Size: 3681 bytes --]

diff --git a/gcc/testsuite/gcc.dg/vect/pr107229-1.c b/gcc/testsuite/gcc.dg/vect/pr107229-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..67b432383d057a630746aa00af50c25fcb527d8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr107229-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* PR tree-optimization/107229.  */
+
+int a, c;
+struct {
+  long d;
+  int : 8;
+  int : 27;
+  int e : 21;
+} f;
+void g(int b) { a = a & 1; }
+int main() {
+  while (c)
+    g(f.e);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr107229-2.c b/gcc/testsuite/gcc.dg/vect/pr107229-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..88bffb63d5e8b2d7bcdeae223f4ec6ea4f611bc9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr107229-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* PR tree-optimization/107229.  */
+
+int a, c;
+struct {
+  long f;
+  long g;
+  long d;
+  int : 8;
+  int : 27;
+  int e : 21;
+} f;
+void g(int b) { a = a & 1; }
+int main() {
+  while (c)
+    g(f.e);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr107229-3.c b/gcc/testsuite/gcc.dg/vect/pr107229-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..4abd8c14531b40e9dbe9802a8f9a0eabba673c9f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr107229-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* PR tree-optimization/107229.  */
+
+int a, c;
+struct {
+  long f;
+  long g;
+  long d;
+  int : 8;
+  int : 32;
+  int : 2;
+  int e : 21;
+} f;
+void g(int b) { a = a & 1; }
+int main() {
+  while (c)
+    g(f.e);
+  return 0;
+}
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index e468a4659fa28a3a31c3390cf19bee65f4590b80..01637c5da08d5a2a00a495522fc9a6436a804398 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -3298,10 +3298,34 @@ get_bitfield_rep (gassign *stmt, bool write, tree *bitpos,
     *struct_expr = TREE_OPERAND (comp_ref, 0);
 
   if (bitpos)
-    *bitpos
-      = fold_build2 (MINUS_EXPR, bitsizetype,
-		     DECL_FIELD_BIT_OFFSET (field_decl),
-		     DECL_FIELD_BIT_OFFSET (rep_decl));
+    {
+      /* To calculate the bitposition of the BITFIELD_REF we have to determine
+	 where our bitfield starts in relation to the container REP_DECL. The
+	 DECL_FIELD_OFFSET of the original bitfield's member FIELD_DECL tells
+	 us how many bytes from the start of the structure there are until the
+	 start of the group of bitfield members the FIELD_DECL belongs to,
+	 whereas DECL_FIELD_BIT_OFFSET will tell us how many bits from that
+	 position our actual bitfield member starts.  For the container
+	 REP_DECL adding DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET will tell
+	 us the distance between the start of the structure and the start of
+	 the container, though the first is in bytes and the later other in
+	 bits.  With this in mind we calculate the bit position of our new
+	 BITFIELD_REF by subtracting the number of bits between the start of
+	 the structure and the container from the number of bits from the start
+	 of the structure and the actual bitfield member. */
+      tree bf_pos = fold_build2 (MULT_EXPR, bitsizetype,
+				 DECL_FIELD_OFFSET (field_decl),
+				 build_int_cst (bitsizetype, BITS_PER_UNIT));
+      bf_pos = fold_build2 (PLUS_EXPR, bitsizetype, bf_pos,
+			    DECL_FIELD_BIT_OFFSET (field_decl));
+      tree rep_pos = fold_build2 (MULT_EXPR, bitsizetype,
+				  DECL_FIELD_OFFSET (rep_decl),
+				  build_int_cst (bitsizetype, BITS_PER_UNIT));
+      rep_pos = fold_build2 (PLUS_EXPR, bitsizetype, rep_pos,
+			     DECL_FIELD_BIT_OFFSET (rep_decl));
+
+      *bitpos = fold_build2 (MINUS_EXPR, bitsizetype, bf_pos, rep_pos);
+    }
 
   return rep_decl;
 

  reply	other threads:[~2022-10-13 10:16 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-12 17:29 Andre Vieira (lists)
2022-10-13  8:14 ` Richard Biener
2022-10-13 10:15   ` Andre Vieira (lists) [this message]
2022-10-13 10:18     ` Richard Biener
2022-10-13 11:39 ` Rainer Orth
2022-10-13 13:55   ` Andre Vieira (lists)
2022-10-13 14:15     ` Richard Biener
2022-10-13 14:42       ` Andre Vieira (lists)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0e62cd70-b461-7ad8-8d37-a39ed4f4a9cd@arm.com \
    --to=andre.simoesdiasvieira@arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=rguenther@suse.de \
    --cc=richard.sandiford@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).