From patchwork Fri Jul 19 17:04:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 1134213 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-505348-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="txX/LK9d"; 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 45qy6R35Jqz9s4Y for ; Sat, 20 Jul 2019 03:04:45 +1000 (AEST) 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:message-id:date:mime-version:content-type; q=dns; s= default; b=xAV4nN0gS7nLOfktXhc7REh/h114TPh97ZISoenSaA+uMJ60Wxxf8 mGqp53DttTfWOJ8DnMM7RCG5xHaAx1L07xVbtGLirizdY6KfWb0X0ir6Q8T5F3/7 iGdeR8WcYm17A64ULDcwKpgjrLQ5/Anko9RUfSLXbU+1YBfH1y1oag= 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:message-id:date:mime-version:content-type; s= default; bh=7zg+m0Jy3sXk9lW1jlo0/8aj0MA=; b=txX/LK9dZTYSv0hDIF/a gg0kTxfe/aXlHCkReA7qmML7BhtMZRhGPamJ8nLE2CzvCN2QYJ7fD8ptm+MZkpvo xK30D0+Wmr4KIvA1uGRHwwrNMKPNyoY5MwmqOysSk+4eQAcqZtud4wgx6ns1p9ai jPZBjkBiJSh3vQYJ2S6SAfA= Received: (qmail 105509 invoked by alias); 19 Jul 2019 17:04:37 -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 105501 invoked by uid 89); 19 Jul 2019 17:04:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-14.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=treessadsec, UD:tree-ssa-dse.c, vice, tree-ssa-dse.c X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 19 Jul 2019 17:04:35 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4B13A30C134B for ; Fri, 19 Jul 2019 17:04:34 +0000 (UTC) Received: from localhost.localdomain (ovpn-112-9.rdu2.redhat.com [10.10.112.9]) by smtp.corp.redhat.com (Postfix) with ESMTP id B46C45C207 for ; Fri, 19 Jul 2019 17:04:33 +0000 (UTC) From: Jeff Law Openpgp: preference=signencrypt To: gcc-patches Subject: Handle strncpy in tree-ssa-dse.c Message-ID: Date: Fri, 19 Jul 2019 11:04:32 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 MIME-Version: 1.0 X-IsSubscribed: yes While looking at BZ 80576 I realized a few things. First for STRNCPY we know the exact count of bytes written and we can treat it just like MEMCPY and others, both in terms of removing/trimming them and in terms of using them to allow removal of other stores. This patch adds support for those routines in DSE. We test that subsequent statements can make those calls dead and vice versa and that we can trim from the head or tail appropriately. While writing that code I also stumbled over a blob of code that I think I copied from tree-ssa-alias.c that isn't necessary. In the relevant code the byte count is always found in the same place. There's no need to check the number of operands to the call to figure out where the count would be. So that little blob of code is simplified ever so slightly. Finally, while writing the tests for strncpy I stumbled over a case that we're still not handling well. In particular something like this: void h (char *s) { extern char a[8]; __builtin_memset (a, 0, sizeof a); __builtin_strncpy (a, s, sizeof a); frob (a); } In this case ref_maybe_used_by_stmt_p returns true for the "a" array at the strncpy call. AFAICT that appears to happen because "a" and "s" could alias each other. strncpy is documented as not allowing overlap between the source and destination objects. So in theory we could consider them not aliasing for this call. I haven't implemented this, but I've got some ideas here. Anyway, I've included an xfailed test for this case in this patch. Bootstrapped and regression tested on x86_64, ppc64, ppc64le, aarch64 & sparc64. Installing on the trunk momentarily. We could in theory handle stpncpy too, we just have to be more careful with its return value. Jeff commit 844df9c9ed48c2c0e80b633eb4f513d1228ef62d Author: Jeff Law Date: Fri Jul 19 11:03:10 2019 -0600 * tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle strncpy. Drop some trivial dead code. (maybe_trim_memstar_call): Handle strncpy. * gcc.dg/tree-ssa/ssa-dse-37.c: New test. * gcc.dg/tree-ssa/ssa-dse-38.c: New test. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 08f91ed32db..d8f60042ac1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-07-19 Jeff Law + + * tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle + strncpy. Drop some trivial dead code. + (maybe_trim_memstar_call): Handle strncpy. + 2019-07-19 Richard Biener PR tree-optimization/91211 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 98fb40ddd96..ce8e3c781b9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-19 Jeff Law + + * gcc.dg/tree-ssa/ssa-dse-37.c: New test. + * gcc.dg/tree-ssa/ssa-dse-38.c: New test. + 2019-07-19 Richard Biener PR tree-optimization/91211 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c new file mode 100644 index 00000000000..56251fc340f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c @@ -0,0 +1,60 @@ +/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */ + + +#ifndef SCOPE +#define SCOPE +#endif + +extern void frob (char *); + +void g (char *s) +{ + SCOPE char a[8]; + __builtin_strncpy (a, s, sizeof a); + __builtin_memset (a, 0, sizeof a); + frob (a); +} + +void h (char *s) +{ + SCOPE char a[8]; + __builtin_memset (a, 0, sizeof a); + __builtin_strncpy (a, s, sizeof a); + frob (a); +} + +void i (char *s) +{ + SCOPE char a[8]; + __builtin_strncpy (a, s, sizeof a); + __builtin_memset (a, 0, sizeof a - 5); + frob (a); +} + +void j (char *s) +{ + SCOPE char a[8]; + __builtin_memset (a, 0, sizeof a); + __builtin_strncpy (a, s, sizeof a - 5); + frob (a); +} + +void l (char *s) +{ + SCOPE char a[8]; + __builtin_strncpy (a, s, sizeof a); + __builtin_memset (a + 2, 0, sizeof a - 2); + frob (a); +} + +void m (char *s) +{ + SCOPE char a[8]; + __builtin_memset (a, 0, sizeof a); + __builtin_strncpy (a + 2, s, sizeof a - 2); + frob (a); +} + +/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" } } */ +/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" } } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c new file mode 100644 index 00000000000..7ae33bfd169 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c @@ -0,0 +1,12 @@ +/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */ + + +/* This changes the scope of the destination object and exposes + missed optimizations in DSE. */ +#define SCOPE extern +#include "ssa-dse-37.c" + +/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" { xfail *-*-* } } } */ + + diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 9bdcf9ae6af..5b7c4fc6d1a 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -113,10 +113,10 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write) case BUILT_IN_MEMCPY_CHK: case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMSET_CHK: + case BUILT_IN_STRNCPY: + case BUILT_IN_STRNCPY_CHK: { - tree size = NULL_TREE; - if (gimple_call_num_args (stmt) == 3) - size = gimple_call_arg (stmt, 2); + tree size = gimple_call_arg (stmt, 2); tree ptr = gimple_call_arg (stmt, 0); ao_ref_init_from_ptr_and_size (write, ptr, size); return true; @@ -469,8 +469,10 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt) { case BUILT_IN_MEMCPY: case BUILT_IN_MEMMOVE: + case BUILT_IN_STRNCPY: case BUILT_IN_MEMCPY_CHK: case BUILT_IN_MEMMOVE_CHK: + case BUILT_IN_STRNCPY_CHK: { int head_trim, tail_trim; compute_trims (ref, live, &head_trim, &tail_trim, stmt); @@ -966,9 +968,11 @@ dse_dom_walker::dse_optimize_stmt (gimple_stmt_iterator *gsi) { case BUILT_IN_MEMCPY: case BUILT_IN_MEMMOVE: + case BUILT_IN_STRNCPY: case BUILT_IN_MEMSET: case BUILT_IN_MEMCPY_CHK: case BUILT_IN_MEMMOVE_CHK: + case BUILT_IN_STRNCPY_CHK: case BUILT_IN_MEMSET_CHK: { /* Occasionally calls with an explicit length of zero