From: Andrew Pinski <pinskia@gmail.com>
To: Martin Jambor <mjambor@suse.cz>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
Richard Biener <rguenther@suse.de>, Jan Hubicka <hubicka@ucw.cz>
Subject: Re: [PATCH] tree-sra: Avoid returns of references to SRA candidates
Date: Mon, 27 Nov 2023 10:20:03 -0800 [thread overview]
Message-ID: <CA+=Sn1=dBtv0PorQut_7nLvVFGQ-L6R8Lmv_-3uT9wrWj1z-ZQ@mail.gmail.com> (raw)
In-Reply-To: <6564dd10.050a0220.70a2b.e9d6SMTPIN_ADDED_BROKEN@mx.google.com>
On Mon, Nov 27, 2023 at 10:16 AM Martin Jambor <mjambor@suse.cz> wrote:
>
> Hi,
>
> The enhancement to address PR 109849 contained an importsnt thinko,
> and that any reference that is passed to a function and does not
> escape, must also not happen to be aliased by the return value of the
> function. This has quickly transpired as bugs PR 112711 and PR
> 112721.
>
> Just as IPA-modref does a good enough job to allow us to rely on the
> escaped set of variables, it sems to be doing well also on updating
> EAF_NOT_RETURNED_DIRECTLY call argument flag which happens to address
> exactly the situation we need to avoid. Of course, if a call
> statement ignores any returned value, we also do not need to check the
> flag.
>
> Hopefully this does not pessimize things too much, I have verified
> that the PR 109849 testcae remains quick and so should also the
> benchmark it is derived from.
>
> The patch has passed bootstrap and testing on x86_64-linux, OK for
> master?
>
> Thanks,
>
> Martin
>
>
> gcc/ChangeLog:
>
> 2023-11-27 Martin Jambor <mjambor@suse.cz>
>
> PR tree-optimization/112711
> PR tree-optimization/112721
> * tree-sra.cc (build_access_from_call_arg): New parameter
> CAN_BE_RETURNED, disqualify any candidate passed by reference if it is
> true. Adjust leading comment.
> (scan_function): Pass appropriate value to CAN_BE_RETURNED of
> build_access_from_call_arg.
>
> gcc/testsuite/ChangeLog:
>
> 2023-11-27 Martin Jambor <mjambor@suse.cz>
>
> PR tree-optimization/112711
> PR tree-optimization/112721
> * g++.dg/tree-ssa/pr112711.C: New test.
> * gcc.dg/tree-ssa/pr112721.c: Likewise.
> ---
> gcc/testsuite/g++.dg/tree-ssa/pr112711.C | 31 ++++++++++++++++++
> gcc/testsuite/gcc.dg/tree-ssa/pr112721.c | 26 +++++++++++++++
> gcc/tree-sra.cc | 40 ++++++++++++++++++------
> 3 files changed, 88 insertions(+), 9 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr112711.C
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr112721.c
>
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr112711.C b/gcc/testsuite/g++.dg/tree-ssa/pr112711.C
> new file mode 100644
> index 00000000000..c04524b04a7
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/pr112711.C
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +
> +typedef int i32;
> +typedef unsigned int u32;
> +
> +static inline void write_i32(void *memory, i32 value) {
> + // swap i32 bytes as if it was u32:
> + u32 u_value = value;
> + value = __builtin_bswap32(u_value);
> +
> + // llvm infers '1' alignment from destination type
> + __builtin_memcpy(__builtin_assume_aligned(memory, 1), &value, sizeof(value));
> +}
> +
> +__attribute__((noipa))
> +static void bug (void) {
> + #define assert_eq(lhs, rhs) if (lhs != rhs) __builtin_trap()
> +
> + unsigned char data[5];
> + write_i32(data, -1362446643);
> + assert_eq(data[0], 0xAE);
> + assert_eq(data[1], 0xCA);
> + write_i32(data + 1, -1362446643);
> + assert_eq(data[1], 0xAE);
> +}
Only a comment on this testcase, it is only valid for little-endian
and 32bit int targets.
You can modify it to fix it for both though.
Thanks,
Andrew
> +
> +int main() {
> + bug();
> + return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr112721.c b/gcc/testsuite/gcc.dg/tree-ssa/pr112721.c
> new file mode 100644
> index 00000000000..adf62613266
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112721.c
> @@ -0,0 +1,26 @@
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +
> +unsigned * volatile gv;
> +
> +struct a {
> + int b;
> +};
> +int c, e;
> +long d;
> +unsigned * __attribute__((noinline))
> +f(unsigned *g) {
> + for (; c;)
> + e = d;
> + return gv ? gv : g;
> +}
> +int main() {
> + int *h;
> + struct a i = {8};
> + int *j = &i.b;
> + h = (unsigned *) f(j);
> + *h = 0;
> + if (i.b != 0)
> + __builtin_abort ();
> + return 0;
> +}
> diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
> index 3a0d52675fe..6a759783990 100644
> --- a/gcc/tree-sra.cc
> +++ b/gcc/tree-sra.cc
> @@ -1268,18 +1268,27 @@ abnormal_edge_after_stmt_p (gimple *stmt, enum out_edge_check *oe_check)
> }
>
> /* Scan expression EXPR which is an argument of a call and create access
> - structures for all accesses to candidates for scalarization. Return true if
> - any access has been inserted. STMT must be the statement from which the
> - expression is taken. */
> + structures for all accesses to candidates for scalarization. Return true
> + if any access has been inserted. STMT must be the statement from which the
> + expression is taken. CAN_BE_RETURNED must be true if call argument flags
> + do not rule out that the argument is directly returned. OE_CHECK is used
> + to remember result of a test for abnormal outgoing edges after this
> + statement. */
>
> static bool
> -build_access_from_call_arg (tree expr, gimple *stmt,
> +build_access_from_call_arg (tree expr, gimple *stmt, bool can_be_returned,
> enum out_edge_check *oe_check)
> {
> if (TREE_CODE (expr) == ADDR_EXPR)
> {
> tree base = get_base_address (TREE_OPERAND (expr, 0));
>
> + if (can_be_returned)
> + {
> + disqualify_base_of_expr (base, "Address possibly returned, "
> + "leading to an alis SRA may not know.");
> + return false;
> + }
> if (abnormal_edge_after_stmt_p (stmt, oe_check))
> {
> disqualify_base_of_expr (base, "May lead to need to add statements "
> @@ -1508,12 +1517,25 @@ scan_function (void)
> case GIMPLE_CALL:
> {
> enum out_edge_check oe_check = SRA_OUTGOING_EDGES_UNCHECKED;
> - for (i = 0; i < gimple_call_num_args (stmt); i++)
> - ret |= build_access_from_call_arg (gimple_call_arg (stmt, i),
> - stmt, &oe_check);
> + gcall *call = as_a <gcall *> (stmt);
> + for (i = 0; i < gimple_call_num_args (call); i++)
> + {
> + bool can_be_returned;
> + if (gimple_call_lhs (call))
> + {
> + int af = gimple_call_arg_flags (call, i);
> + can_be_returned = !(af & EAF_NOT_RETURNED_DIRECTLY);
> + }
> + else
> + can_be_returned = false;
> + ret |= build_access_from_call_arg (gimple_call_arg (call,
> + i),
> + stmt, can_be_returned,
> + &oe_check);
> + }
> if (gimple_call_chain(stmt))
> - ret |= build_access_from_call_arg (gimple_call_chain(stmt),
> - stmt, &oe_check);
> + ret |= build_access_from_call_arg (gimple_call_chain(call),
> + stmt, false, &oe_check);
> }
>
> t = gimple_call_lhs (stmt);
> --
> 2.43.0
>
next parent reply other threads:[~2023-11-27 18:20 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <6564dd10.050a0220.70a2b.e9d6SMTPIN_ADDED_BROKEN@mx.google.com>
2023-11-27 18:20 ` Andrew Pinski [this message]
2023-11-27 18:16 Martin Jambor
2023-11-28 8:05 ` Richard Biener
2023-11-28 16:16 ` Martin Jambor
2023-11-28 16:33 ` Richard Biener
2023-11-28 16:59 ` Jan Hubicka
2023-11-28 17:30 ` Richard Biener
2023-11-28 17:38 ` Jan Hubicka
2023-11-28 18:35 ` Richard Biener
2023-11-29 12:04 ` Martin Jambor
2023-11-29 12:18 ` Jan Hubicka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CA+=Sn1=dBtv0PorQut_7nLvVFGQ-L6R8Lmv_-3uT9wrWj1z-ZQ@mail.gmail.com' \
--to=pinskia@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=mjambor@suse.cz \
--cc=rguenther@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).