https://gcc.gnu.org/g:7e8e4dac65ba37ff7511d7897fa50a00e1d3479a

commit r16-7521-g7e8e4dac65ba37ff7511d7897fa50a00e1d3479a
Author: Andrew Pinski <[email protected]>
Date:   Sat Feb 14 11:33:01 2026 -0800

    forwprop: Fix copy prop aggregates into return statements slightly 
[PR124099]
    
    So a few more restrictions are needed here.
    First we don't need to change if the return statement is already
    a RESULT_DECL nor deference of the RESULT_DECL.
    Second proping a global variable into the return is ok for the most
    part except enumtls does not know how to expand that correctly and things
    go down hill. So restrict to non global vars now.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    Also tested the testcase with TLS turned off so enumtls ran.
    
            PR tree-optimization/124099
    
    gcc/ChangeLog:
    
            * tree-ssa-forwprop.cc (optimize_agr_copyprop_return): Don't do 
anything
            if the return is already result decl or a deference of result decl.
            Also reject non local var decls.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/tls-return-1.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/torture/tls-return-1.c | 12 ++++++++++++
 gcc/tree-ssa-forwprop.cc                    | 15 +++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/tls-return-1.c 
b/gcc/testsuite/gcc.dg/torture/tls-return-1.c
new file mode 100644
index 000000000000..aa56e42904cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/tls-return-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+
+/* PR tree-optimization/124099 */ 
+
+struct s1 { int t[2];};
+__thread struct s1 t;
+struct s1 g()
+{ 
+  return t;
+}
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index c4fde7b4aae0..931c0798a813 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -1734,11 +1734,22 @@ optimize_agr_copyprop_return (gimple *defstmt, greturn 
*use,
       || is_gimple_min_invariant (rvalue)
       || TYPE_VOLATILE (TREE_TYPE (rvalue)))
     return;
+
+  /* `return <retval>;` is already the best it could be.
+     Likewise `return *<retval>_N(D)`.  */
+  if (TREE_CODE (rvalue) == RESULT_DECL
+      || (TREE_CODE (rvalue) == MEM_REF
+         && TREE_CODE (TREE_OPERAND (rvalue, 0)) == SSA_NAME
+         && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (rvalue, 0)))
+              == RESULT_DECL))
+    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))
+  /* Currently only support non-global vars.
+     See PR 124099 on enumtls not supporting expanding for GIMPLE_RETURN.
+     FIXME: could support VCEs too?  */
+  if (!VAR_P (newsrc) || is_global_var (newsrc))
     return;
   if (dump_file && (dump_flags & TDF_DETAILS))
     {

Reply via email to