From patchwork Fri Dec 7 17:01:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 1009568 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-491916-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="OuKYZla0"; 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 43BJfp0XWxz9sMp for ; Sat, 8 Dec 2018 04:02:09 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:message-id:date:mime-version:content-type; q=dns; s= default; b=uR360HRjALkf3bjJj66b2p1sH4+onylyJBK8H9glc3DtDpvdtzRq4 p6qnqW6Lc4xEdssxXLm5YtSiwxl0i6p5x+VO274g+YdOmTe/Ch5E/iJL49NglYyN RmyYjI+4HcngmSCVjkKE8naF06Pa69bNT9t8wfsWOevpuS5lN7gDCM= 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:from :to:subject:message-id:date:mime-version:content-type; s= default; bh=b9cEMcdncceb2wq4gAco3zb8jvs=; b=OuKYZla0rpXQUbXwLqxd wPK0rxhgeaJhNgRGPunQg8m5y7/gze5VXpqAjDjF1B9Vp6Bcr6yRV7o2GhMwmzS1 GO7RovGB4cjDHFi4ceulGT4uOIg90NqxtqmjIXoc/FEy6UGu6sjRI+DbBI9W/EVp sHTRznwxhiuR/9Myj+gUBKA= Received: (qmail 29255 invoked by alias); 7 Dec 2018 17:02:02 -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 28966 invoked by uid 89); 7 Dec 2018 17:01:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=reflects, evrp, FINAL, dom X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 07 Dec 2018 17:01:48 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A923430BCCFE for ; Fri, 7 Dec 2018 17:01:46 +0000 (UTC) Received: from localhost.localdomain (ovpn-112-17.rdu2.redhat.com [10.10.112.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0127D5DD61 for ; Fri, 7 Dec 2018 17:01:45 +0000 (UTC) From: Jeff Law Openpgp: preference=signencrypt To: gcc-patches Subject: [committed] [PR middle-end/87813] EVRP vs global range data for warning passes Message-ID: <5d9fd28e-5606-c7e0-a2b9-d5bfd3bb38d8@redhat.com> Date: Fri, 7 Dec 2018 10:01:44 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0 MIME-Version: 1.0 X-IsSubscribed: yes So as discussed in BZ87813, the evrp range analyzer currently reflects any globally valid ranges it finds into the global range information we attach to SSA_NAMEs. That is usually a good thing, except when the analyzer is called from a warning pass. Enabling/disabling of warnings should not affect code generation. This patch allows clients to indicate if they want the range analyzer to reflect globally discovered ranges into the SSA_NAME. The optimization passes obviously want that behavior. The sprintf warning pass does not. As expected, it was just a matter of adding a flag to the class and testing it in a few places. There was a solitary test, identified in the BZ, that turned out to be problematical. builtins/strnlen.c at -Og was relying on the range analyzer instance in the sprintf warning pass to set a global range. That in turn allowed the call to strnlen to be eliminated. With this patch that no longer occurs and we call strnlen. strnlen in this test is actually wrapped so that it aborts if OPTIMIZE is defined. I didn't see any reasonable way to preserve the optimization at -Og given we don't run VRP, DOM, EVRP, etc. So I've just added a strnlen.x file to filter out the -Og run of the strnlen test. Bootstrapped and regression tested on x86_64-linux-gnu. Installing on the trunk momentarily. jeff * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Add m_update_global_ranges member. Add corresponding argument to ctor. * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer): Add new argument and initialize m_update_global_ranges. (evrp_range_analyzer::set_ssa_range_info): Assert that we are updating global ranges. (evrp_range_analyzer::record_ranges_from_incoming_edge): Only update global ranges if explicitly requested. (evrp_range_analyzer::record_ranges_from_phis): Similarly. (evrp_range_analyzer::record_ranges_from_stmt): Similarly. * gimple-ssa-evrp.c (evrp_dom_walker): Pass new argument to evrp_range_analyzer ctor. * gimple-ssa-sprintf.c (sprintf_dom_walker): Similarly. * tree-ssa-dom.c (dom_opt_dom_walker): Similarly. * gcc.c-torture/builtins/strnlen.x: New file to filter -Og from options to test. diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index 220dde093b5..3efaca1a994 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -42,7 +42,8 @@ along with GCC; see the file COPYING3. If not see #include "vr-values.h" #include "gimple-ssa-evrp-analyze.h" -evrp_range_analyzer::evrp_range_analyzer () : stack (10) +evrp_range_analyzer::evrp_range_analyzer (bool update_global_ranges) + : stack (10), m_update_global_ranges (update_global_ranges) { edge e; edge_iterator ei; @@ -107,6 +108,8 @@ evrp_range_analyzer::try_find_new_range (tree name, void evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range *vr) { + gcc_assert (m_update_global_ranges); + /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) { @@ -213,6 +216,7 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb) continue; push_value_range (vrs[i].first, vrs[i].second); if (is_fallthru + && m_update_global_ranges && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt)) { set_ssa_range_info (vrs[i].first, vrs[i].second); @@ -267,7 +271,8 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) vr_values->update_value_range (lhs, &vr_result); /* Set the SSA with the value range. */ - set_ssa_range_info (lhs, &vr_result); + if (m_update_global_ranges) + set_ssa_range_info (lhs, &vr_result); } } @@ -309,7 +314,8 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) /* Case one. We can just update the underlying range information as well as the global information. */ vr_values->update_value_range (output, &vr); - set_ssa_range_info (output, &vr); + if (m_update_global_ranges) + set_ssa_range_info (output, &vr); } else { diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h index 0d2b4188b8c..01942f06362 100644 --- a/gcc/gimple-ssa-evrp-analyze.h +++ b/gcc/gimple-ssa-evrp-analyze.h @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see class evrp_range_analyzer { public: - evrp_range_analyzer (void); + evrp_range_analyzer (bool update_global_ranges); ~evrp_range_analyzer (void) { delete vr_values; @@ -70,6 +70,9 @@ class evrp_range_analyzer /* STACK holds the old VR. */ auto_vec > stack; + + /* True if we are updating global ranges, false otherwise. */ + bool m_update_global_ranges; }; #endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */ diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index deb45cdb9f6..9900980aecf 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -70,6 +70,7 @@ class evrp_dom_walker : public dom_walker public: evrp_dom_walker () : dom_walker (CDI_DOMINATORS), + evrp_range_analyzer (true), evrp_folder (evrp_range_analyzer.get_vr_values ()) { need_eh_cleanup = BITMAP_ALLOC (NULL); diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 456a7d40011..00485d9a073 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -121,7 +121,9 @@ struct format_result; class sprintf_dom_walker : public dom_walker { public: - sprintf_dom_walker () : dom_walker (CDI_DOMINATORS) {} + sprintf_dom_walker () + : dom_walker (CDI_DOMINATORS), + evrp_range_analyzer (false) {} ~sprintf_dom_walker () {} edge before_dom_children (basic_block) FINAL OVERRIDE; diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/strnlen.x b/gcc/testsuite/gcc.c-torture/execute/builtins/strnlen.x new file mode 100644 index 00000000000..9ee8a52baab --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/builtins/strnlen.x @@ -0,0 +1,14 @@ +# At -Og no pass records the global range information +# necessary to optimize the strnlen calls down to +# a constant. The framework assumes that the test +# will never call strnlen when the optimizer is +# enabled. So we filter out the -Og run here. + +set torture_eval_before_compile { + if {[string match {*-Og*} "$option"]} { + continue + } +} + +return 0 + diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index ce840488403..e3e009a0e63 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -578,6 +578,7 @@ public: : dom_walker (direction, REACHABLE_BLOCKS), m_const_and_copies (const_and_copies), m_avail_exprs_stack (avail_exprs_stack), + evrp_range_analyzer (true), m_dummy_cond (dummy_cond) { } virtual edge before_dom_children (basic_block);