From patchwork Thu Jan 31 07:39:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1033968 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-495000-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="QIdvCUwm"; 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 43qsb164Pmz9sDX for ; Thu, 31 Jan 2019 18:40:12 +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 :subject:to:cc:message-id:date:mime-version:content-type; q=dns; s=default; b=TNzlT6tFnIYMb9vmJhsmOc5Y1vUVjueZeySVBnbsCefKwbANik cjM3vRvAsQ6e//8lYkdpRuqN3sxIT8c24hUgXamQ8HxTjIuZz/AVI2FTKMLz8KIm NUVYKK4tlQE0q80e9qbkWG+GxqU/YUU5zYCp398I+QAMohdmNISPvq94k= 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 :subject:to:cc:message-id:date:mime-version:content-type; s= default; bh=AyHqczvl2lh+FbFhL1HLRgfV/es=; b=QIdvCUwm7lyo5EJ1XFRQ BpVUnaZz2OKlMBgMKEfZV/BdsW1//joJp8O1xXFcEUTyFnx2E9dZRWW0fKD07M9s 1Ax3xA0CoBMB/DHBBbVMRqyjE7lgTJ2aRgKMAAG4xtk+PAvlojmgXc4WQDT56FV2 NXzqCpIAJm0eCydvA2RSV5M= Received: (qmail 114444 invoked by alias); 31 Jan 2019 07:40:05 -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 114427 invoked by uid 89); 31 Jan 2019 07:40:04 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=forwarder, gate, lean, liberty X-HELO: mail-wr1-f47.google.com Received: from mail-wr1-f47.google.com (HELO mail-wr1-f47.google.com) (209.85.221.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 31 Jan 2019 07:40:03 +0000 Received: by mail-wr1-f47.google.com with SMTP id v13so2101730wrw.5 for ; Wed, 30 Jan 2019 23:40:03 -0800 (PST) Received: from abulafia.quesejoda.com (46.red-79-159-61.dynamicip.rima-tde.net. [79.159.61.46]) by smtp.gmail.com with ESMTPSA id s8sm4060414wrn.44.2019.01.30.23.39.59 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 23:40:00 -0800 (PST) From: Aldy Hernandez Subject: [PR middle-end/85598] make -Wprintf* pass use loop info for PHI's To: Richard Biener Cc: Jakub Jelinek , gcc-patches , Martin Sebor Message-ID: Date: Thu, 31 Jan 2019 02:39:53 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi folks. The problem here is that Wprintf* uses the evrp_range_analyzer engine, and doesn't understand that the x_5 != 256 conditional below should make the RANGE [0, 255], not [0, 256]. [local count: 1063004407]: # RANGE [0, 256] NONZERO 511 # x_10 = PHI <0(2), x_5(3)> snprintf (&temp, 4, "%%%02X", x_10); # RANGE [1, 256] NONZERO 511 x_5 = x_10 + 1; if (x_5 != 256) goto ; [98.99%] else goto ; [1.01%] This PR is handled quite easily in the ranger work, but alas there is nothing for this release. Therefore, I'd like to dedicate as little time as possible to this PR this time around. Various possible solutions are discussed in the PR. I think an easy way is to lean on loop analysis to refine the PHI result. It turns out the evrp engine already does this if SCEV data is available. As Richard mentioned in the PR, we should avoid code differences dependent on -W* flags. I have put the loop init code in the pass itself, but am open to moving it outside, perhaps early in the gate function ??. I also took the liberty of calling loop_optimizer_init() with the smallest subset of LOOPS_NORMAL which could still fix the problem (LOOPS_HAVE_PREHEADERS). This avoids unnecessary changes to the CFG. But really, I'm just guessing here. LOOPS_NORMAL would also work, albeit creating forwarder blocks. Tested on x86-64 Linux. What do you think? Aldy commit 189e32856dc4656931a66d4da0be81abb2eceb46 Author: Aldy Hernandez Date: Wed Jan 30 12:25:25 2019 +0100 PR middle-end/85598 * gimple-ssa-sprintf.c (pass_sprintf_length::execute): Build optimizer info when running late and optimizing. diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 8e6016fc42f..973452fd209 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -65,6 +65,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "calls.h" #include "cfgloop.h" +#include "tree-scalar-evolution.h" +#include "tree-ssa-loop.h" #include "intl.h" #include "langhooks.h" @@ -4200,10 +4202,34 @@ pass_sprintf_length::execute (function *fun) init_target_to_host_charmap (); calculate_dominance_info (CDI_DOMINATORS); + bool optimizing_late = optimize > 0 && fold_return_value; + if (optimizing_late) + { + /* ?? We should avoid changing the CFG as much as possible. + This is a warning pass, after all. Thus, use + LOOPS_HAVE_PREHEADERS instead of LOOPS_NORMAL. This avoids + extensive changes to the CFG, without the full hammer of + AVOID_CFG_MANIPULATIONS which would cripple SCEV. + + ?? Should we run this outside of the pass (early in the gate + function). + + FIXME: This should go away, when we have finer grained or + on-demand range information. */ + loop_optimizer_init (LOOPS_HAVE_PREHEADERS); + scev_initialize (); + } + sprintf_dom_walker sprintf_dom_walker; sprintf_dom_walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun)); + if (optimizing_late) + { + scev_finalize (); + loop_optimizer_finalize (); + } + /* Clean up object size info. */ fini_object_sizes (); return 0; diff --git a/gcc/testsuite/gcc.dg/pr85598.c b/gcc/testsuite/gcc.dg/pr85598.c new file mode 100644 index 00000000000..c84b63f8084 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr85598.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; +extern void __chk_fail (void); +extern int snprintf (char *, size_t, const char *, ...); + +int main() +{ + char temp[100]; + unsigned int x; + char *str = temp; + for(x=0; x<256; ++x) { + snprintf(str, 4, "%%%02X", x); + } +}