From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by sourceware.org (Postfix) with ESMTPS id 2D8B6385801E for ; Tue, 26 Jul 2022 13:42:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2D8B6385801E Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 6A7561FE66 for ; Tue, 26 Jul 2022 13:41:59 +0000 (UTC) Received: from wotan.suse.de (wotan.suse.de [10.160.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 652692C141 for ; Tue, 26 Jul 2022 13:41:59 +0000 (UTC) Date: Tue, 26 Jul 2022 13:41:59 +0000 (UTC) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/2] tree-optimization/105651 - simplify address range overlap check User-Agent: Alpine 2.22 (LSU 394 2020-01-19) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, MISSING_MID, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Tue, 26 Jul 2022 13:42:01 -0000 Message-ID: <20220726134159.PTllyfQb2LUI9AgPeHxlTZhwsR9hdf-IFRuDXZKmRJc@z> The following adds a pattern for ifcombine to match an address overlap check and use alias analysis to decide overlap at compile-time. This happens with code generated from std::string as shown in the PR even if meanwhile the trunk generated code causes the pattern to no longer match. Bootstrapped and tested on x86_64-unknown-linux-gnu. PR tree-optimization/105651 * match.pd: Add pattern optimizing address range overlap. * gcc.dg/tree-ssa/ssa-ifcombine-14.c: New testcase. --- gcc/match.pd | 47 +++++++++++++++++++ .../gcc.dg/tree-ssa/ssa-ifcombine-14.c | 18 +++++++ 2 files changed, 65 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-14.c diff --git a/gcc/match.pd b/gcc/match.pd index 330c1db0c8e..7661317a53f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7806,6 +7806,53 @@ and, { swap_p ? @0 : @2; })) { rhs_tree; }))))))))) +/* Similarly handle + + (uint) @A < (uint) @B + @BO & (uint) @B < (uint) @A + @AO + + in particular optimize the case when @A and @B are within distinct + objects and all addresses are invariant as happens with std::string + in PR105651. */ +(for cmp1 (lt le le lt) + cmp2 (lt le lt le) + (simplify + (bit_and (cmp1:c (convert@4 @0) (convert @1)) + (cmp2:c (convert@5 @2) (convert @3))) + (with + { + tree addr0, addr1, addr2, addr3; + /* Instead of multiple matchings see to extract a base from the + conversion operands since all we need to relate is bases. */ + auto get_addr = [] (tree op) -> tree { + if (TREE_CODE (op) == ADDR_EXPR) + return op; + else if (TREE_CODE (op) == SSA_NAME) + if (gassign *ass = dyn_cast (SSA_NAME_DEF_STMT (op))) + if (gimple_assign_rhs_code (ass) == ADDR_EXPR + || gimple_assign_rhs_code (ass) == POINTER_PLUS_EXPR) + return gimple_assign_rhs1 (ass); + return op; + }; + } + (if ((addr0 = get_addr (@0)) + && (addr1 = get_addr (@1)) + && (addr2 = get_addr (@2)) + && (addr3 = get_addr (@3)) + && INTEGRAL_TYPE_P (TREE_TYPE (@4)) + && types_match (TREE_TYPE (@4), TREE_TYPE (@5))) + (with { poly_int64 diff0, diff1; } + (if (ptr_difference_const (addr3, addr0, &diff0) + && known_ge (diff0, 0) + && ptr_difference_const (addr1, addr2, &diff1) + && known_ge (diff1, 0) + /* Since we are in the end just comparing whether two objects may + overlap via alias analysis it isn't really important to exactly + compute the ranges above. ptr_difference_const mainly determines + there is a common base and the known_ge is testing we are comparing + the proper end points. */ + && !ptr_derefs_may_alias_p (addr0, addr1)) + { constant_boolean_node (false, type); })))))) + /* Fold REDUC (@0 & @1) -> @0[I] & @1[I] if element I is the only nonzero element of @1. */ (for reduc (IFN_REDUC_PLUS IFN_REDUC_IOR IFN_REDUC_XOR) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-14.c new file mode 100644 index 00000000000..f058ac04a36 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-14.c @@ -0,0 +1,18 @@ +/* From PR105651 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +typedef __UINTPTR_TYPE__ uintptr_t; +void init (char *a); +void oops (); +void foo () +{ + char a[16]; + init (a); + char *p = "foo"; + if ((uintptr_t)a < (uintptr_t)&p[4] && (uintptr_t)p < (uintptr_t)&a[16]) + oops (); +} + +/* { dg-final { scan-tree-dump "optimizing two comparisons to 0" "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not "oops" "ifcombine" } } */ -- 2.35.3