From patchwork Fri Jul 28 06:37:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1814090 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=EQuEH8g0; dkim-atps=neutral Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RBycY54vMz1yYD for ; Fri, 28 Jul 2023 16:37:48 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3431F385AFB9 for ; Fri, 28 Jul 2023 06:37:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3431F385AFB9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1690526266; bh=u8Mfd3y8BeA97Kscce5cGwn6LJ1Ywidy7+wvvmCwFXY=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=EQuEH8g0xNFhZ0Uhhrkbs8sdRXhUmp+JgJXvb2PDRYP8poF7jDQbaIaYiULKrIhOn 4jaoJXItjXlLkx5+TDOyFJqPfHsGQ2knWvE4GKn/U5pIqWYO2Lh49Le1Q6dzTOVoKp Hup9NvRia0St2GFPiHfdZg865Yq/7UqUcE4v9VY8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 9609C3858D37 for ; Fri, 28 Jul 2023 06:37:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9609C3858D37 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 929B12828D8; Fri, 28 Jul 2023 08:37:22 +0200 (CEST) Date: Fri, 28 Jul 2023 08:37:22 +0200 To: gcc-patches@gcc.gnu.org Subject: loop-split improvements, part 1 Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, JMQ_SPF_NEUTRAL, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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-Patchwork-Original-From: Jan Hubicka via Gcc-patches From: Jan Hubicka Reply-To: Jan Hubicka Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi, while looking on profile misupdate on hmmer I noticed that loop splitting pass is not able to handle the loop it has as an example it should apply on: One transformation of loops like: for (i = 0; i < 100; i++) { if (i < 50) A; else B; } into: for (i = 0; i < 50; i++) { A; } for (; i < 100; i++) { B; } The problem is that ivcanon turns the test into i != 100 and the pass explicitly gives up on any loops ending with != test. It needs to know the directoin of the induction variable in order to derive right conditions, but that can be done also from step. It turns out that there are no testcases for basic loop splitting. I will add some with the profile update fix. There are other issues, like VRP will turn i < 99 into i == 99 based on value range which also makes the pass to give up. Bootstrapped/regtested x86_64-linux, OK? gcc/ChangeLog: * tree-ssa-loop-split.cc (split_loop): Also support NE driven loops when IV test is not overflowing. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/ifc-12.c: Disable loop splitting. * gcc.target/i386/avx2-gather-6.c: Likewise. * gcc.target/i386/avx2-vect-aggressive.c: Likewise. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c index 9468c070489..bedf29c7dbc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Ofast -fdump-tree-ifcvt-stats-blocks-details" } */ +/* { dg-options "-Ofast -fdump-tree-ifcvt-stats-blocks-details -fno-split-loops" } */ /* { dg-require-visibility "" } */ struct st diff --git a/gcc/testsuite/gcc.target/i386/avx2-gather-6.c b/gcc/testsuite/gcc.target/i386/avx2-gather-6.c index b9119581ae2..47a95dbe989 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-gather-6.c +++ b/gcc/testsuite/gcc.target/i386/avx2-gather-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -mavx2 -fno-common -fdump-tree-vect-details -mtune=skylake" } */ +/* { dg-options "-O3 -mavx2 -fno-common -fdump-tree-vect-details -mtune=skylake -fno-split-loops" } */ #include "avx2-gather-5.c" diff --git a/gcc/testsuite/gcc.target/i386/avx2-vect-aggressive.c b/gcc/testsuite/gcc.target/i386/avx2-vect-aggressive.c index 57192791857..fa336e70e84 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-vect-aggressive.c +++ b/gcc/testsuite/gcc.target/i386/avx2-vect-aggressive.c @@ -1,6 +1,6 @@ /* { dg-do run } */ /* { dg-require-effective-target avx2 } */ -/* { dg-options "-mavx2 -O3 -fopenmp-simd -fdump-tree-vect-details -fdisable-tree-thread1" } */ +/* { dg-options "-mavx2 -O3 -fopenmp-simd -fdump-tree-vect-details -fdisable-tree-thread1 -fno-split-loops" } */ #include "avx2-check.h" #define N 64 diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc index b41b5e614c2..27780370d85 100644 --- a/gcc/tree-ssa-loop-split.cc +++ b/gcc/tree-ssa-loop-split.cc @@ -540,10 +545,17 @@ split_loop (class loop *loop1) || !empty_block_p (loop1->latch) || !easy_exit_values (loop1) || !number_of_iterations_exit (loop1, exit1, &niter, false, true) - || niter.cmp == ERROR_MARK - /* We can't yet handle loops controlled by a != predicate. */ - || niter.cmp == NE_EXPR) + || niter.cmp == ERROR_MARK) return false; + if (niter.cmp == NE_EXPR) + { + if (!niter.control.no_overflow) + return false; + if (tree_int_cst_sign_bit (niter.control.step) > 0) + niter.cmp = GT_EXPR; + else + niter.cmp = LT_EXPR; + } bbs = get_loop_body (loop1);