From: Andrew Pinski Date: Fri, 13 Feb 2026 04:36:33 +0000 (-0800) Subject: forwprop: Add copy prop for aggregates into a return [PR95825] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b960a57e1b00390c2ca9ff1406b72232d379a322;p=thirdparty%2Fgcc.git forwprop: Add copy prop for aggregates into a return [PR95825] 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 --- 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(use_stmt), dest, src); + else if (is_a (use_stmt)) + optimize_agr_copyprop_return (stmt, as_a(use_stmt), dest, src); } }