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 |
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 --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));