From patchwork Sun Mar 27 18:58:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 602377 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3qY5sj0DHKz9sBc for ; Mon, 28 Mar 2016 05:58:31 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=AyGUVIQi; dkim-atps=neutral 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:cc:subject:date:message-id; q=dns; s=default; b=KTyMgDgmdXix Lx6te9v/xZjMYLf+P4Wsmgb0OPciBqJ/QCEtz4BulSfPnlSe2OY46+ZybfEFRhsT N8uSZ3SFhq+pxUKBjto/6aqtXpfEJNaBU+I02eFS6ZvlUv0cqczumK2ehIcFJWM7 lGYMH1uiJB9V0nM1BYc7wTJppg9/CG8= 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:cc:subject:date:message-id; s=default; bh=+m4HYR0zKmJqjRl04e QUuwV6g2g=; b=AyGUVIQiSRbVF/Myef2Uqo8t3yIs9s+NmI8XDRhX/Ud8NCoTEC Go9GLXAMzBSzvQIXkp1WQThQgwN+gAarYCj92LAXc1Rz2W3hsQYWygDEd4uND7qI y1BpWojHjOJwLnybQuz1EMhsaD5kh4Ppq7DWmP8XV6fsC3eyS1Q8jkyJI= Received: (qmail 88217 invoked by alias); 27 Mar 2016 18:58:22 -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 88196 invoked by uid 89); 27 Mar 2016 18:58:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=*bar, sk:gimple_, op1, nonetheless X-HELO: mail-qg0-f45.google.com Received: from mail-qg0-f45.google.com (HELO mail-qg0-f45.google.com) (209.85.192.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sun, 27 Mar 2016 18:58:11 +0000 Received: by mail-qg0-f45.google.com with SMTP id j35so94773777qge.0 for ; Sun, 27 Mar 2016 11:58:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=9n0spWxkaw5BdXVtWqlzCFhMxUyC/ECKzlE/SRtQeuc=; b=VtN37WZg9PJeXnLrhwJ8egL9EUIJtPy4+DAbcAkaE/1JiJxPI+pSVANHJsCFowk6Ga 873js2Y+eeF2ZDvVl3jz/yu/R6NxbogXt5O0DGP6wp+spVeLtj5ayD+4ha5MZ21KXX4+ kteNZj9T3M5B5ouelFxMNExGcu6OFrdHGLbklzg1zbSkdu3aVrHQsCWYeRR2WqJHE3Kw gozT7VhY5R3ZVTQ/NOw50gjYTzjnVVFCDqa51ro9MEKmP5pCAGJ943kQY5yGH9g51ji7 zM1y1UxHyT97EnyWqFw+Fs7+8ckqBaAGuKWN6yDaalDi22ujGRy7DOo9ZB2xO43W2Al1 AM/Q== X-Gm-Message-State: AD7BkJKRz9CuMGOCKBzt3nI0ifZyYmr7mHZ0tA7+MLXvcB3U2B0dFbreyBLgeOuaSJ6wNA== X-Received: by 10.140.218.139 with SMTP id o133mr32596251qhb.33.1459105088971; Sun, 27 Mar 2016 11:58:08 -0700 (PDT) Received: from localhost.localdomain (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id 107sm2211364qgz.24.2016.03.27.11.58.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 27 Mar 2016 11:58:08 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: Patrick Palka Subject: [PATCH] Fix PR tree-optimization/59124 (bogus -Warray-bounds warning) Date: Sun, 27 Mar 2016 14:58:03 -0400 Message-Id: <1459105083-24035-1-git-send-email-patrick@parcs.ath.cx> In unrolling of the inner loop in the test case below we introduce unreachable code that otherwise contains out-of-bounds array accesses. This is because the estimation of the maximum number of iterations of the inner loop is too conservative: we assume 6 iterations instead of the actual 4. Nonetheless, VRP should be able to tell that the code is unreachable so that it doesn't warn about it. The only thing holding VRP back is that it doesn't look through conditionals of the form if (j_10 != CST1) where j_10 = j_9 + CST2 so that it could add the assertion j_9 != (CST1 - CST2) This patch teaches VRP to detect such conditionals and to add such assertions, so that it could remove instead of warn about the unreachable code created during loop unrolling. What this addition does with the test case below is something like this: ASSERT_EXPR (i <= 5); for (i = 1; i < 6; i++) { j = i - 1; if (j == 0) break; // ASSERT_EXPR (i != 1) bar[j] = baz[j]; j = i - 2 if (j == 0) break; // ASSERT_EXPR (i != 2) bar[j] = baz[j]; j = i - 3 if (j == 0) break; // ASSERT_EXPR (i != 3) bar[j] = baz[j]; j = i - 4 if (j == 0) break; // ASSERT_EXPR (i != 4) bar[j] = baz[j]; j = i - 5 if (j == 0) break; // ASSERT_EXPR (i != 5) bar[j] = baz[j]; j = i - 6 if (j == 0) break; // ASSERT_EXPR (i != 6) bar[j] = baz[j]; // unreachable because (i != 6 && i <= 5) is always false } (I think the patch I sent a year ago that improved the register_edge_assert stuff would have fixed this too. I'll try to post it again during next stage 1. https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00908.html) Bootstrap + regtest in progress on x86_64-pc-linux-gnu, does this look OK to commit after testing? gcc/ChangeLog: PR tree-optimization/59124 * tree-vrp.c (register_edge_assert_for): For NAME != CST1 where NAME = A + CST2 add the assertion A != (CST1 - CST2). gcc/testsuite/ChangeLog: PR tree-optimization/59124 * gcc.dg/Warray-bounds-19.c: New test. --- gcc/testsuite/gcc.dg/Warray-bounds-19.c | 17 +++++++++++++++++ gcc/tree-vrp.c | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-19.c diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-19.c b/gcc/testsuite/gcc.dg/Warray-bounds-19.c new file mode 100644 index 0000000..e2f9661 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-19.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/59124 */ +/* { dg-options "-O3 -Warray-bounds" } */ + +unsigned baz[6]; + +void foo(unsigned *bar, unsigned n) +{ + unsigned i, j; + + if (n > 6) + n = 6; + + for (i = 1; i < n; i++) + for (j = i - 1; j > 0; j--) + bar[j - 1] = baz[j - 1]; +} + diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b5654c5..31bd575 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5820,6 +5820,28 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si, } } + /* In the case of NAME != CST1 where NAME = A + CST2 we can + assert that NAME != (CST1 - CST2). */ + if ((comp_code == EQ_EXPR || comp_code == NE_EXPR) + && TREE_CODE (val) == INTEGER_CST) + { + gimple *def_stmt = SSA_NAME_DEF_STMT (name); + + if (is_gimple_assign (def_stmt) + && gimple_assign_rhs_code (def_stmt) == PLUS_EXPR) + { + tree op0 = gimple_assign_rhs1 (def_stmt); + tree op1 = gimple_assign_rhs2 (def_stmt); + if (TREE_CODE (op0) == SSA_NAME + && TREE_CODE (op1) == INTEGER_CST) + { + op1 = int_const_binop (MINUS_EXPR, val, op1); + register_edge_assert_for_2 (op0, e, si, comp_code, + op0, op1, is_else_edge); + } + } + } + /* In the case of NAME == 0 or NAME != 1, for BIT_IOR_EXPR defining statement of NAME we can assert both operands of the BIT_IOR_EXPR have zero value. */