diff mbox series

tree-sra: Avoid SRAing arguments to a function returning_twice (PR 117142)

Message ID ri6ttd4qunp.fsf@virgil.suse.cz
State New
Headers show
Series tree-sra: Avoid SRAing arguments to a function returning_twice (PR 117142) | expand

Commit Message

Martin Jambor Oct. 22, 2024, 10:49 a.m. UTC
Hi,

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.

Bootstrapped and tested on x86_64-linux. OK for master and all active
release branches (though for gcc 13 and 12 the condition will probable
be elsewhere, IIRC)?

Thanks,

Martin


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.
---
 gcc/testsuite/gcc.dg/tree-ssa/pr117142.c | 14 ++++++++++++++
 gcc/tree-sra.cc                          |  9 +++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117142.c

Comments

Richard Biener Oct. 22, 2024, 11:14 a.m. UTC | #1
On Tue, 22 Oct 2024, Martin Jambor wrote:

> Hi,
> 
> 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.
> 
> Bootstrapped and tested on x86_64-linux. OK for master and all active
> release branches (though for gcc 13 and 12 the condition will probable
> be elsewhere, IIRC)?

OK.

Richard.

> Thanks,
> 
> Martin
> 
> 
> 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.
> ---
>  gcc/testsuite/gcc.dg/tree-ssa/pr117142.c | 14 ++++++++++++++
>  gcc/tree-sra.cc                          |  9 +++++++++
>  2 files changed, 23 insertions(+)
>  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 64e2f007d68..c0915dce5c4 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));
>
diff mbox series

Patch

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 64e2f007d68..c0915dce5c4 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));