From patchwork Sun Nov 20 13:50:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 83150 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp1005737qge; Sun, 20 Nov 2016 05:50:56 -0800 (PST) X-Received: by 10.13.225.151 with SMTP id k145mr8488484ywe.121.1479649856502; Sun, 20 Nov 2016 05:50:56 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id i189si3666751ybc.35.2016.11.20.05.50.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Nov 2016 05:50:56 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-442072-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-442072-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-442072-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=m2z1roIPJH7TQ3rkQNLGU2Nb7c4DhUSPDma4Ce55oDu2hy yXkwwP58kQnDnI8ivKel4/GNGh6rUG3cIbEGID+/s+pOVKQg4FB4rk3ixOFA7/HM aGsTdPKWDk/Jpd2Tzt2q5MfgEtDYW2VUwxUZWwov4HgqxcQsUp9o0c6h6cH00= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=WdSAxU4VanzS7FfE526ccX7es2o=; b=GDfk97jfEwVCzYkyKOdn YM/UKC69v4itS5Dnh/BMzCj4MK+4PQv/MlxZYUYCe+RMy/l+8peRhr01sbHPJ1RE ImYCvRSbxl5z/SuqwlDn81pI1KnPGN/M7+lBtdgZeuSOkfmrqBwDGI0/kqr1mUKn tMYNgorZU/XBdA5Cfw2hDPU= Received: (qmail 5900 invoked by alias); 20 Nov 2016 13:50:36 -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 5866 invoked by uid 89); 20 Nov 2016 13:50:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=grateful, regressed, strlens, sk:ptrdiff X-HELO: mail-io0-f176.google.com Received: from mail-io0-f176.google.com (HELO mail-io0-f176.google.com) (209.85.223.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 20 Nov 2016 13:50:22 +0000 Received: by mail-io0-f176.google.com with SMTP id n13so20677297ioe.2 for ; Sun, 20 Nov 2016 05:50:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=8vH8KFTuKZYyO/Mo3b0Y18dLiXcXyMK4P1XPtiCyFNo=; b=SFeV7WaoA5ppJbQSJ2dXHcHSrLDt/qJ7G0fXMqJrC2p/dc032lqbzdXG5BTaFBWIw6 b69lenO2rRaEAS72OwIiOcEoDhj5FZi1J6lwcCOk1M2UYTsmQczg92cpZl0UE8aOVUN0 4phkbBOQ0dUzhR90GGSskoTvO6MJyXmCDdoINDV1c+XlqWWStPOXpgB6/+byMXAG3adi HoniI8AM1FTGUwMeMVsbN4pZFHpIgpLaNBZJPIphPSz2P4bxwk9y6usWi3KCSQ4XV7Mx IL6deggwmYcb3bTQvWXgFMo9B+rpfW6SW1T2IOxLrMY98WTMdTV9w8xkexK3MG0lINQk v5Qg== X-Gm-Message-State: AKaTC00wppPPfo/G6uWZb2UsAVZpkR4YA4Vkz4jhgMsy6xb0MnUZ7dkUZykY35N8pp5s11gUQLF05r4Q4xAzrDmm X-Received: by 10.107.55.136 with SMTP id e130mr6733838ioa.76.1479649820763; Sun, 20 Nov 2016 05:50:20 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.12.169 with HTTP; Sun, 20 Nov 2016 05:50:20 -0800 (PST) From: Prathamesh Kulkarni Date: Sun, 20 Nov 2016 19:20:20 +0530 Message-ID: Subject: PR78153 To: gcc Patches , Richard Biener , Martin Sebor X-IsSubscribed: yes Hi, As suggested by Martin in PR78153 strlen's return value cannot exceed PTRDIFF_MAX. So I set it's range to [0, PTRDIFF_MAX - 1] in extract_range_basic() in the attached patch. However it regressed strlenopt-3.c: Consider fn1() from strlenopt-3.c: __attribute__((noinline, noclone)) size_t fn1 (char *p, char *q) { size_t s = strlen (q); strcpy (p, q); return s - strlen (p); } The optimized dump shows the following: __attribute__((noclone, noinline)) fn1 (char * p, char * q) { size_t s; size_t _7; long unsigned int _9; : s_4 = strlen (q_3(D)); _9 = s_4 + 1; __builtin_memcpy (p_5(D), q_3(D), _9); _7 = 0; return _7; } which introduces the regression, because the test expects "return 0;" in fn1(). The issue seems to be in vrp2: Before the patch: Visiting statement: s_4 = strlen (q_3(D)); Found new range for s_4: VARYING Visiting statement: _1 = s_4; Found new range for _1: [s_4, s_4] marking stmt to be not simulated again Visiting statement: _7 = s_4 - _1; Applying pattern match.pd:111, gimple-match.c:27997 Match-and-simplified s_4 - _1 to 0 Intersecting [0, 0] and [0, +INF] to [0, 0] Found new range for _7: [0, 0] __attribute__((noclone, noinline)) fn1 (char * p, char * q) { size_t s; long unsigned int _1; long unsigned int _9; : s_4 = strlen (q_3(D)); _9 = s_4 + 1; __builtin_memcpy (p_5(D), q_3(D), _9); _1 = s_4; return 0; } After the patch: Visiting statement: s_4 = strlen (q_3(D)); Intersecting [0, 9223372036854775806] and [0, 9223372036854775806] to [0, 9223372036854775806] Found new range for s_4: [0, 9223372036854775806] marking stmt to be not simulated again Visiting statement: _1 = s_4; Intersecting [0, 9223372036854775806] EQUIVALENCES: { s_4 } (1 elements) and [0, 9223372036854775806] to [0, 9223372036854775806] EQUIVALENCES: { s_4 } (1 elements) Found new range for _1: [0, 9223372036854775806] marking stmt to be not simulated again Visiting statement: _7 = s_4 - _1; Intersecting ~[9223372036854775807, 9223372036854775809] and ~[9223372036854775807, 9223372036854775809] to ~[9223372036854775807, 9223372036854775809] Found new range for _7: ~[9223372036854775807, 9223372036854775809] marking stmt to be not simulated again __attribute__((noclone, noinline)) fn1 (char * p, char * q) { size_t s; long unsigned int _1; size_t _7; long unsigned int _9; : s_4 = strlen (q_3(D)); _9 = s_4 + 1; __builtin_memcpy (p_5(D), q_3(D), _9); _1 = s_4; _7 = s_4 - _1; return _7; } Then forwprop4 turns _1 = s_4 _7 = s_4 - _1 into _7 = 0 and we end up with: _7 = 0 return _7 in optimized dump. Running ccp again after forwprop4 trivially solves the issue, however I am not sure if we want to run ccp again ? The issue is probably with extract_range_from_ssa_name(): For _1 = s_4 Before patch: VR for s_4 is set to varying. So VR for _1 is set to [s_4, s_4] by extract_range_from_ssa_name. Since VR for _1 is [s_4, s_4] it implicitly implies that _1 is equal to s_4, and vrp is able to transform _7 = s_4 - _1 to _7 = 0 (by using match.pd pattern x - x -> 0). After patch: VR for s_4 is set to [0, PTRDIFF_MAX - 1] And correspondingly VR for _1 is set to [0, PTRDIFF_MAX - 1] so IIUC, we then lose the information that _1 is equal to s_4, and vrp doesn't transform _7 = s_4 - _1 to _7 = 0. forwprop4 does that because it sees that s_4 and _1 are equivalent. Does this sound correct ? I am not sure how to proceed with the patch, and would be grateful for suggestions. Thanks, Prathamesh diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78153-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78153-1.c new file mode 100644 index 0000000..2530ba0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78153-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp-slim" } */ + +void f(const char *s) +{ + if (__PTRDIFF_MAX__ <= __builtin_strlen (s)) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "__builtin_abort" "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78153-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78153-2.c new file mode 100644 index 0000000..de70450 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78153-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp-slim" } */ + +void f(const char *s) +{ + __PTRDIFF_TYPE__ n = __builtin_strlen (s); + if (n < 0) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "__builtin_abort" "evrp" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index c2a4133..d17b413 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4013,6 +4013,16 @@ extract_range_basic (value_range *vr, gimple *stmt) : vrp_val_max (type), NULL); } return; + case CFN_BUILT_IN_STRLEN: + { + tree type = TREE_TYPE (gimple_call_lhs (stmt)); + unsigned HOST_WIDE_INT max = + TREE_INT_CST_LOW (vrp_val_max (ptrdiff_type_node)) - 1; + + set_value_range (vr, VR_RANGE, build_int_cst (type, 0), + build_int_cst (type, max), NULL); + } + return; default: break; }