From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17058 invoked by alias); 7 Sep 2011 11:47:09 -0000 Received: (qmail 17050 invoked by uid 22791); 7 Sep 2011 11:47:08 -0000 X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,TW_TM X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 07 Sep 2011 11:46:50 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id BE87A8F3B5 for ; Wed, 7 Sep 2011 13:46:49 +0200 (CEST) Date: Wed, 07 Sep 2011 11:55:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH] Propagate out predicate inversions in forwprop Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 X-SW-Source: 2011-09/txt/msg00479.txt.bz2 This makes sure that we propagate comparisons that we cannot invert into inverted conditions by swapping edges or the conditional ops. For the testcase it transforms : D.2724_4 = xx_2(D) < xy_3(D); p_5 = (int) D.2724_4; D.2725_6 = p_5 == 0; np_7 = (int) D.2725_6; if (np_7 != 0) to : if (xx_2(D) < xy_3(D)) while without the patch we would be left with : D.2724_4 = xx_2(D) < xy_3(D); if (D.2724_4 == 0) Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu. Richard. 2011-09-07 Richard Guenther * tree-ssa-forwprop.c (forward_propagate_into_gimple_cond): Canonicalize negated predicates by swapping edges. (forward_propagate_into_cond): Likewise. * gcc.dg/tree-ssa/forwprop-16.c: New testcase. Index: gcc/tree-ssa-forwprop.c =================================================================== *** gcc/tree-ssa-forwprop.c (revision 178633) --- gcc/tree-ssa-forwprop.c (working copy) *************** forward_propagate_into_gimple_cond (gimp *** 534,539 **** --- 534,556 ---- return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1; } + /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges. */ + if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE + || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) + && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1)) + && ((code == EQ_EXPR + && integer_zerop (rhs2)) + || (code == NE_EXPR + && integer_onep (rhs2)))) + { + basic_block bb = gimple_bb (stmt); + gimple_cond_set_code (stmt, NE_EXPR); + gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1))); + EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); + EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); + return 1; + } + return 0; } *************** forward_propagate_into_cond (gimple_stmt *** 548,553 **** --- 565,571 ---- gimple stmt = gsi_stmt (*gsi_p); tree tmp = NULL_TREE; tree cond = gimple_assign_rhs1 (stmt); + bool swap = false; /* We can do tree combining on SSA_NAME and comparison expressions. */ if (COMPARISON_CLASS_P (cond)) *************** forward_propagate_into_cond (gimple_stmt *** 557,573 **** TREE_OPERAND (cond, 1)); else if (TREE_CODE (cond) == SSA_NAME) { tree name = cond; gimple def_stmt = get_prop_source_stmt (name, true, NULL); if (!def_stmt || !can_propagate_from (def_stmt)) return 0; ! if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison) tmp = fold_build2_loc (gimple_location (def_stmt), ! gimple_assign_rhs_code (def_stmt), boolean_type_node, gimple_assign_rhs1 (def_stmt), gimple_assign_rhs2 (def_stmt)); } if (tmp) --- 575,601 ---- TREE_OPERAND (cond, 1)); else if (TREE_CODE (cond) == SSA_NAME) { + enum tree_code code; tree name = cond; gimple def_stmt = get_prop_source_stmt (name, true, NULL); if (!def_stmt || !can_propagate_from (def_stmt)) return 0; ! code = gimple_assign_rhs_code (def_stmt); ! if (TREE_CODE_CLASS (code) == tcc_comparison) tmp = fold_build2_loc (gimple_location (def_stmt), ! code, boolean_type_node, gimple_assign_rhs1 (def_stmt), gimple_assign_rhs2 (def_stmt)); + else if ((code == BIT_NOT_EXPR + && TYPE_PRECISION (TREE_TYPE (cond)) == 1) + || (code == BIT_XOR_EXPR + && integer_onep (gimple_assign_rhs2 (def_stmt)))) + { + tmp = gimple_assign_rhs1 (def_stmt); + swap = true; + } } if (tmp) *************** forward_propagate_into_cond (gimple_stmt *** 586,592 **** else if (integer_zerop (tmp)) gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt)); else ! gimple_assign_set_rhs1 (stmt, unshare_expr (tmp)); stmt = gsi_stmt (*gsi_p); update_stmt (stmt); --- 614,628 ---- else if (integer_zerop (tmp)) gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt)); else ! { ! gimple_assign_set_rhs1 (stmt, unshare_expr (tmp)); ! if (swap) ! { ! tree t = gimple_assign_rhs2 (stmt); ! gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt)); ! gimple_assign_set_rhs3 (stmt, t); ! } ! } stmt = gsi_stmt (*gsi_p); update_stmt (stmt); Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-16.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/forwprop-16.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-16.c (revision 0) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-forwprop1" } */ + + int foo (double xx, double xy) + { + int p = xx < xy; + int np = !p; + if (np) + return 5; + return 2; + } + + /* { dg-final { scan-tree-dump "if \\\(x" "forwprop1" } } */ + /* { dg-final { cleanup-tree-dump "forwprop1" } } */