From patchwork Mon Oct 10 21:06:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 680567 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3stCNn5K16z9sBR for ; Tue, 11 Oct 2016 08:06:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=eULFHqef; dkim-atps=neutral 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=ljTnLuFC9w+Cltpv8/icyDISvGQS/ZGHkLL8miTuXHqLxT1vmk wpO1S2QkQA2TadRCZHSAauEREbm31Bv/K++08TFdLWYOTxrHVdrwHUdeu/KTJHuA ROk6q9dtZN+h338+lu2ggQT+LOqfiTfCS6lb35N5pn9qFR3rCi/3BPjpM= 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=+uaXwk6scHczvQGfQZiyA6tSFz0=; b=eULFHqefYiLq6HM3TFyr 6f3OGKskSjIOBMDaLYRg8b22D3fzbIz1PVbwhzuNQyVDfSmiWqV+4m0zUcX4itQJ VHIJWWvKI/NMygHaciJrXqvgJcr2qrk46uho8Zo4KlTRXHJ4l1x6PdqgDvslSQvk FYdwy3M2CXyEf8QVpSS/NhE= Received: (qmail 88710 invoked by alias); 10 Oct 2016 21:06:38 -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 88694 invoked by uid 89); 10 Oct 2016 21:06:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=U*law, xfailed, Applied, law@redhat.com 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; Mon, 10 Oct 2016 21:06:33 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B259D74A2D for ; Mon, 10 Oct 2016 21:06:31 +0000 (UTC) Received: from localhost.localdomain (ovpn-116-144.phx2.redhat.com [10.3.116.144]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9AL6Vr2019655 for ; Mon, 10 Oct 2016 17:06:31 -0400 To: gcc-patches From: Jeff Law Subject: [tree-optimization/71947] Avoid unwanted propagations Message-ID: <93897686-686e-ddae-6f32-9e6ee2ad8981@redhat.com> Date: Mon, 10 Oct 2016 15:06:30 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 X-IsSubscribed: yes So if we have an equality conditional between A & B, we record into our const/copy tables A = B and B = A. This helps us discover some of the more obscure equivalences. But it also creates problems with an expression like A ^ B Where we might cprop the first operand generating B ^ B Then the second generating B ^ A ANd we've lost the folding opportunity. At first I'd tried folding after each propagation step, but that turns into a bit of a nightmare because of changes in the underlying structure of the gimple statement and cycles that may develop if we re-build the operand cache after folding. This approach is simpler and should catch all these cases for binary operators. We just track the last copy propagated argument and refuse to ping-pong propagations. It fixes the tests from 71947 and 77647 without regressing (obviously). I've included an xfailed test for a more complex situation that we don't currently handle (would require backtracking from the equality comparison through the logicals that feed the equality comparison). Bootstrapped and regression tested on x86_64. Applied to the trunk. commit 6223e6e425b6de916f0330b9dbe5698765d4a73c Author: law Date: Mon Oct 10 20:40:59 2016 +0000 PR tree-optimization/71947 * tree-ssa-dom.c (cprop_into_stmt): Avoid replacing A with B, then B with A within a single statement. PR tree-optimization/71947 * gcc.dg/tree-ssa/pr71947-1.c: New test. * gcc.dg/tree-ssa/pr71947-2.c: New test. * gcc.dg/tree-ssa/pr71947-3.c: New test. * gcc.dg/tree-ssa/pr71947-4.c: New test. * gcc.dg/tree-ssa/pr71947-5.c: New test. * gcc.dg/tree-ssa/pr71947-6.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240947 138bc75d-0d04-0410-961f-82ee72b054a4 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1738bc7..16e25bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-10-10 Jeff Law + + PR tree-optimization/71947 + * tree-ssa-dom.c (cprop_into_stmt): Avoid replacing A with B, then + B with A within a single statement. + 2016-10-10 Bill Schmidt PR tree-optimization/77824 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 04966cf..e31bcc6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2016-10-10 Jeff Law + + PR tree-optimization/71947 + * gcc.dg/tree-ssa/pr71947-1.c: New test. + * gcc.dg/tree-ssa/pr71947-2.c: New test. + * gcc.dg/tree-ssa/pr71947-3.c: New test. + * gcc.dg/tree-ssa/pr71947-4.c: New test. + * gcc.dg/tree-ssa/pr71947-5.c: New test. + * gcc.dg/tree-ssa/pr71947-6.c: New test. + 2016-10-10 Thomas Koenig PR fortran/77915 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-1.c new file mode 100644 index 0000000..b033495 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ + + +int f(int x, int y) +{ + int ret; + + if (x == y) + ret = x ^ y; + else + ret = 1; + + return ret; +} + +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-2.c new file mode 100644 index 0000000..de8f88b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ + + +int f(int x, int y) +{ + int ret; + if (x == y) + ret = x - y; + else + ret = 1; + + return ret; +} + +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-3.c new file mode 100644 index 0000000..e79847f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ + +int f(int x, int y) +{ + int ret = 10; + if (x == y) + ret = x - y; + return ret; +} + +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-4.c new file mode 100644 index 0000000..a881f0d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ + + + +static inline long load(long *p) +{ + long ret; + asm ("movq %1,%0\n\t" : "=r" (ret) : "m" (*p)); + if (ret != *p) + __builtin_unreachable(); + return ret; +} + +long foo(long *mem) +{ + long ret; + ret = load(mem); + return ret + *mem; +} + +/* { dg-final { scan-tree-dump "Folded to: _\[0-9\]+ = _\[0-9\]+ \\* 2" "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-5.c new file mode 100644 index 0000000..fa679f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-5.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ + + +static inline long load(long *p) +{ + long ret; + asm ("movq %1,%0\n\t" : "=r" (ret) : "m" (*p)); + if (ret != *p) + __builtin_unreachable(); + return ret; +} + +long foo(long *mem) +{ + long ret; + ret = load(mem); + return ret - *mem; +} + +/* { dg-final { scan-tree-dump "Folded to: _\[0-9\]+ = 0;" "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-6.c new file mode 100644 index 0000000..9cb89cb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-6.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ + + +int f(int x, int y, int a, int b) +{ + int ret = 10; + if (a == x + && b == y + && a == b) + ret = x - y; + + return ret; +} + +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" { xfail *-*-* } } } */ diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index b007388..5376ff9 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1731,9 +1731,26 @@ cprop_into_stmt (gimple *stmt) { use_operand_p op_p; ssa_op_iter iter; + tree last_copy_propagated_op = NULL; FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE) - cprop_operand (stmt, op_p); + { + tree old_op = USE_FROM_PTR (op_p); + + /* If we have A = B and B = A in the copy propagation tables + (due to an equality comparison), avoid substituting B for A + then A for B in the trivially discovered cases. This allows + optimization of statements were A and B appear as input + operands. */ + if (old_op != last_copy_propagated_op) + { + cprop_operand (stmt, op_p); + + tree new_op = USE_FROM_PTR (op_p); + if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME) + last_copy_propagated_op = new_op; + } + } } /* Optimize the statement in block BB pointed to by iterator SI