From patchwork Tue Aug 9 08:23:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 109162 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]) by ozlabs.org (Postfix) with SMTP id EA930B6F84 for ; Tue, 9 Aug 2011 18:23:28 +1000 (EST) Received: (qmail 24267 invoked by alias); 9 Aug 2011 08:23:25 -0000 Received: (qmail 24256 invoked by uid 22791); 9 Aug 2011 08:23:22 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_TM X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 09 Aug 2011 08:23:08 +0000 Received: by qwh5 with SMTP id 5so1475913qwh.20 for ; Tue, 09 Aug 2011 01:23:07 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.52.140 with SMTP id i12mr850479qcg.244.1312878187539; Tue, 09 Aug 2011 01:23:07 -0700 (PDT) Received: by 10.229.5.132 with HTTP; Tue, 9 Aug 2011 01:23:07 -0700 (PDT) In-Reply-To: References: <2141181079.338186.1311940751732.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> <1167286131.338432.1311941276860.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> Date: Tue, 9 Aug 2011 10:23:07 +0200 Message-ID: Subject: Re: [patch tree-optimization]: Fix for PR/49806 From: Kai Tietz To: Richard Guenther Cc: Kai Tietz , gcc-patches@gcc.gnu.org X-IsSubscribed: yes 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 Hello, actual the remaining issue about this PR is that vrp constructs by range analyzis for bitwise and/or expressions type-casted results, like ((type) A) op ((type) B), or ((type) A) op CST. So I've added to simplify_bit_ops_using_rnages the transformation of ((type) A) op ((type) B) -> (type) (A op B) ((type) A) op CST -> (type) (A op CST'), with CST'=(type-A) This first transformation is valid if A has an integral type, TYPE is of integral kind, and type of B has compatible type to type of A. The second transformation is valid if A has integral type, TYPE is of integral kind, and CST fits into type of A. 2011-08-09 Kai Tietz PR middle-end/49806 * tree-vrp.c (simplify_bit_ops_using_ranges): Add code for type-cast sinking for bitwise-operations. * gcc.dg/tree-ssa/vrp47.c: Remove dom-dump and adjusted scan test for vrp result. Bootstrapped and regression tested for all languages (including Ada and Obj-C++) on host x86_64-pc-linux-gnu. Ok for apply? Regards, Kai Index: gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c +++ gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c @@ -4,8 +4,8 @@ jumps when evaluating an && condition. VRP is not able to optimize this. */ /* { dg-do compile { target { ! "mips*-*-* s390*-*-* avr-*-* mn10300-*-*" } } } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-dom1" } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-dom1 -march=i586" { target { i?86-*-* && ilp32 } } } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -march=i586" { target { i?86-*-* && ilp32 } } } */ int h(int x, int y) { @@ -37,12 +37,10 @@ int f(int x) /* { dg-final { scan-tree-dump-times "\[xy\]\[^ \]* !=" 0 "vrp1" } } */ /* This one needs more copy propagation that only happens in dom1. */ -/* { dg-final { scan-tree-dump-times "x\[^ \]* & y" 1 "dom1" } } */ -/* { dg-final { scan-tree-dump-times "x\[^ \]* & y" 1 "vrp1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "x\[^ \]* & y" 1 "vrp1" } } */ /* These two are fully simplified by VRP. */ /* { dg-final { scan-tree-dump-times "x\[^ \]* \[|\] y" 1 "vrp1" } } */ /* { dg-final { scan-tree-dump-times "x\[^ \]* \\^ 1" 1 "vrp1" } } */ /* { dg-final { cleanup-tree-dump "vrp1" } } */ -/* { dg-final { cleanup-tree-dump "dom1" } } */ Index: gcc/gcc/tree-vrp.c =================================================================== --- gcc.orig/gcc/tree-vrp.c +++ gcc/gcc/tree-vrp.c @@ -6968,15 +6968,63 @@ simplify_abs_using_ranges (gimple stmt) static bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt) { + gimple def0, def1; tree op0 = gimple_assign_rhs1 (stmt); tree op1 = gimple_assign_rhs2 (stmt); - tree op = NULL_TREE; + tree op = NULL_TREE, nop0 = NULL_TREE, nop1 = NULL_TREE; value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }; value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }; double_int may_be_nonzero0, may_be_nonzero1; double_int must_be_nonzero0, must_be_nonzero1; double_int mask; + def0 = TREE_CODE (op0) == SSA_NAME ? SSA_NAME_DEF_STMT (op0) : NULL; + def1 = TREE_CODE (op1) == SSA_NAME ? SSA_NAME_DEF_STMT (op1) : NULL; + if (def0 && is_gimple_assign (def0)) + nop0 = gimple_assign_rhs1 (def0); + if (def1 && is_gimple_assign (def1)) + nop1 = gimple_assign_rhs1 (def1); + + /* Simplify ((type) X) op ((type) Y) -> (type) (X op Y), if X and Y have + compatible integral types. */ + if (nop0 != NULL_TREE && nop1 != NULL_TREE + && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def0)) + && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def1)) + && INTEGRAL_TYPE_P (TREE_TYPE (nop0)) + && types_compatible_p (TREE_TYPE (nop0), TREE_TYPE (nop1))) + { + gimple newop; + tree tem = create_tmp_reg (TREE_TYPE (nop0), NULL); + newop = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), + tem, nop0, nop1); + tem = make_ssa_name (tem, newop); + gimple_assign_set_lhs (newop, tem); + gsi_insert_before (gsi, newop, GSI_SAME_STMT); + update_stmt (newop); + gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem, NULL_TREE); + return true; + } + /* Simplify ((type) X) op CST -> (type) (X op (type-X) CST), if X has + an integral types. Additiona CST has to fit into type of X. */ + else if (nop0 != NULL_TREE && TREE_CODE (op1) == INTEGER_CST + && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def0)) + && INTEGRAL_TYPE_P (TREE_TYPE (nop0)) + && int_fits_type_p (op1, TREE_TYPE (nop0))) + { + tree nop0 = gimple_assign_rhs1 (def0); + tree nop1 = fold_convert (TREE_TYPE (nop0), op1); + gimple newop; + tree tem = create_tmp_reg (TREE_TYPE (nop0), NULL); + newop = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), + tem, nop0, nop1); + tem = make_ssa_name (tem, newop); + gimple_assign_set_lhs (newop, tem); + gsi_insert_before (gsi, newop, GSI_SAME_STMT); + update_stmt (newop); + gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem, NULL_TREE); + return true; + } + if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0))