From patchwork Fri Jan 10 14:13:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1221106 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-517108-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=FW11xnga; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=PamOMbL1; dkim-atps=neutral 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 47vQ225v5vz9sPn for ; Sat, 11 Jan 2020 01:13:29 +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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=guAs+hS1N2opy9qNSkp+lpyfnK4vzCbs1M9LfStvYj0vdWwX8V XAgwgE2QX8WFnwRDHFNQ0gZALJ1NvnCs5dSIZs19+O98wVF4Fc2MZIByXsP/65hN Pb+l03tZIEIRez4irYHf/SSK+KYlxVxy8um9wNpeuuGTIwd+5Ktz02vJo= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=52N/Ul4uWCC2I8f1obLHYMMA4GQ=; b=FW11xngaa1JFPeCBw0ZU X66c4anzWUUydfG0NxgRhCe5bsTijEsMnQqk9nidDeUicWPK0wXOCFx1VhES4nJ7 yFT8VF7NmR6mmx+YKzM2Hddj4JcDVp7SH0/3JgiBvy3nxY8YsD2HuBsD3YDuDlLP QRaI3TJI4nPoSIR8lBdyrJU= Received: (qmail 6198 invoked by alias); 10 Jan 2020 14:13:21 -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 6186 invoked by uid 89); 10 Jan 2020 14:13:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=280100 X-HELO: mail-wr1-f50.google.com Received: from mail-wr1-f50.google.com (HELO mail-wr1-f50.google.com) (209.85.221.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 10 Jan 2020 14:13:19 +0000 Received: by mail-wr1-f50.google.com with SMTP id b6so1978254wrq.0 for ; Fri, 10 Jan 2020 06:13:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=FovwxwMQcHb252U3Dot2sCy5F8tmyoPtQcVVVTOkvKM=; b=PamOMbL1plf49u9/vd59+GjEGDWMgyOOTLGTLx49VpY4kOjXqgT2cm3HDWKZuyAkPG EOm1bT45NVoaD3sK2f1iwu9t/wBtcKX29jUOavQUmfdj1VXCGMbFkonK3Svx5n7pEgh2 4C4eWkhdAM+8MZNDmxa9zhyOiz1EtZklIRtjfrtiF4PE2qqXdQnxCcGRinAWgpM32OY7 9dwFWOghz4mEHFso6xFbE19RbyDVKx0wbVWFdjhE4vyj9Q0s5QWbYSio7D0eccmZtQ98 45WAChwNriq+LE5EzjPwuutlrl3IQdVm1Py3TWgIngShv/4NpDx/y90xBy0hlO6KcvHa C+Bw== Received: from ?IPv6:2a02:8084:d6bd:2b80:df53:c350:cc3e:ee3d? ([2a02:8084:d6bd:2b80:df53:c350:cc3e:ee3d]) by smtp.gmail.com with ESMTPSA id i10sm2412130wru.16.2020.01.10.06.13.16 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 10 Jan 2020 06:13:16 -0800 (PST) To: gcc-patches@gcc.gnu.org From: Martin Sebor Subject: [PATCH] allow nul-over-nul elimination only for single-byte stores (PR 93213) Message-ID: <897daca7-4104-2513-463e-a271213300aa@gmail.com> Date: Fri, 10 Jan 2020 14:13:16 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 X-IsSubscribed: yes The multi-byte store enhancement to the strlen optimization checked sometime last summer didn't take care to prevent the nul-over-nul store elimination of multi-byte assignments. This made it possible for subsequent multi-byte stores of fewer nuls to cause prior larger stores to be eliminated. The latent bug was exposed by a small unrelated change last December that had masked it until then. The attached patch makes sure that only single-byte nul stores are considered as candidates for this elimination. I will commit it next week if there are no concerns or suggestions. Martin PR tree-optimization/93213 - wrong code with -Og -foptimize-strlen gcc/testsuite/ChangeLog: PR tree-optimization/93213 * gcc.c-torture/execute/pr93213.c: New test. gcc/ChangeLog: PR tree-optimization/93213 * tree-ssa-strlen.c (handle_store): Only allow single-byte nul-over-nul stores to be eliminated. Index: gcc/testsuite/gcc.c-torture/execute/pr93213.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/pr93213.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr93213.c (working copy) @@ -0,0 +1,45 @@ +/* PR tree-optimization/93213 - wrong code on a multibyte store with + -Og -foptimize-strlen + { dg-additional-options "-Og -foptimize-strlen" } */ + +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned __int128 u128; + +static inline u128 +foo (u16 u16_1, u32 u32_1, u128 u128_1) +{ + u128 u128_0 = 0; + u128_1 -= __builtin_mul_overflow (u32_1, u16_1, &u32_1); + __builtin_memmove (&u16_1, &u128_0, 2); + __builtin_memmove (&u16_1, &u128_1, 1); + return u16_1; +} + +__attribute__ ((noipa)) void +bar (void) +{ + char a[] = { 1, 2 }; + const char b[] = { 0, 0 }; + const char c[] = { 2 }; + __builtin_memcpy (a, b, 2); + // The above is transformed into + // MEM [(char * {ref-all})&a] = 0; + // which was then dropped because of the non-nul store below. + __builtin_memcpy (a, c, 1); + + volatile char *p = a; + if (p[0] != 2 || p[1] != 0) + __builtin_abort (); +} + +int +main (void) +{ + u16 x = foo (-1, -1, 0); + if (x != 0xff) + __builtin_abort (); + + bar (); + return 0; +} Index: gcc/tree-ssa-strlen.c =================================================================== --- gcc/tree-ssa-strlen.c (revision 280100) +++ gcc/tree-ssa-strlen.c (working copy) @@ -5239,10 +5239,10 @@ handle_store (gimple_stmt_iterator *gsi, bool *zer } } - if (si != NULL && offset == 0 && storing_all_zeros_p) + if (si != NULL && offset == 0 && storing_all_zeros_p && lenrange[2] == 1) { - /* Allow adjust_last_stmt to remove it if the stored '\0' - is immediately overwritten. */ + /* For single-byte stores only, allow adjust_last_stmt to remove + the statement if the stored '\0' is immediately overwritten. */ laststmt.stmt = stmt; laststmt.len = build_int_cst (size_type_node, 1); laststmt.stridx = si->idx;