From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 56840 invoked by alias); 23 Nov 2015 15:17:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 56829 invoked by uid 89); 23 Nov 2015 15:17:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL,BAYES_00,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_LOW,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Mon, 23 Nov 2015 15:17:24 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 93E3EAAC4 for ; Mon, 23 Nov 2015 15:16:13 +0000 (UTC) Date: Mon, 23 Nov 2015 15:22:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix problem reported in PR68465 Message-ID: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2015-11/txt/msg02742.txt.bz2 The following fixes CH - FRE - LIM not doing store-motion across a loop nest for redundant header checks. FRE is supposed to do such redundant comparison "threading" but didn't do it because of latch edges confusing the single_pred_p check. The following fixes it by disregarding edges that come from blocks we dominate. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2015-11-23 Richard Biener PR tree-optimization/68465 * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Also record equalities from multiple predecessor blocks if only one non-backedge exists. * gcc.dg/tree-ssa/ssa-fre-52.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 230737) --- gcc/tree-ssa-sccvn.c (working copy) *************** sccvn_dom_walker::before_dom_children (b *** 4357,4376 **** /* If we have a single predecessor record the equivalence from a possible condition on the predecessor edge. */ ! if (single_pred_p (bb)) { - edge e = single_pred_edge (bb); /* Check if there are multiple executable successor edges in the source block. Otherwise there is no additional info to be recorded. */ edge e2; ! FOR_EACH_EDGE (e2, ei, e->src->succs) ! if (e2 != e && e2->flags & EDGE_EXECUTABLE) break; if (e2 && (e2->flags & EDGE_EXECUTABLE)) { ! gimple *stmt = last_stmt (e->src); if (stmt && gimple_code (stmt) == GIMPLE_COND) { --- 4402,4435 ---- /* If we have a single predecessor record the equivalence from a possible condition on the predecessor edge. */ ! edge pred_e = NULL; ! FOR_EACH_EDGE (e, ei, bb->preds) ! { ! /* Ignore simple backedges from this to allow recording conditions ! in loop headers. */ ! if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest)) ! continue; ! if (! pred_e) ! pred_e = e; ! else ! { ! pred_e = NULL; ! break; ! } ! } ! if (pred_e) { /* Check if there are multiple executable successor edges in the source block. Otherwise there is no additional info to be recorded. */ edge e2; ! FOR_EACH_EDGE (e2, ei, pred_e->src->succs) ! if (e2 != pred_e && e2->flags & EDGE_EXECUTABLE) break; if (e2 && (e2->flags & EDGE_EXECUTABLE)) { ! gimple *stmt = last_stmt (pred_e->src); if (stmt && gimple_code (stmt) == GIMPLE_COND) { *************** sccvn_dom_walker::before_dom_children (b *** 4378,4388 **** tree lhs = gimple_cond_lhs (stmt); tree rhs = gimple_cond_rhs (stmt); record_conds (bb, code, lhs, rhs, ! (e->flags & EDGE_TRUE_VALUE) != 0); code = invert_tree_comparison (code, HONOR_NANS (lhs)); if (code != ERROR_MARK) record_conds (bb, code, lhs, rhs, ! (e->flags & EDGE_TRUE_VALUE) == 0); } } } --- 4437,4447 ---- tree lhs = gimple_cond_lhs (stmt); tree rhs = gimple_cond_rhs (stmt); record_conds (bb, code, lhs, rhs, ! (pred_e->flags & EDGE_TRUE_VALUE) != 0); code = invert_tree_comparison (code, HONOR_NANS (lhs)); if (code != ERROR_MARK) record_conds (bb, code, lhs, rhs, ! (pred_e->flags & EDGE_TRUE_VALUE) == 0); } } } Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-52.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-52.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-52.c (working copy) *************** *** 0 **** --- 1,26 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-fre1" } */ + + void bar (); + void foo (int n) + { + if (n > 0) + { + int j = 0; + do + { + if (n > 0) + { + int i = 0; + do + { + bar (); + } + while (i < n); + } + } + while (j < n); + } + } + + /* { dg-final { scan-tree-dump-times "if" 1 "fre1" } } */