From patchwork Fri Oct 15 09:12:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 46265 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7E3E73857C6C for ; Fri, 15 Oct 2021 09:15:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7E3E73857C6C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1634289305; bh=w243ImSQ/vivpFUdBbqi2qLlOQWLZhLJvJ07uouA5uk=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=AyC6Ma7/Te4X+7eQbuNf9MedCfHOOYAolTyokGSjjmjPL8ZkJOsELkf59/lyZYdgI YB/d4FSBTsCpg+2Ff0pVGwQodXNPw1lHf8zWnIN3c6E7m/n9Ne1omC2XWG32+xu7Lt QmIWWWYoXtkLdBAVLI9ep+TrSpRaNBpe+9H5IqYY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id 7ACD23858005 for ; Fri, 15 Oct 2021 09:14:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7ACD23858005 Received: by mail-wm1-x333.google.com with SMTP id z77-20020a1c7e50000000b0030db7b70b6bso2315164wmc.1 for ; Fri, 15 Oct 2021 02:14:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=w243ImSQ/vivpFUdBbqi2qLlOQWLZhLJvJ07uouA5uk=; b=sMn4uvGZPVzwD5wxV6amSbLgF5EgCClF9rCvQfiSEqgo6d+qpFWo7JeWv7VbG1frM4 DNjCexodgvUB4t81iTaDQXaS4C8dudzz8MN/rWH6tBVZWdKk3zJM5w43YtDyyYVK32Fb VrVJ7MWXLZdAGPDBWSLpfts94h8QShC689jSzw+IEIBtfn55/5q4q1XZdOUFI6HHOtjb 6rgPq+M7JWJ1lXxvFqAl4e8hOqSkfJsCVF2juWAGM3lCrhVVc5v1K1MypeyfyReI82HZ Xd2lShnjDFmFZ7M1HgsbPY+55U+qP9buGCtDe48YCgOEO94mvdXs7PWxWHIHTP+mWQpl 4eJA== X-Gm-Message-State: AOAM533nXfqVgprjXeJXapUC700y2HciwDy9AM55PQegBAgCbeVmziVv qGJSXVquzOlaWl4IXomZ/I9CQe+m/HA9qg== X-Google-Smtp-Source: ABdhPJwIKKUE9sEwbenohDJcwSwgWAWCPZGfGg9U6FitkQsNsAJx2NMxgpEIk9rajdiboD0AHFpjXA== X-Received: by 2002:a05:600c:ac1:: with SMTP id c1mr11144598wmr.99.1634289274429; Fri, 15 Oct 2021 02:14:34 -0700 (PDT) Received: from fomalhaut.localnet ([2a01:e0a:41b:84f0:cf71:f5e0:b050:bede]) by smtp.gmail.com with ESMTPSA id f3sm4025190wml.11.2021.10.15.02.14.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Oct 2021 02:14:33 -0700 (PDT) X-Google-Original-From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Tame if-combining when loop unswitching is enabled Date: Fri, 15 Oct 2021 11:12:22 +0200 Message-ID: <2796861.e9J7NaK4W3@fomalhaut> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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-Patchwork-Original-From: Eric Botcazou via Gcc-patches From: Eric Botcazou Reply-To: Eric Botcazou Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, in order to make it possible to vectorize loops running over arrays in Ada, which generally contain index checks, hence control-flow instructions, we rely on loop unswitching to generate two copies of the loop, one guarded with a global condition (no index check fails in the loop) and vectorizable and one with the original index checks and non-vectorizable. This is achieved by the simple trick of prepending the global_condition to the condition of the index checks and letting the loop unswitching pass do its magic. But there is an enemy, namely if-combining, which can turn a simple boolean conjunction into something else that loop unswitching cannot deal with, and a testcase is attached with 3 slightly different versions of the same issue. Therefore the attached patch attempts to tame if-combining by reasoning on the loop invariant status (really loop depths) of the conditions. Bootstrapped/regtested on x86-64/Linux, OK for the mainline? 2021-10-15 Eric Botcazou * tree-ssa-ifcombine.c: Include cfgloop.h. (operand_loop_depth): New function. (ifcombine_ifandif): When loop unswitching is enabled, do not merge conditions whose loop invariant status is different. 2021-10-15 Eric Botcazou * gnat.dg/vect19.ads, gnat.dg/vect19.adb: New test. diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index f93e04aa4df..986084049da 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see BRANCH_COST. */ #include "fold-const.h" #include "cfganal.h" +#include "cfgloop.h" #include "gimple-fold.h" #include "gimple-iterator.h" #include "gimplify-me.h" @@ -378,6 +379,19 @@ update_profile_after_ifcombine (basic_block inner_cond_bb, outer2->probability = profile_probability::never (); } +/* Return the loop depth of GIMPLE operand OP. */ + +static int +operand_loop_depth (tree op) +{ + basic_block bb; + + if (TREE_CODE (op) == SSA_NAME && (bb = gimple_bb (SSA_NAME_DEF_STMT (op)))) + return bb_loop_depth (bb); + + return 0; +} + /* If-convert on a and pattern with a common else block. The inner if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB. inner_inv, outer_inv and result_inv indicate whether the conditions @@ -554,6 +568,22 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, HONOR_NANS (gimple_cond_lhs (outer_cond))); if (outer_cond_code == ERROR_MARK) return false; + /* Do not merge if the loop invariant status of the conditions is not + the same and we'll be unswitching loops downstream. */ + if (flag_unswitch_loops) + { + const int current_depth + = MIN (bb_loop_depth (inner_cond_bb), + bb_loop_depth (outer_cond_bb)); + const int inner_depth + = MAX (operand_loop_depth (gimple_cond_lhs (inner_cond)), + operand_loop_depth (gimple_cond_rhs (inner_cond))); + const int outer_depth + = MAX (operand_loop_depth (gimple_cond_lhs (outer_cond)), + operand_loop_depth (gimple_cond_rhs (outer_cond))); + if ((inner_depth < current_depth) != (outer_depth < current_depth)) + return false; + } /* Don't return false so fast, try maybe_fold_or_comparisons? */ if (!(t = maybe_fold_and_comparisons (boolean_type_node, inner_cond_code,