From patchwork Thu Jul 11 13:54:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1130806 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-504930-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Usq/j3fS"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45kyHD02Kbz9sBt for ; Thu, 11 Jul 2019 23:55:03 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=WyO3lD1q+fuJIfp2jP2+WkccCWgIZFgkcCI1rVya1oDNL/OWickfo hpmoNjEKs5RrNvZn+ElMuX+EMo5f2+HZqgGQ3UqPg0P2ZmwWEc+tFQj7x2SPIrs6 W9QTdd3Qlkt5IY8vY/3HLpBvTnOUNEv07Sw9R/sR36XUu0RgzZu7O8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=JY1lSknSfFyjtXHGl4EQUesjiU0=; b=Usq/j3fSUVJlsvY0YfzX AJLGuzBmv9FVnwHLZlyKM/eBxF5ZqlXsjyiob54mWNgrLxmxee4LAq7hVkQgoQgJ rcTz6ftutfdvdqs/HUN7EoeGNTttX2+dXl+8iCfpoWaq6zzby/EEW9RYSsyZr59r /FkBVPncjpCY7UjqybpvPxc= Received: (qmail 110161 invoked by alias); 11 Jul 2019 13:54:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 110126 invoked by uid 89); 11 Jul 2019 13:54:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS autolearn=ham version=3.3.1 spammy=att, 273322, cb, poly_offset_int X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 11 Jul 2019 13:54:54 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 1A989281ECC; Thu, 11 Jul 2019 15:54:45 +0200 (CEST) Date: Thu, 11 Jul 2019 15:54:45 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, rguenther@suse.de, d@dcepelik.cz Subject: Make nonoverlapping_component_refs_since_match_p work with non-trivial MEM_REFs and TMRs Message-ID: <20190711135445.n75ttzdw7mxzba42@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Hi, this patch makes nonoverlapping_component_refs_since_match_p to accept paths with non-trivial MEM_REFs and TMRs assuming that they have same semantics. Bootstrapped/regtested x86_64-linux, OK? Honza * tree-ssa-alias.c (same_tmr_indexing_p): Break out from ... (indirect_refs_may_alias_p): ... here. (nonoverlapping_component_refs_since_match_p): Support also non-trivial mem refs in the access paths. Index: testsuite/gcc.dg/tree-ssa/alias-access-path-9.c =================================================================== --- testsuite/gcc.dg/tree-ssa/alias-access-path-9.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/alias-access-path-9.c (working copy) @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +/* This testcase tests nonoverlapping_component_refs_since_match_p in presence + of non-trivial mem-refs. */ +struct a {int a,b;}; +struct b {struct a a[10];}; +struct c {int c; struct b b;} c, *cptr; + +void +set_a(struct a *a, int p) +{ + a->a=p; +} +void +set_b(struct a *a, int p) +{ + a->b=p; +} +int +get_a(struct a *a) +{ + return a->a; +} + +int +test(int i, int j) +{ + struct b *bptr = &c.b; + set_a (&bptr->a[i], 123); + set_b (&bptr->a[j], 124); + return get_a (&bptr->a[i]); +} + +int +test2(int i, int j) +{ + struct b *bptr = &cptr->b; + set_a (&bptr->a[i], 125); + set_b (&bptr->a[j], 126); + return get_a (&bptr->a[i]); +} +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */ +/* { dg-final { scan-tree-dump-times "return 125" 1 "fre1"} } */ Index: tree-ssa-alias.c =================================================================== --- tree-ssa-alias.c (revision 273322) +++ tree-ssa-alias.c (working copy) @@ -1216,6 +1216,25 @@ nonoverlapping_component_refs_p_1 (const return -1; } +/* Return if TARGET_MEM_REFS base1 and base2 have same offsets. */ + +static bool +same_tmr_indexing_p (tree base1, tree base2) +{ + return ((TMR_STEP (base1) == TMR_STEP (base2) + || (TMR_STEP (base1) && TMR_STEP (base2) + && operand_equal_p (TMR_STEP (base1), + TMR_STEP (base2), 0))) + && (TMR_INDEX (base1) == TMR_INDEX (base2) + || (TMR_INDEX (base1) && TMR_INDEX (base2) + && operand_equal_p (TMR_INDEX (base1), + TMR_INDEX (base2), 0))) + && (TMR_INDEX2 (base1) == TMR_INDEX2 (base2) + || (TMR_INDEX2 (base1) && TMR_INDEX2 (base2) + && operand_equal_p (TMR_INDEX2 (base1), + TMR_INDEX2 (base2), 0)))); +} + /* Try to disambiguate REF1 and REF2 under the assumption that MATCH1 and MATCH2 either point to the same address or are disjoint. MATCH1 and MATCH2 are assumed to be ref in the access path of REF1 and REF2 @@ -1265,20 +1284,6 @@ nonoverlapping_component_refs_since_matc component_refs1.safe_push (ref1); ref1 = TREE_OPERAND (ref1, 0); } - if (TREE_CODE (ref1) == MEM_REF && ref1 != match1) - { - if (!integer_zerop (TREE_OPERAND (ref1, 1))) - { - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; - return -1; - } - } - /* TODO: Handle TARGET_MEM_REF later. */ - if (TREE_CODE (ref1) == TARGET_MEM_REF && ref1 != match1) - { - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; - return -1; - } /* Create the stack of handled components for REF2. */ while (handled_component_p (ref2) && ref2 != match2) @@ -1290,15 +1295,39 @@ nonoverlapping_component_refs_since_matc component_refs2.safe_push (ref2); ref2 = TREE_OPERAND (ref2, 0); } - if (TREE_CODE (ref2) == MEM_REF && ref2 != match2) + + bool mem_ref1 = TREE_CODE (ref1) == MEM_REF && ref1 != match1; + bool mem_ref2 = TREE_CODE (ref2) == MEM_REF && ref2 != match2; + + /* If only one of access path starts with MEM_REF check that offset is 0 + so the addresses stays the same after stripping it. + TODO: In this case we may walk the other access path until we get same + offset. + + If both starts with MEM_REF, offset has to be same. */ + if ((mem_ref1 && !mem_ref2 && !integer_zerop (TREE_OPERAND (ref1, 1))) + || (mem_ref2 && !mem_ref1 && !integer_zerop (TREE_OPERAND (ref2, 1))) + || (mem_ref1 && mem_ref2 + && !tree_int_cst_equal (TREE_OPERAND (ref1, 1), + TREE_OPERAND (ref2, 1)))) { - if (!integer_zerop (TREE_OPERAND (ref2, 1))) - { - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; - return -1; - } + ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; + return -1; } - if (TREE_CODE (ref2) == TARGET_MEM_REF && ref2 != match2) + + bool target_mem_ref1 = TREE_CODE (ref1) == TARGET_MEM_REF && ref1 != match1; + bool target_mem_ref2 = TREE_CODE (ref2) == TARGET_MEM_REF && ref2 != match2; + + if ((target_mem_ref1 && !target_mem_ref2 + && (TMR_INDEX (ref1) || TMR_INDEX2 (ref1) + || !integer_zerop (TREE_OPERAND (ref1, 1)))) + || (target_mem_ref2 && !target_mem_ref1 + && (TMR_INDEX (ref2) || TMR_INDEX2 (ref2) + || !integer_zerop (TREE_OPERAND (ref2, 1)))) + || (target_mem_ref1 && target_mem_ref2 + && (!same_tmr_indexing_p (ref1, ref2) + || !tree_int_cst_equal (TREE_OPERAND (ref1, 1), + TREE_OPERAND (ref2, 1))))) { ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; return -1; @@ -1776,18 +1805,7 @@ indirect_refs_may_alias_p (tree ref1 ATT || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))) || (TREE_CODE (base1) == TARGET_MEM_REF && TREE_CODE (base2) == TARGET_MEM_REF - && (TMR_STEP (base1) == TMR_STEP (base2) - || (TMR_STEP (base1) && TMR_STEP (base2) - && operand_equal_p (TMR_STEP (base1), - TMR_STEP (base2), 0))) - && (TMR_INDEX (base1) == TMR_INDEX (base2) - || (TMR_INDEX (base1) && TMR_INDEX (base2) - && operand_equal_p (TMR_INDEX (base1), - TMR_INDEX (base2), 0))) - && (TMR_INDEX2 (base1) == TMR_INDEX2 (base2) - || (TMR_INDEX2 (base1) && TMR_INDEX2 (base2) - && operand_equal_p (TMR_INDEX2 (base1), - TMR_INDEX2 (base2), 0)))))) + && same_tmr_indexing_p (base1, base2)))) { poly_offset_int moff1 = mem_ref_offset (base1) << LOG2_BITS_PER_UNIT; poly_offset_int moff2 = mem_ref_offset (base2) << LOG2_BITS_PER_UNIT;