public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-3270] ifcvt: Fix bitpos calculation in bitfield lowering [PR107229]
@ 2022-10-13 11:11 Andre Simoes Dias Vieira
  0 siblings, 0 replies; only message in thread
From: Andre Simoes Dias Vieira @ 2022-10-13 11:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:9f0d4adabe2035886a1aa8d2ca990a90de000613

commit r13-3270-g9f0d4adabe2035886a1aa8d2ca990a90de000613
Author: Andre Vieira <andre.simoesdiasvieira@arm.com>
Date:   Thu Oct 13 12:09:38 2022 +0100

    ifcvt: Fix bitpos calculation in bitfield lowering [PR107229]
    
    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.
    
    gcc/ChangeLog:
    
            PR tree-optimization/107229
            * tree-if-conv.cc (get_bitfield_rep): Fix bitposition calculation.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/vect/pr107229-1.c: New test.
            * gcc.dg/vect/pr107229-2.c: New test.
            * gcc.dg/vect/pr107229-3.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr107229-1.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.dg/vect/pr107229-2.c | 18 ++++++++++++++++++
 gcc/testsuite/gcc.dg/vect/pr107229-3.c | 19 +++++++++++++++++++
 gcc/tree-if-conv.cc                    | 32 ++++++++++++++++++++++++++++----
 4 files changed, 81 insertions(+), 4 deletions(-)

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 00000000000..67b432383d0
--- /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 00000000000..88bffb63d5e
--- /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 00000000000..4abd8c14531
--- /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 e468a4659fa..01637c5da08 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;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-10-13 11:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-13 11:11 [gcc r13-3270] ifcvt: Fix bitpos calculation in bitfield lowering [PR107229] Andre Simoes Dias Vieira

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).