]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/113727 - bogus SRA with BIT_FIELD_REF
authorRichard Biener <rguenther@suse.de>
Tue, 19 Mar 2024 13:50:06 +0000 (14:50 +0100)
committerRichard Biener <rguenther@suse.de>
Thu, 21 Mar 2024 07:33:25 +0000 (08:33 +0100)
When SRA analyzes BIT_FIELD_REFs it handles writes and not byte
aligned reads differently from byte aligned reads.  Instead of
trying to create replacements for the loaded portion the former
cases try to replace the base object while keeping the wrapping
BIT_FIELD_REFs.  This breaks when we have both kinds operating
on the same base object if there's no appearant overlap conflict
as the conflict that then nevertheless exists isn't handled with.
The fix is to enforce what I think is part of the design handling
the former case - that only the full base object gets replaced
and no further sub-objects are created within as otherwise
keeping the wrapping BIT_FIELD_REF cannot work.  The patch
enforces this within analyze_access_subtree.

PR tree-optimization/113727
* tree-sra.cc (analyze_access_subtree): Do not allow
replacements in subtrees when grp_partial_lhs.

* gcc.dg/torture/pr113727.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr113727.c [new file with mode: 0644]
gcc/tree-sra.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr113727.c b/gcc/testsuite/gcc.dg/torture/pr113727.c
new file mode 100644 (file)
index 0000000..f92ddad
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+struct f {
+  unsigned au : 5;
+  unsigned f3 : 21;
+} g_994;
+
+int main()
+{
+  struct f aq1 = {};
+    {
+      struct f aq = {9, 5};
+      struct f as = aq;
+      for (int y = 0 ; y <= 4; y += 1)
+       if (as.au)
+         {
+           struct f aa[5] = {{2, 154}, {2, 154}, {2, 154}, {2, 154}, {2, 154}};
+           as = aa[0];
+         }
+      aq1 = as;
+    }
+  if (aq1.f3 != 0x9a)
+    __builtin_abort();
+  return 0;
+}
index f8e71ec48b9372d827f9209d111f5498c5072674..dbfae5e7fdd99becbd08a52b21bbb2f1c4126311 100644 (file)
@@ -2735,7 +2735,8 @@ analyze_access_subtree (struct access *root, struct access *parent,
     {
       hole |= covered_to < child->offset;
       sth_created |= analyze_access_subtree (child, root,
-                                            allow_replacements && !scalar,
+                                            allow_replacements && !scalar
+                                            && !root->grp_partial_lhs,
                                             totally);
 
       root->grp_unscalarized_data |= child->grp_unscalarized_data;