From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from server.nextmovesoftware.com (server.nextmovesoftware.com [162.254.253.69]) by sourceware.org (Postfix) with ESMTPS id 3C14C3858D28 for ; Sun, 20 Feb 2022 16:51:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3C14C3858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nextmovesoftware.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nextmovesoftware.com; s=default; h=Content-Type:MIME-Version:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=EG23Vxv2NXIEcHqy29t950i3RbSXL3XGfbbYHyB+wPM=; b=A7j/qmDjb3DrxBDm8fJNcIGf5u adoEJR2gVZUtzTyaEJzVu0cM1FOiVTFwYcNWLAvmAQ6GVBgfjJvxa4hQnvf0fyxbsB7Z3xiP0BlF8 nUVVP0Dc6dVjY06Yozs69CBqurmKvBLpR/7ECBxgxchytBHq/ZQt7CESF0v1Umzdx3/lxeiNORf+b ADCri/DUkNPEy4IzZCoCG/6TbOe/nT+WFYtjK3p0J4+9OkXTwPOjVbvm6nSbuYN2XOtMU/3IuHt8h rWFygg1xLcmYQy+1dA6YQ5toDsSVOyG2NY7lkkBnKu4URTqiXhy61CKFc0v83cvwe3YlbszxwTh1E +IcBWt3w==; Received: from host86-186-213-42.range86-186.btcentralplus.com ([86.186.213.42]:49453 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nLpQv-0002aX-Mp for gcc-patches@gcc.gnu.org; Sun, 20 Feb 2022 11:51:37 -0500 From: "Roger Sayle" To: Subject: [PATCH] PR tree-optimization/83907: Improved memset handling in strlen pass. Date: Sun, 20 Feb 2022 16:51:36 -0000 Message-ID: <014201d8267a$206e1320$614a3960$@nextmovesoftware.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0143_01D8267A.206F4BA0" X-Mailer: Microsoft Outlook 16.0 Thread-Index: AdgmeXL+ygybIEnjSkWUWPq1wMpAPQ== Content-Language: en-gb X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.nextmovesoftware.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - nextmovesoftware.com X-Get-Message-Sender-Via: server.nextmovesoftware.com: authenticated_id: roger@nextmovesoftware.com X-Authenticated-Sender: server.nextmovesoftware.com: roger@nextmovesoftware.com X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Feb 2022 16:51:39 -0000 This is a multipart message in MIME format. ------=_NextPart_000_0143_01D8267A.206F4BA0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit This patch implements the missed optimization enhancement PR 83907, by handling memset with a constant byte value in tree-ssa's strlen optimization pass. Effectively, this treats memset(dst,'x',3) as it would memcpy(dst,"xxx",3). This patch also includes a tweak to handle_store to address another missed optimization observed in the related test case pr83907-2.c. The consecutive byte stores to memory get coalesced into a vector write of a vector const, but unfortunately tree-ssa-strlen's handle_store didn't previously handle the (unusual) case where the stored "string" starts with a zero byte but also contains non-zero bytes. This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check with no new failures. Ok for mainline? 2022-02-20 Roger Sayle gcc/ChangeLog PR tree-optimization/83907 * tree-ssa-strlen.cc (handle_builtin_memset): Record a strinfo for memset with an constant char value. (handle_store): Improved handling of stores with a first byte of zero, but not storing_all_zeros_p. gcc/testsuite/ChangeLog PR tree-optimization/83907 * gcc.dg/tree-ssa/pr83907-1.c: New test case. * gcc.dg/tree-ssa/pr83907-2.c: New test case. Thanks in advance, Roger -- ------=_NextPart_000_0143_01D8267A.206F4BA0 Content-Type: text/plain; name="patchslb.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="patchslb.txt" diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc=0A= index 7370516..d2db197 100644=0A= --- a/gcc/tree-ssa-strlen.cc=0A= +++ b/gcc/tree-ssa-strlen.cc=0A= @@ -3810,9 +3810,44 @@ strlen_pass::handle_builtin_memset (bool = *zero_write)=0A= {=0A= gimple *memset_stmt =3D gsi_stmt (m_gsi);=0A= tree ptr =3D gimple_call_arg (memset_stmt, 0);=0A= + tree memset_val =3D gimple_call_arg (memset_stmt, 1);=0A= + tree memset_size =3D gimple_call_arg (memset_stmt, 2);=0A= +=0A= /* Set to the non-constant offset added to PTR. */=0A= wide_int offrng[2];=0A= int idx1 =3D get_stridx (ptr, memset_stmt, offrng, ptr_qry.rvals);=0A= + if (idx1 =3D=3D 0=0A= + && TREE_CODE (memset_val) =3D=3D INTEGER_CST=0A= + && ((TREE_CODE (memset_size) =3D=3D INTEGER_CST=0A= + && !integer_zerop (memset_size))=0A= + || TREE_CODE (memset_size) =3D=3D SSA_NAME))=0A= + {=0A= + unsigned HOST_WIDE_INT mask =3D (HOST_WIDE_INT_1U << = CHAR_TYPE_SIZE) - 1;=0A= + bool full_string_p =3D (wi::to_wide (memset_val) & mask) =3D=3D 0;=0A= +=0A= + /* We only handle symbolic lengths when writing non-zero values. = */=0A= + if (full_string_p && TREE_CODE (memset_size) !=3D INTEGER_CST)=0A= + return false;=0A= +=0A= + idx1 =3D new_stridx (ptr);=0A= + if (idx1 =3D=3D 0)=0A= + return false;=0A= + tree newlen;=0A= + if (full_string_p)=0A= + newlen =3D build_int_cst (size_type_node, 0);=0A= + else if (TREE_CODE (memset_size) =3D=3D INTEGER_CST)=0A= + newlen =3D fold_convert (size_type_node, memset_size);=0A= + else=0A= + newlen =3D memset_size;=0A= +=0A= + strinfo *dsi =3D new_strinfo (ptr, idx1, newlen, full_string_p);=0A= + set_strinfo (idx1, dsi);=0A= + find_equal_ptrs (ptr, idx1);=0A= + dsi->dont_invalidate =3D true;=0A= + dsi->writable =3D true;=0A= + return false;=0A= + }=0A= +=0A= if (idx1 <=3D 0)=0A= return false;=0A= strinfo *si1 =3D get_strinfo (idx1);=0A= @@ -3825,7 +3860,6 @@ strlen_pass::handle_builtin_memset (bool = *zero_write)=0A= if (!valid_builtin_call (alloc_stmt))=0A= return false;=0A= tree alloc_size =3D gimple_call_arg (alloc_stmt, 0);=0A= - tree memset_size =3D gimple_call_arg (memset_stmt, 2);=0A= =0A= /* Check for overflow. */=0A= maybe_warn_overflow (memset_stmt, false, memset_size, NULL, false, = true);=0A= @@ -3841,7 +3875,7 @@ strlen_pass::handle_builtin_memset (bool = *zero_write)=0A= return false;=0A= =0A= /* Bail when the call writes a non-zero value. */=0A= - if (!integer_zerop (gimple_call_arg (memset_stmt, 1)))=0A= + if (!integer_zerop (memset_val))=0A= return false;=0A= =0A= /* Let the caller know the memset call cleared the destination. */=0A= @@ -5093,8 +5127,9 @@ strlen_pass::handle_store (bool *zero_write)=0A= return false;=0A= }=0A= =0A= - if (storing_all_zeros_p=0A= - || storing_nonzero_p=0A= + if (storing_nonzero_p=0A= + || storing_all_zeros_p=0A= + || (full_string_p && lenrange[1] =3D=3D 0)=0A= || (offset !=3D 0 && store_before_nul[1] > 0))=0A= {=0A= /* When STORING_NONZERO_P, we know that the string will start=0A= @@ -5104,8 +5139,9 @@ strlen_pass::handle_store (bool *zero_write)=0A= of leading non-zero characters and set si->NONZERO_CHARS to=0A= the result instead.=0A= =0A= - When STORING_ALL_ZEROS_P, we know that the string is now=0A= - OFFSET characters long.=0A= + When STORING_ALL_ZEROS_P, or the first byte written is zero,=0A= + i.e. FULL_STRING_P && LENRANGE[1] =3D=3D 0, we know that the=0A= + string is now OFFSET characters long.=0A= =0A= Otherwise, we're storing an unknown value at offset OFFSET,=0A= so need to clip the nonzero_chars to OFFSET.=0A= diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83907-1.c = b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-1.c=0A= new file mode 100644=0A= index 0000000..2a6f4f5=0A= --- /dev/null=0A= +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-1.c=0A= @@ -0,0 +1,13 @@=0A= +/* { dg-do compile } */=0A= +/* { dg-options "-O2 -fdump-tree-optimized" } */=0A= +=0A= +extern char str[];=0A= +=0A= +unsigned int foo()=0A= +{=0A= + __builtin_memset(str,'x',5);=0A= + str[5] =3D 0;=0A= + return __builtin_strlen (str);=0A= +}=0A= +=0A= +/* { dg-final { scan-tree-dump-not "strlen" "optimized" } } */=0A= diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83907-2.c = b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-2.c=0A= new file mode 100644=0A= index 0000000..cc27504=0A= --- /dev/null=0A= +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-2.c=0A= @@ -0,0 +1,14 @@=0A= +/* { dg-do compile } */=0A= +/* { dg-options "-O2 -fdump-tree-optimized" } */=0A= +=0A= +extern char str[];=0A= +=0A= +unsigned int foo()=0A= +{=0A= + __builtin_memset(str,'x',5);=0A= + str[5] =3D 0;=0A= + str[6] =3D 'z';=0A= + return __builtin_strlen (str);=0A= +}=0A= +=0A= +/* { dg-final { scan-tree-dump-not "strlen" "optimized" } } */=0A= ------=_NextPart_000_0143_01D8267A.206F4BA0--