From patchwork Thu Nov 20 03:21:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 412561 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 11FFD14009B for ; Thu, 20 Nov 2014 14:21:28 +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:cc:subject:date:message-id; q=dns; s=default; b=xPcThPcaGVaq 4yA6SZJJCZDvOAAPf4uaweE0Lx+rc1HNW3QVdoyRzarpLsURY1NSaem4FkkjI0u8 7KmXDc3fFYxlLhLABI31w3Yd/wDH5/G8YDmdFmmd3zVCBKLdxVKh5azwP1GVFn2R URakWG+twljm9GkBGb1qBLyUja7VSVA= 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=bu1SlrJYJhOzN8R06Z 9F+de+7o8=; b=rGYit0ywnV48weCfBc+6yCjqnP3SIPdTI10lnfmuwlWMS0Q0cv 2sWh+NGPVl7bd3USgbD3pLXdl3o2Od48JSFXdA1VipU/pA3aczpBD6SGtnTr1S3X JfcowHHKVKfplmOnpmJLu9dbkEsgk7MlNO6bEBnqeyWzajgJuvEwk5DJU= Received: (qmail 4235 invoked by alias); 20 Nov 2014 03:21:18 -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 4212 invoked by uid 89); 20 Nov 2014 03:21:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-HELO: mail-qg0-f42.google.com Received: from mail-qg0-f42.google.com (HELO mail-qg0-f42.google.com) (209.85.192.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 20 Nov 2014 03:21:12 +0000 Received: by mail-qg0-f42.google.com with SMTP id i50so1539943qgf.29 for ; Wed, 19 Nov 2014 19:21:10 -0800 (PST) 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=K8bxZNFGWTWEeC0fCvWMPMd01EC+UcgDYLUWJBPoQz0=; b=hkTanxE/TZedE2vRERUjsQd1sSPPDr/0ENoTvwEHdlBahqsXrg4ugnjoUHeISUAYbj +NRFS9pHhVsk1iJevbN1TxcoiZGbo2sLUibYFKjrmwybgFlr9WhbGlKGFLn+EpsfTpyX CWVNLU9tq/FAFddEeYBa5X1Q3UzbL18SUfBYIWLkbp6So9e+GcR/9dCMRAZKA9RnEPM4 G239MHEEoSSPF58hEsrpprjedk8PlmOyBS6KeC6gO9s+STj/B+/XmbvVEYw1BlJsvT/6 m+hGEYaiRABiE/5AITEiJP7blRq01+x51Xy+WKvPKFh+8xpBikRzSjotV84I+Jf8G7IB lkhg== X-Gm-Message-State: ALoCoQnveXD9YN4489qr4SmcSWXhUix7ZcrQjGV8BZZq7bIujXpa5qNP0B7lhFxgtjV8vhgh1GrJ X-Received: by 10.224.93.18 with SMTP id t18mr57492299qam.102.1416453669826; Wed, 19 Nov 2014 19:21:09 -0800 (PST) Received: from localhost.localdomain (ool-4353af5c.dyn.optonline.net. [67.83.175.92]) by mx.google.com with ESMTPSA id p78sm1042027qgp.44.2014.11.19.19.21.08 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Nov 2014 19:21:08 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: Patrick Palka Subject: [PATCH] Disable an unsafe VRP transformation when -fno-strict-overflow is set Date: Wed, 19 Nov 2014 22:21:00 -0500 Message-Id: <1416453660-19905-1-git-send-email-patrick@parcs.ath.cx> VRP may simplify a conditional like i <= 5 to i == 5 if it is known that the lower bound of i's range is 5, e.g. [5, +INF]. But if the upper bound of i's range is also overflow infinity, i.e. [5, +INF(OVF)] then this transformation is only valid if -fstrict-overflow is in effect. Likewise for transforming i > 10 to i != 10 given i's range is [10, +INF(OVF)] and for transforming i <= 20 to i == 20 given i's range is [-INF(OVF), 20]. This patch makes this transformation only get performed if strict overflow rules are in effect and potentially emits a -Wstrict-overflow=3 warning when the transformation takes place. Bootstrap and regtesting in progress on x86_64-unknown-linux-gnu. Does the patch look OK if there are no new regressions? gcc/ * tree-vrp.c (test_for_singularity): New parameter strict_overflow_p. Set *strict_overflow_p to true if signed overflow must be undefined for the return value to satisfy the conditional. (simplify_cond_using_ranges): Don't perform the simplification if it violates overflow rules. gcc/testsuite/ * gcc.dg/no-strict-overflow-8.c: New test. --- gcc/testsuite/gcc.dg/no-strict-overflow-8.c | 25 +++++++++++++ gcc/tree-vrp.c | 57 +++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/no-strict-overflow-8.c diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-8.c b/gcc/testsuite/gcc.dg/no-strict-overflow-8.c new file mode 100644 index 0000000..11ef935 --- /dev/null +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-8.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ + +/* We cannot fold i > 0 because p->a - p->b can be larger than INT_MAX + and thus i can wrap. Dual of Wstrict-overflow-18.c */ + +struct c { unsigned int a; unsigned int b; }; +extern void bar (struct c *); +int +foo (struct c *p) +{ + int i; + int sum = 0; + + for (i = 0; i < p->a - p->b; ++i) + { + if (i > 0) + sum += 2; + bar (p); + } + return sum; +} + +/* { dg-final { scan-tree-dump "i_.* > 0" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index bcf4c2b..444af71 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9117,11 +9117,15 @@ simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt) a known value range VR. If there is one and only one value which will satisfy the - conditional, then return that value. Else return NULL. */ + conditional, then return that value. Else return NULL. + + If signed overflow must be undefined for the value to satisfy + the conditional, then set *STRICT_OVERFLOW_P to true. */ static tree test_for_singularity (enum tree_code cond_code, tree op0, - tree op1, value_range_t *vr) + tree op1, value_range_t *vr, + bool *strict_overflow_p) { tree min = NULL; tree max = NULL; @@ -9172,7 +9176,16 @@ test_for_singularity (enum tree_code cond_code, tree op0, then there is only one value which can satisfy the condition, return that value. */ if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min)) - return min; + { + if ((cond_code == LE_EXPR || cond_code == LT_EXPR) + && is_overflow_infinity (vr->max)) + *strict_overflow_p = true; + if ((cond_code == GE_EXPR || cond_code == GT_EXPR) + && is_overflow_infinity (vr->min)) + *strict_overflow_p = true; + + return min; + } } return NULL; } @@ -9252,9 +9265,12 @@ simplify_cond_using_ranges (gcond *stmt) able to simplify this conditional. */ if (vr->type == VR_RANGE) { - tree new_tree = test_for_singularity (cond_code, op0, op1, vr); + enum warn_strict_overflow_code wc = WARN_STRICT_OVERFLOW_CONDITIONAL; + bool sop = false; + tree new_tree = test_for_singularity (cond_code, op0, op1, vr, &sop); - if (new_tree) + if (new_tree + && (!sop || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))) { if (dump_file) { @@ -9275,16 +9291,30 @@ simplify_cond_using_ranges (gcond *stmt) fprintf (dump_file, "\n"); } + if (sop && issue_strict_overflow_warning (wc)) + { + location_t location = input_location; + if (gimple_has_location (stmt)) + location = gimple_location (stmt); + + warning_at (location, OPT_Wstrict_overflow, + "assuming signed overflow does not occur when " + "simplifying conditional"); + } + return true; } /* Try again after inverting the condition. We only deal with integral types here, so no need to worry about issues with inverting FP comparisons. */ - cond_code = invert_tree_comparison (cond_code, false); - new_tree = test_for_singularity (cond_code, op0, op1, vr); + sop = false; + new_tree = test_for_singularity + (invert_tree_comparison (cond_code, false), + op0, op1, vr, &sop); - if (new_tree) + if (new_tree + && (!sop || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))) { if (dump_file) { @@ -9305,6 +9335,17 @@ simplify_cond_using_ranges (gcond *stmt) fprintf (dump_file, "\n"); } + if (sop && issue_strict_overflow_warning (wc)) + { + location_t location = input_location; + if (gimple_has_location (stmt)) + location = gimple_location (stmt); + + warning_at (location, OPT_Wstrict_overflow, + "assuming signed overflow does not occur when " + "simplifying conditional"); + } + return true; } }