From patchwork Thu Jul 27 21:36:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 108862 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp2595595qge; Thu, 27 Jul 2017 14:36:24 -0700 (PDT) X-Received: by 10.84.129.103 with SMTP id 94mr5621021plb.63.1501191384799; Thu, 27 Jul 2017 14:36:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501191384; cv=none; d=google.com; s=arc-20160816; b=ZuCeVqrdJJsbn5w6uwJO/eb0aa/qe3PGYA+jfTFqTeWfmLvpqd/8GCA0UNeTNf33f3 R3+ztn+DpH/erhKhE6kXPuUYdADBkDYaixOpHefDtiH7bbLviaKSai8AiYG2Ex1186pk G/yg/rm5iWRMReCrqJDkm+AOdM7G9P39+Un/YY9GURnBIs3uJXJbM9NRPX//ca5dxnML 6TBceJhEugGoKHOLps+CvQ+WNOtto15hgZKEN+msR00xKy0kACwRwJy/cZUUChHo5/FF klGHC3RuWllVuDankHNU2MxLq+K3TLT8rkEBn4wZYePqotmcUzg06MLqiuyLBfkP+dsw nDug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:date:subject:mail-followup-to:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=hip3mw1sstacw24+Q8XgKW+Sm2xe+R5Rtc+OvUGZZ5I=; b=NL+RIY4qZcf9eC8XB2VDulNDlEiTVryecGAgrzizKqRQ6CSYLOvDWbwGHzwks18AtK YZ1a+LyRy8g8Ag0T47zh1ny408rCMXMQhJlLJJVu6sLGVo66/IV9zLhVvSDuudkXUvV/ qw7OrrFh2Gchub7zCTXUdcp2x4MKzM2S+iuUtyR6CB7tSEXOh9qmuf3dMhmwF0sad+cz DdSY7zIgzgBid0RLnyAVgS/iBdsk+7R6bWL3sgI6M8DoRpxKKtQOwtCwPMYEQAf9wTkm jZC5v2CzjgmpX9vkt3lTtH6oLv6I/mpd26K16NHF38nLWicSYI0Tyg9Hgk+SNOfgwQYW v75g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.b=GPliBon8; spf=pass (google.com: domain of gcc-patches-return-459211-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-459211-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s197si11523653pgs.641.2017.07.27.14.36.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Jul 2017 14:36:24 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-459211-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 header.b=GPliBon8; spf=pass (google.com: domain of gcc-patches-return-459211-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-459211-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=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:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=Rv/lz6ELrgyeKr1uSsWszPzE5yBodMkW5rrepr5cycUVwt25I4Lw+ ab0dzUY0YpdzhArN6nvKwQDGrYOAtLUPBGWQeCaioOGJcn80M091BLcv/45icbZ/ 5axeWSpv3TWwPrYVsaSTY9OduIc6FJPJOnhdjsceJ7Yocgw5g8+Ye4= 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:date:message-id:mime-version:content-type; s= default; bh=PiaY8OrMKHPfE+gvpXxoxCNcVGQ=; b=GPliBon8s4GN8aiWdAdJ 4b9f2oPiBPtCAANU0PFWa3IoRbdergDMX5uhINmCxirHUU6hIrUMlkCyEhvWyPMX wbqIsudQ6QwqIT+pgVzJEoAtdlBnIp6wYGq5oJU9SelPKdeuRwDH7ICo8cKd+wO9 hNhNERL3sXnd9pbsMkYg6H4= Received: (qmail 120133 invoked by alias); 27 Jul 2017 21:36:10 -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 119197 invoked by uid 89); 27 Jul 2017 21:36:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=nsi, rfa X-HELO: mail-wr0-f172.google.com Received: from mail-wr0-f172.google.com (HELO mail-wr0-f172.google.com) (209.85.128.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Jul 2017 21:36:07 +0000 Received: by mail-wr0-f172.google.com with SMTP id y43so148362699wrd.3 for ; Thu, 27 Jul 2017 14:36:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=hip3mw1sstacw24+Q8XgKW+Sm2xe+R5Rtc+OvUGZZ5I=; b=NduQB2yleXd3mRWTkXET/ronBi10dqh7bfgWMz+uoFtLmYGvzPSj7NXkHyPTYJQRIb 8h+dnqiQKdBj+w4EfJlIjv0wpqTTcA2lVqfG7H05UgjxU+sG7v7uoq/1QAg/4ozhWaJ1 fuzqRPtPVTZrffAEeJABdwr3VlhRskFqURhyaBuViNMaVmyfHsucwv6mqm0WgODquDLm 3U+yuJBkxzbtNbZqO5NKdU9+fzbqgA5We+26HhfhwfKuFIcRwT1pxtOAadSnyc5jD1bL kxzGnmKN66E69Acoy0WMIi/xDrXHov82xqdL9ZuBCqm1DUbbQ5pwaYxI+3kPDxz4nEQW x1ug== X-Gm-Message-State: AIVw113jWKiS13n2bRdALpYhmAFiERgXx4+R7+HX1sROQIYEHjN2oM9A 3+rM7jPWw2Kw7MWELtdKhA== X-Received: by 10.223.171.200 with SMTP id s66mr5025615wrc.38.1501191365309; Thu, 27 Jul 2017 14:36:05 -0700 (PDT) Received: from localhost ([2.26.27.176]) by smtp.gmail.com with ESMTPSA id z190sm17906358wmz.31.2017.07.27.14.36.03 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 27 Jul 2017 14:36:04 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: RFA: Backport fix for PR80769 Date: Thu, 27 Jul 2017 22:36:03 +0100 Message-ID: <87y3r9tvek.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This is a minimal-ish backport of the fix for PR80769. The trunk version also replaced open-coded instances of get_next_strinfo with calls to the new function. It also added asserts in various other places to try to ensure that related strinfos were consistently delayed or not delayed. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK for gcc-7-branch? (And OK for gcc-6-branch if the same patch passes testing there?) Richard 2017-07-27 Richard Sandiford gcc/ PR tree-optimization/80769 * tree-ssa-strlen.c (strinfo): Document that "stmt" is also used for malloc and calloc. Document the new invariant that all related strinfos have delayed lengths or none do. (get_next_strinfo): New function. (verify_related_strinfos): Move earlier in file. (set_endptr_and_length): New function, split out from... (get_string_length): ...here. Also set the lengths of related strinfos. gcc/testsuite/ PR tree-optimization/80769 * gcc.dg/strlenopt-31.c: New test. * gcc.dg/strlenopt-31g.c: Likewise. Index: gcc/tree-ssa-strlen.c =================================================================== --- gcc/tree-ssa-strlen.c 2017-05-10 18:04:24.514775477 +0100 +++ gcc/tree-ssa-strlen.c 2017-07-27 18:21:20.308966958 +0100 @@ -61,7 +61,13 @@ struct strinfo tree length; /* Any of the corresponding pointers for querying alias oracle. */ tree ptr; - /* Statement for delayed length computation. */ + /* This is used for two things: + + - To record the statement that should be used for delayed length + computations. We maintain the invariant that all related strinfos + have delayed lengths or none do. + + - To record the malloc or calloc call that produced this result. */ gimple *stmt; /* Pointer to '\0' if known, if NULL, it can be computed as ptr + length. */ @@ -156,6 +162,19 @@ get_strinfo (int idx) return (*stridx_to_strinfo)[idx]; } +/* Get the next strinfo in the chain after SI, or null if none. */ + +static inline strinfo * +get_next_strinfo (strinfo *si) +{ + if (si->next == 0) + return NULL; + strinfo *nextsi = get_strinfo (si->next); + if (nextsi == NULL || nextsi->first != si->first || nextsi->prev != si->idx) + return NULL; + return nextsi; +} + /* Helper function for get_stridx. */ static int @@ -438,6 +457,45 @@ set_strinfo (int idx, strinfo *si) (*stridx_to_strinfo)[idx] = si; } +/* Return the first strinfo in the related strinfo chain + if all strinfos in between belong to the chain, otherwise NULL. */ + +static strinfo * +verify_related_strinfos (strinfo *origsi) +{ + strinfo *si = origsi, *psi; + + if (origsi->first == 0) + return NULL; + for (; si->prev; si = psi) + { + if (si->first != origsi->first) + return NULL; + psi = get_strinfo (si->prev); + if (psi == NULL) + return NULL; + if (psi->next != si->idx) + return NULL; + } + if (si->idx != si->first) + return NULL; + return si; +} + +/* Set SI's endptr to ENDPTR and compute its length based on SI->ptr. + Use LOC for folding. */ + +static void +set_endptr_and_length (location_t loc, strinfo *si, tree endptr) +{ + si->endptr = endptr; + si->stmt = NULL; + tree start_as_size = fold_convert_loc (loc, size_type_node, si->ptr); + tree end_as_size = fold_convert_loc (loc, size_type_node, endptr); + si->length = fold_build2_loc (loc, MINUS_EXPR, size_type_node, + end_as_size, start_as_size); +} + /* Return string length, or NULL if it can't be computed. */ static tree @@ -533,12 +591,12 @@ get_string_length (strinfo *si) case BUILT_IN_STPCPY_CHK_CHKP: gcc_assert (lhs != NULL_TREE); loc = gimple_location (stmt); - si->endptr = lhs; - si->stmt = NULL; - lhs = fold_convert_loc (loc, size_type_node, lhs); - si->length = fold_convert_loc (loc, size_type_node, si->ptr); - si->length = fold_build2_loc (loc, MINUS_EXPR, size_type_node, - lhs, si->length); + set_endptr_and_length (loc, si, lhs); + for (strinfo *chainsi = verify_related_strinfos (si); + chainsi != NULL; + chainsi = get_next_strinfo (chainsi)) + if (chainsi->length == NULL) + set_endptr_and_length (loc, chainsi, lhs); break; case BUILT_IN_MALLOC: break; @@ -607,32 +665,6 @@ unshare_strinfo (strinfo *si) return nsi; } -/* Return first strinfo in the related strinfo chain - if all strinfos in between belong to the chain, otherwise - NULL. */ - -static strinfo * -verify_related_strinfos (strinfo *origsi) -{ - strinfo *si = origsi, *psi; - - if (origsi->first == 0) - return NULL; - for (; si->prev; si = psi) - { - if (si->first != origsi->first) - return NULL; - psi = get_strinfo (si->prev); - if (psi == NULL) - return NULL; - if (psi->next != si->idx) - return NULL; - } - if (si->idx != si->first) - return NULL; - return si; -} - /* Attempt to create a new strinfo for BASESI + OFF, or find existing strinfo if there is any. Return it's idx, or 0 if no strinfo has been created. */ Index: gcc/testsuite/gcc.dg/strlenopt-31.c =================================================================== --- /dev/null 2017-07-27 17:06:14.642985039 +0100 +++ gcc/testsuite/gcc.dg/strlenopt-31.c 2017-07-27 18:11:20.158804210 +0100 @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include "strlenopt.h" + +__attribute__((noinline, noclone)) int +bar (char *p1, const char *q) +{ + strcpy (p1, "abcde"); + char *p2 = strchr (p1, '\0'); + strcpy (p2, q); + char *p3 = strchr (p2, '\0'); + memcpy (p3, "x", 2); + return strlen (p1); +} + +int +main (void) +{ + char buffer[10]; + int res = bar (buffer, "foo"); + if (strcmp (buffer, "abcdefoox") != 0 || res != 9) + abort (); + return 0; +} Index: gcc/testsuite/gcc.dg/strlenopt-31g.c =================================================================== --- /dev/null 2017-07-27 17:06:14.642985039 +0100 +++ gcc/testsuite/gcc.dg/strlenopt-31g.c 2017-07-27 18:11:20.158804210 +0100 @@ -0,0 +1,9 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-options "-O2 -fdump-tree-strlen" } */ + +#define USE_GNU +#include "strlenopt-31.c" + +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-not "strlen \\(" "strlen" } } */