I didn't implement this before today as I had not see any code
where this would make a difference. I noticed while looking into
regressions an uninitialized warning that shows up only with
-fsanitize=address. This because SRA causes some extra total
scalaization when using -fsanitize=address. Which in turn exposes
an uninitialized warning. This fixes the uninitialized warning
by doing a simple copy prop into the return statement.

That is if we have:
```
  D.3407 = D.3418;
  return D.3407;
```

turn it into:
```
  D.3407 = D.3418;
  return D.3418;
```

This forces SRA not to do total scalarization on D.3418 and allows for better 
code
too.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/95825

gcc/ChangeLog:

        * tree-ssa-forwprop.cc (optimize_agr_copyprop_return): New function.
        (optimize_agr_copyprop): Call optimize_agr_copyprop_return
        for return statements.

gcc/testsuite/ChangeLog:

        * g++.dg/warn/uninit-pr95825-1.C: New test.
        * gcc.dg/tree-ssa/copy-prop-aggregate-return-1.c: New test.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/testsuite/g++.dg/warn/uninit-pr95825-1.C  | 22 +++++++++++
 .../tree-ssa/copy-prop-aggregate-return-1.c   | 22 +++++++++++
 gcc/tree-ssa-forwprop.cc                      | 37 +++++++++++++++++++
 3 files changed, 81 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/warn/uninit-pr95825-1.C
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-return-1.c

diff --git a/gcc/testsuite/g++.dg/warn/uninit-pr95825-1.C 
b/gcc/testsuite/g++.dg/warn/uninit-pr95825-1.C
new file mode 100644
index 00000000000..01a9b26a1f2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/uninit-pr95825-1.C
@@ -0,0 +1,22 @@
+// { dg-do compile }
+// { dg-options "-O1 -fsanitize=address" }
+
+// PR tree-optimization/95825
+
+struct s1
+{
+  char init;
+  int value;
+};
+
+static struct s1 f()
+{
+  struct s1 t;
+  t.init = 0;
+  return t; /* { dg-bogus "is used uninitialized" } */
+}
+
+struct s1 g()
+{
+  return f();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-return-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-return-1.c
new file mode 100644
index 00000000000..f402931a0ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-return-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1-details" } */
+
+struct s1
+{
+  char init;
+  int value;
+};
+
+static inline struct s1 f()
+{
+  struct s1 t;
+  t.init = 0;
+  return t;
+}
+
+struct s1 g()
+{
+  return f();
+}
+
+/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1"} } */
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index b1d63e189bd..c4fde7b4aae 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -1721,6 +1721,41 @@ optimize_agr_copyprop_arg (gimple *defstmt, gcall *call,
     update_stmt (call);
 }
 
+/* Helper function for optimize_agr_copyprop, propagate aggregates
+   into the return stmt USE if the operand of the return matches DEST;
+   replacing it with SRC.  */
+static void
+optimize_agr_copyprop_return (gimple *defstmt, greturn *use,
+                             tree dest, tree src)
+{
+  tree rvalue = gimple_return_retval (use);
+  if (!rvalue
+      || TREE_CODE (rvalue) == SSA_NAME
+      || is_gimple_min_invariant (rvalue)
+      || TYPE_VOLATILE (TREE_TYPE (rvalue)))
+    return;
+  tree newsrc = new_src_based_on_copy (rvalue, dest, src);
+  if (!newsrc)
+    return;
+  /* Currently only support decls, could support VCEs too? */
+  if (!DECL_P (newsrc))
+    return;
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Simplified\n  ");
+      print_gimple_stmt (dump_file, use, 0, dump_flags);
+      fprintf (dump_file, "after previous\n  ");
+      print_gimple_stmt (dump_file, defstmt, 0, dump_flags);
+    }
+  gimple_return_set_retval (use, newsrc);
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "into\n  ");
+      print_gimple_stmt (dump_file, use, 0, dump_flags);
+    }
+  update_stmt (use);
+}
+
 /* Optimizes
    DEST = SRC;
    DEST2 = DEST; # DEST2 = SRC2;
@@ -1764,6 +1799,8 @@ optimize_agr_copyprop (gimple *stmt)
        optimize_agr_copyprop_1 (stmt, use_stmt, dest, src);
       else if (is_gimple_call (use_stmt))
        optimize_agr_copyprop_arg (stmt, as_a<gcall*>(use_stmt), dest, src);
+      else if (is_a<greturn*> (use_stmt))
+       optimize_agr_copyprop_return (stmt, as_a<greturn*>(use_stmt), dest, 
src);
     }
 }
 
-- 
2.43.0

Reply via email to