From patchwork Tue Jan 30 08:30:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 193881 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1076980dyb; Tue, 30 Jan 2024 00:33:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IG7YLn4pwEgMI+HGM7DalU+GaFoepAXkYgG7xCr1sJV4SZKhigLeAXcMmwcydDmrW1wRhpG X-Received: by 2002:a05:622a:1a87:b0:42a:894d:69bd with SMTP id s7-20020a05622a1a8700b0042a894d69bdmr8113868qtc.116.1706603629454; Tue, 30 Jan 2024 00:33:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706603629; cv=pass; d=google.com; s=arc-20160816; b=yDQvY2b5OX7ltpMfmgUBxll02Cl5QzNw0QAqmIktxgShAfSFII1Q6NzMHDKP5UWT1W RghMSdX82DTEB+6aOv0pxrHl5JSvQDi8TJ3/XFFD0uVysRyDVbhKGeei8p8NBPpEZ0mi V0YRmqgchKh3Im9fmEB/z4iMTZmKpPQcfva9rf9KnZGgvz0YuqFsvn36GInpfuSU7hhD 2Cu6/TcPiRLlZVFYNjY3JGSZ2M5GEa8UYa8eZN7Sdtq+0JG3oYljizWomboQXvEQcZ4A fylwuC0uciDv11tD6WPh/R5/HUbkvsKpR1qRKROezArnhEU68WniaiM4QlFf9JVuhLGO IzZw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:reply-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-disposition :mime-version:message-id:subject:cc:to:from:date:dkim-signature :arc-filter:dmarc-filter:delivered-to; bh=oFOrudR3mPo6Ky85Nn47ktQ3Itjthj/fW/BXSxSdP1U=; fh=FCjeRajqaQYHMkQtfIia8KT5yBac53mYOLLyJhYG/AY=; b=OAqPKztqFCPT/ZdTsVrtTx6rlxj7psUHOFOEwsC9D4y+6xhF0+Uq1Hx5lNByhB1961 LhREH6T+oeE8nrgYe+piKl+MDdVPMAYJht+a2yaukbdaGGLkNWtI1AgwJvpz1wag9Yr2 LMA5u5DkNkTaWbfn51ckjitpPkg0BBtzFuATI+Yn+ztzzZ7obJsQw9R4hxIvkPwBdxA+ hBlLp7Vw8r3g7mNidC3HksaaHHAQQ+uqpvuIvaN4JnzrcCXcstsyVKQM0h5XmhOy8YKJ fKA0ZwR7w+OHZPIe2pPuqzGQ6N988qYxirC9QSBKsnML1YhKNZs9Z8ZdeuDngxJE6zaJ xqtg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=hdu3aweM; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id h16-20020ac85850000000b0042bdf0a5a2dsi84952qth.313.2024.01.30.00.33.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 00:33:49 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=hdu3aweM; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 13139385840F for ; Tue, 30 Jan 2024 08:33:49 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 3E47D3858CDA for ; Tue, 30 Jan 2024 08:30:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3E47D3858CDA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3E47D3858CDA Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706603462; cv=none; b=pWsmYL1m2dJvOtKLKYVypOp1fcU1kHWNWaz9uki2Sf6vWz+Zpfs7VD3+dG38/fI0dxPAZBNw4sVLTwnJmQpDoGDr2+dq+xNAzdTkws2XTODG9TL/foukq1ZIuYOxz8gshBu/yqHz/1Uoe2wX1xbQyA3ZIynXnTLqxv0ZdQxuZ2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706603462; c=relaxed/simple; bh=0g1h9Xr9czQeWVZDovBW3LIZ7gMjdBDIRiNmYA598zc=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=qbkpvPGhq39IhL3hbfQ4ADtqcuZ5F3FearWWx5eGfuWnizA87WptuPCVmlihzjkLl3rKUUc/R2eTl8g0xi58W/wEZx9ZVYAIHcJRkkKllLNKLMJQsdZBA55ECYCq60j/4SUW1YlVsS059FtvrUSoBAHFAVGQVQrc6zXa9hYWRaY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706603450; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=oFOrudR3mPo6Ky85Nn47ktQ3Itjthj/fW/BXSxSdP1U=; b=hdu3aweMl6xQ7mIbtPr/JqAk8DK8dxV7MM8KZtcnPaZDak9uKbzNYKmuO90AqkvRjmT5Dm 4f7yMDL8AxuOD10it9KZN9DE/0rtbWFxfvCr2dU1xNDTHIZZ2rgrrLk/pqrK8UQcAX2l4m IsvKlG/ZZPVtNyPPv1BY6o19rSYOi34= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-541-1FHVokOAOuurjrUzL2OoTA-1; Tue, 30 Jan 2024 03:30:48 -0500 X-MC-Unique: 1FHVokOAOuurjrUzL2OoTA-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 8A2D2185A789; Tue, 30 Jan 2024 08:30:48 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.70]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4D564492BE2; Tue, 30 Jan 2024 08:30:48 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 40U8Uj8h1616715 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 30 Jan 2024 09:30:45 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 40U8Uik31616714; Tue, 30 Jan 2024 09:30:44 +0100 Date: Tue, 30 Jan 2024 09:30:44 +0100 From: Jakub Jelinek To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-ssa-strlen: Fix up handle_store [PR113603] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-4.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789503607455602466 X-GMAIL-MSGID: 1789503607455602466 Hi! Since r10-2101-gb631bdb3c16e85f35d3 handle_store uses count_nonzero_bytes{,_addr} which (more recently limited to statements with the same vuse) can walk earlier statements feeding the rhs of the store and call get_stridx on it. Unlike most of the other functions where get_stridx is called first on rhs and only later on lhs, handle_store calls get_stridx on the lhs before the count_nonzero_bytes* call and does some si->nonzero_bytes comparison on it. Now, strinfo structures are refcounted and it is important not to screw it up. What happens on the following testcase is that we call get_strinfo on the destination idx's base (g), which returns a strinfo at that moment with refcount of 2, one copy referenced in bb 2 final strinfos, one in bb 3 (the vector of strinfos was unshared from the dominator there because some other strinfo was added) and finally we process a store in bb 6. Now, count_nonzero_bytes is called and that sees &g[1] in a PHI and calls get_stridx on it, which in turn calls get_stridx_plus_constant because &g + 1 address doesn't have stridx yet. This creates a new strinfo for it: si = new_strinfo (ptr, idx, build_int_cst (size_type_node, nonzero_chars), basesi->full_string_p); set_strinfo (idx, si); and the latter call, because it is the first one in bb 6 that needs it, unshares the stridx_to_strinfo vector (so refcount of the g strinfo becomes 3). Now, get_stridx_plus_constant needs to chain the new strinfo of &g[1] in between the related strinfos, so after the g record. Because the strinfo is now shared between the current bb and 2 other bbs, it needs to unshare_strinfo it (creating a new strinfo which can be modified as a copy of the old one, decrementing refcount of the old shared one and setting refcount of the new one to 1): if (strinfo *nextsi = get_strinfo (chainsi->next)) { nextsi = unshare_strinfo (nextsi); si->next = nextsi->idx; nextsi->prev = idx; } chainsi = unshare_strinfo (chainsi); if (chainsi->first == 0) chainsi->first = chainsi->idx; chainsi->next = idx; Now, the bug is that the caller of this a couple of frames above, handle_store, holds on a pointer to this g strinfo (but doesn't know about the unsharing, so the pointer is to the old strinfo with refcount of 2), and later needs to update it, so it si = unshare_strinfo (si); and modifies some fields in it. This creates a new strinfo (with refcount of 1 which is stored into the vector of the current bb) based on the old strinfo for g and decrements refcount of the old one to 1. So, now we are in inconsistent state, because the old strinfo for g is referenced in bb 2 and bb 3 vectors, but has just refcount of 1, and then have one strinfo (the one created by unshare_strinfo (chainsi) in get_stridx_plus_constant) which has refcount of 1 but isn't referenced from anywhere anymore. Later on when we free one of the bb 2 or bb 3 vectors (forgot which) that decrements refcount from 1 to 0 and poisons the strinfo/returns it to the pool, but then maybe_invalidate when looking at the other bb's pointer to it ICEs. The following patch fixes it by calling get_strinfo again, it is guaranteed to return non-NULL, but could be an unshared copy instead of the originally fetched shared one. I believe we only need to do this refetching for the case where get_strinfo is called on the lhs before get_stridx is called on other operands, because we should be always modifying (apart from the chaining changes) the strinfo for the destination of the statements, not other strinfos just consumed in there. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-01-30 Jakub Jelinek PR tree-optimization/113603 * tree-ssa-strlen.cc (strlen_pass::handle_store): After count_nonzero_bytes call refetch si using get_strinfo in case it has been unshared in the meantime. * gcc.c-torture/compile/pr113603.c: New test. Jakub --- gcc/tree-ssa-strlen.cc.jj 2024-01-29 10:20:25.000000000 +0100 +++ gcc/tree-ssa-strlen.cc 2024-01-29 15:50:17.056461933 +0100 @@ -5044,6 +5044,9 @@ strlen_pass::handle_store (bool *zero_wr if (si != NULL) { + /* The count_nonzero_bytes call above might have unshared si. + Fetch it again from the vector. */ + si = get_strinfo (idx); /* The corresponding element is set to 1 if the first and last element, respectively, of the sequence of characters being written over the string described by SI ends before --- gcc/testsuite/gcc.c-torture/compile/pr113603.c.jj 2024-01-29 16:09:54.335227319 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr113603.c 2024-01-29 16:09:36.010481829 +0100 @@ -0,0 +1,40 @@ +/* PR tree-optimization/113603 */ + +int a, e; +signed char b; +int *c; +signed char *d; +short f; +signed char g[3]; + +int * +foo (void) +{ + for (int i = 0; i < 3; i++) + g[i] = 2; + int j[100][100] = { {}, {4} }; + signed char *k = &g[1]; + do + { + for (;;) + { + if (c) + break; + return &a; + } + for (f = 0;; f++) + { + for (b = 0; b < 2; b++) + *c = j[b][f]; + if (e) + d = k; + *k = *d; + if (*c) + break; + if (f) + break; + } + } + while (f); + return 0; +}