aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2024-10-23 11:30:32 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2024-10-23 11:35:56 +0200
commit29d8f1f0b7ad3c69b3bdb130325300d5f73aa784 (patch)
treec365fcb0c8137f0c2a3cf850f8d4d0291ba45e04 /gcc
parent89c92804ea307ec807cc74c1cff4d3503452587a (diff)
downloadgcc-29d8f1f0b7ad3c69b3bdb130325300d5f73aa784.zip
gcc-29d8f1f0b7ad3c69b3bdb130325300d5f73aa784.tar.gz
gcc-29d8f1f0b7ad3c69b3bdb130325300d5f73aa784.tar.bz2
tree-sra: Avoid SRAing arguments to a function returning_twice (PR 117142)
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. gcc/ChangeLog: 2024-10-21 Martin Jambor <mjambor@suse.cz> PR tree-optimization/117142 * tree-sra.cc (build_access_from_call_arg): Disqualify any candidate passed to a function returning twice. gcc/testsuite/ChangeLog: 2024-10-21 Martin Jambor <mjambor@suse.cz> PR tree-optimization/117142 * gcc.dg/tree-ssa/pr117142.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr117142.c14
-rw-r--r--gcc/tree-sra.cc9
2 files changed, 23 insertions, 0 deletions
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 0000000..fc62c1e
--- /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 64e2f00..c0915dc 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -1397,6 +1397,15 @@ static bool
build_access_from_call_arg (tree expr, gimple *stmt, bool can_be_returned,
enum out_edge_check *oe_check)
{
+ if (gimple_call_flags (stmt) & ECF_RETURNS_TWICE)
+ {
+ tree base = expr;
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ base = get_base_address (TREE_OPERAND (expr, 0));
+ disqualify_base_of_expr (base, "Passed to a returns_twice call.");
+ return false;
+ }
+
if (TREE_CODE (expr) == ADDR_EXPR)
{
tree base = get_base_address (TREE_OPERAND (expr, 0));