Hello,

this is a manual bacport of commit
29d8f1f0b7ad3c69b3bdb130325300d5f73aa784 which must be done slightly
elsewhere for gcc 13 and 12 because function
build_access_from_call_arg was added only in gcc 14.

But the gist of the patch is the same.  The commit message of the
original fix says:

PR 117142 shows that the current SRA probably never worked reliably
with arguments passed to a function returning twice, because it then
creates statements before the call which however needs to be at the
beginning of a basic block.

While it should be possible to make at least the case of passing
arguments by value work with SRA (the statements would need to be put
just on the non-abnormal edges leading to the BB), this would mean
large surgery of function sra_modify_expr and I guess the time would
better be spent re-organizing the whole pass.

It has passed bootstrap and testing on x86_64-linux when applied on top
of the gcc-13 release branch and I plan to commit it there tomorrow.
After some two more weeks I plan to do the same on top of gcc-12.

Martin


gcc/ChangeLog:

2024-11-14  Martin Jambor  <mjam...@suse.cz>

        PR tree-optimization/117142
        * tree-sra.cc (scan_function): Disqualify any candidate passed to
        a function returning twice.

gcc/testsuite/ChangeLog:

2024-11-14  Martin Jambor  <mjam...@suse.cz>

        * gcc.dg/tree-ssa/pr117142.c: New test.
---
 gcc/testsuite/gcc.dg/tree-ssa/pr117142.c | 14 ++++++++++++++
 gcc/tree-sra.cc                          | 13 ++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117142.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117142.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr117142.c
new file mode 100644
index 00000000000..fc62c1e58f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117142.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct a {
+  int b;
+};
+void c(int, int);
+void __attribute__((returns_twice))
+bar1(struct a);
+void bar(struct a) {
+  struct a d;
+  bar1(d);
+  c(d.b, d.b);
+}
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index 77508894772..8a9cbeec490 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -1504,9 +1504,16 @@ scan_function (void)
              break;
 
            case GIMPLE_CALL:
-             for (i = 0; i < gimple_call_num_args (stmt); i++)
-               ret |= build_access_from_expr (gimple_call_arg (stmt, i),
-                                              stmt, false);
+             if (gimple_call_flags (stmt) & ECF_RETURNS_TWICE)
+               {
+                 for (i = 0; i < gimple_call_num_args (stmt); i++)
+                   disqualify_base_of_expr (gimple_call_arg (stmt, i),
+                                            "Passed to a returns_twice call.");
+               }
+             else
+               for (i = 0; i < gimple_call_num_args (stmt); i++)
+                 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
+                                                stmt, false);
 
              t = gimple_call_lhs (stmt);
              if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
-- 
2.47.0

Reply via email to