From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id ACF6C3858C3A for ; Wed, 13 Oct 2021 09:26:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org ACF6C3858C3A Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 7525E20114 for ; Wed, 13 Oct 2021 09:26:06 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5509613CD1 for ; Wed, 13 Oct 2021 09:26:06 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id bbSqEy6mZmGPLAAAMHmgww (envelope-from ) for ; Wed, 13 Oct 2021 09:26:06 +0000 Date: Wed, 13 Oct 2021 11:26:06 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] ipa/102714 - IPA SRA eliding volatile Message-ID: <46ssn392-nn9-9359-329-4p3sr118rs7r@fhfr.qr> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Oct 2021 09:26:09 -0000 The following fixes the volatileness check of IPA SRA which was looking at the innermost reference when checking TREE_THIS_VOLATILE but the reference to check is the outermost one. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. 2021-10-13 Richard Biener PR ipa/102714 * ipa-sra.c (ptr_parm_has_nonarg_uses): Fix volatileness check. * gcc.dg/ipa/pr102714.c: New testcase. --- gcc/ipa-sra.c | 40 +++++----- gcc/testsuite/gcc.dg/ipa/pr102714.c | 117 ++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr102714.c diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c index 965e246d788..88036590425 100644 --- a/gcc/ipa-sra.c +++ b/gcc/ipa-sra.c @@ -1005,15 +1005,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm, if (gimple_assign_single_p (stmt)) { tree rhs = gimple_assign_rhs1 (stmt); - while (handled_component_p (rhs)) - rhs = TREE_OPERAND (rhs, 0); - if (TREE_CODE (rhs) == MEM_REF - && TREE_OPERAND (rhs, 0) == name - && integer_zerop (TREE_OPERAND (rhs, 1)) - && types_compatible_p (TREE_TYPE (rhs), - TREE_TYPE (TREE_TYPE (name))) - && !TREE_THIS_VOLATILE (rhs)) - uses_ok++; + if (!TREE_THIS_VOLATILE (rhs)) + { + while (handled_component_p (rhs)) + rhs = TREE_OPERAND (rhs, 0); + if (TREE_CODE (rhs) == MEM_REF + && TREE_OPERAND (rhs, 0) == name + && integer_zerop (TREE_OPERAND (rhs, 1)) + && types_compatible_p (TREE_TYPE (rhs), + TREE_TYPE (TREE_TYPE (name)))) + uses_ok++; + } } else if (is_gimple_call (stmt)) { @@ -1047,15 +1049,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm, continue; } - while (handled_component_p (arg)) - arg = TREE_OPERAND (arg, 0); - if (TREE_CODE (arg) == MEM_REF - && TREE_OPERAND (arg, 0) == name - && integer_zerop (TREE_OPERAND (arg, 1)) - && types_compatible_p (TREE_TYPE (arg), - TREE_TYPE (TREE_TYPE (name))) - && !TREE_THIS_VOLATILE (arg)) - uses_ok++; + if (!TREE_THIS_VOLATILE (arg)) + { + while (handled_component_p (arg)) + arg = TREE_OPERAND (arg, 0); + if (TREE_CODE (arg) == MEM_REF + && TREE_OPERAND (arg, 0) == name + && integer_zerop (TREE_OPERAND (arg, 1)) + && types_compatible_p (TREE_TYPE (arg), + TREE_TYPE (TREE_TYPE (name)))) + uses_ok++; + } } } diff --git a/gcc/testsuite/gcc.dg/ipa/pr102714.c b/gcc/testsuite/gcc.dg/ipa/pr102714.c new file mode 100644 index 00000000000..65dd86f5c15 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr102714.c @@ -0,0 +1,117 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */ + +typedef _Bool bool; + +enum { + false = 0, + true = 1 +}; + +struct xarray { + unsigned int xa_lock; + unsigned int xa_flags; + void * xa_head; + +}; + +struct list_head { + struct list_head *next, *prev; +}; + +struct callback_head { + struct callback_head *next; + void (*func)(struct callback_head *head); +} __attribute__((aligned(sizeof(void *)))); + +struct xa_node { + unsigned char shift; + unsigned char offset; + unsigned char count; + unsigned char nr_values; + struct xa_node *parent; + struct xarray *array; + union { + struct list_head private_list; + struct callback_head callback_head; + }; + void *slots[(1UL << (0 ? 4 : 6))]; + union { + unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))]; + unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))]; + }; +}; + +static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift) +{ + return ((1UL << (0 ? 4 : 6)) << shift) - 1; +} + +static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node) +{ + return shift_maxindex(node->shift); +} + +static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr) +{ + return (void *)((unsigned long)ptr & ~2UL); +} + +static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr) +{ + return ((unsigned long)ptr & 3UL) == + 2UL; +} + +static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long v) +{ + return (void *)((v << 2) | 2); +} + +static unsigned radix_tree_load_root(const struct xarray *root, + struct xa_node **nodep, unsigned long *maxindex) +{ + struct xa_node *node = + ({ + typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); }); + ((typeof(*root->xa_head) *)(________p1)); + }); + + *nodep = node; + + if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) { + node = entry_to_node(node); + *maxindex = node_maxindex(node); + return node->shift + (0 ? 4 : 6); + } + + *maxindex = 0; + return 0; +} + +void *__radix_tree_lookup(const struct xarray *root, + unsigned long index, struct xa_node **nodep, + void ***slotp) +{ + struct xa_node *node, *parent; + unsigned long maxindex; + + restart: + parent = ((void *)0); + radix_tree_load_root(root, &node, &maxindex); + while (radix_tree_is_internal_node(node)) { + + parent = entry_to_node(node); + if (node == xa_mk_internal(256)) + goto restart; + if (parent->shift == 0) + break; + } + if (nodep) + *nodep = parent; + + return node; +} + +/* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */ +/* { dg-final { scan-tree-dump " ={v} " "optimized" } } */ -- 2.31.1