SRA: Limit replacement creation for accesses propagated from LHSs

Message ID ri6czap6y5j.fsf@suse.cz
State Accepted
Headers
Series SRA: Limit replacement creation for accesses propagated from LHSs |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Martin Jambor Oct. 18, 2022, 1:48 p.m. UTC
  Hi,

PR 107206 is fallout from the fix to PR 92706 where we started
propagating accesses across assignments also from LHS to RHS of
assignments so that we would not do harmful total scalarization of the
aggregates on the RHS.

But this can lead to new scalarization of these aggregates and in the
testcase of PR 107206 these can appear in superfluous uses of
un-initialized values and spurious warnings.

Fixed by making sure the the accesses created by propagation in this
direction are only used as a basis for replacements when the structure
would be totally scalarized anyway.

Richi has already approved the patch (without the testcase) in Bugzilla,
so I plan to commit it after bootstrapping and testing it on an x86_64
(on top of a more recent trunk than last week).

Thanks,

Martin


gcc/ChangeLog:

2022-10-18  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/107206
	* tree-sra.cc (struct access): New field grp_result_of_prop_from_lhs.
	(analyze_access_subtree): Do not create replacements for accesses with
	this flag when not toally scalarizing.
	(propagate_subaccesses_from_lhs): Set the new flag.

gcc/testsuite/ChangeLog:

2022-10-18  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/107206
	* g++.dg/tree-ssa/pr107206.C: New test.
---
 gcc/testsuite/g++.dg/tree-ssa/pr107206.C | 27 ++++++++++++++++++++++++
 gcc/tree-sra.cc                          |  7 ++++++
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr107206.C
  

Patch

diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr107206.C b/gcc/testsuite/g++.dg/tree-ssa/pr107206.C
new file mode 100644
index 00000000000..34810ad2b7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr107206.C
@@ -0,0 +1,27 @@ 
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-options "-O -Wuninitialized" }
+
+#include <optional>
+struct X {
+    X() = default;
+    X(X const& r) : i(r.i) {}
+    int i;
+};
+struct Y {
+    Y() : x() {}
+    X x;
+    std::optional<int> o;
+};
+struct Z {
+    Y y;
+    explicit Z(Y y) : y(y) {}
+};
+void f(Y const&);
+void test() {
+    Y const y;
+    Z z(y);
+    z.y.o = 1;
+    auto const w = z;
+    f(w.y);
+}
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index 1a3e12f18cc..6cbeddfc548 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -260,6 +260,9 @@  struct access
 
   /* Should TREE_NO_WARNING of a replacement be set?  */
   unsigned grp_no_warning : 1;
+
+  /* Result of propagation accross link from LHS to RHS.  */
+  unsigned grp_result_of_prop_from_lhs : 1;
 };
 
 typedef struct access *access_p;
@@ -2532,6 +2535,9 @@  analyze_access_subtree (struct access *root, struct access *parent,
   if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
     allow_replacements = false;
 
+  if (!totally && root->grp_result_of_prop_from_lhs)
+    allow_replacements = false;
+
   for (child = root->first_child; child; child = child->next_sibling)
     {
       hole |= covered_to < child->offset;
@@ -2959,6 +2965,7 @@  propagate_subaccesses_from_lhs (struct access *lacc, struct access *racc)
 	  struct access *new_acc
 	    = create_artificial_child_access (racc, lchild, norm_offset,
 					      true, false);
+	  new_acc->grp_result_of_prop_from_lhs = 1;
 	  propagate_subaccesses_from_lhs (lchild, new_acc);
 	}
       else