From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28131 invoked by alias); 26 Jun 2015 10:54:49 -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 28116 invoked by uid 89); 26 Jun 2015 10:54:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_50,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.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; Fri, 26 Jun 2015 10:54:47 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4AA26AC27 for ; Fri, 26 Jun 2015 10:54:44 +0000 (UTC) Date: Fri, 26 Jun 2015 10:57:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH][5/n] Remove GENERIC stmt combining from SCCVN 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-06/txt/msg01932.txt.bz2 This moves some equality comparison patterns from fold-const.c to match.pd. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2015-06-26 Richard Biener * fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B and -A CMP CST -> A CMP -CST which is redundant with a pattern in match.pd. Move (A | C) == D where C & ~D != 0 -> 0, (X ^ Y) ==/!= 0 -> X ==/!= Y, (X ^ Y) ==/!= {Y,X} -> {X,Y} ==/!= 0 and (X ^ C1) op C2 -> X op (C1 ^ C2) to ... * match.pd: ... patterns here. * gcc.dg/tree-ssa/forwprop-25.c: Adjust. Index: gcc/fold-const.c =================================================================== *** gcc/fold-const.c (revision 224943) --- gcc/fold-const.c (working copy) *************** fold_binary_loc (location_t loc, *** 12165,12179 **** type); } - /* Similarly for a NEGATE_EXPR. */ - if (TREE_CODE (arg0) == NEGATE_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && 0 != (tem = negate_expr (fold_convert_loc (loc, TREE_TYPE (arg0), - arg1))) - && TREE_CODE (tem) == INTEGER_CST - && !TREE_OVERFLOW (tem)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem); - /* Similarly for a BIT_XOR_EXPR; X ^ C1 == C2 is X == (C1 ^ C2). */ if (TREE_CODE (arg0) == BIT_XOR_EXPR && TREE_CODE (arg1) == INTEGER_CST --- 12165,12170 ---- *************** fold_binary_loc (location_t loc, *** 12358,12379 **** return omit_one_operand_loc (loc, type, rslt, arg0); } - /* If we have (A | C) == D where C & ~D != 0, convert this into 0. - Similarly for NE_EXPR. */ - if (TREE_CODE (arg0) == BIT_IOR_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - { - tree notd = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1), arg1); - tree candnotd - = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), - TREE_OPERAND (arg0, 1), - fold_convert_loc (loc, TREE_TYPE (arg0), notd)); - tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node; - if (integer_nonzerop (candnotd)) - return omit_one_operand_loc (loc, type, rslt, arg0); - } - /* If this is a comparison of a field, we may be able to simplify it. */ if ((TREE_CODE (arg0) == COMPONENT_REF || TREE_CODE (arg0) == BIT_FIELD_REF) --- 12349,12354 ---- *************** fold_binary_loc (location_t loc, *** 12431,12462 **** } } - /* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y. */ - if (integer_zerop (arg1) - && TREE_CODE (arg0) == BIT_XOR_EXPR) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - TREE_OPERAND (arg0, 1)); - - /* (X ^ Y) == Y becomes X == 0. We know that Y has no side-effects. */ - if (TREE_CODE (arg0) == BIT_XOR_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - build_zero_cst (TREE_TYPE (arg0))); - /* Likewise (X ^ Y) == X becomes Y == 0. X has no side-effects. */ - if (TREE_CODE (arg0) == BIT_XOR_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) - && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 1), - build_zero_cst (TREE_TYPE (arg0))); - - /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ - if (TREE_CODE (arg0) == BIT_XOR_EXPR - && TREE_CODE (arg1) == INTEGER_CST - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), - fold_build2_loc (loc, BIT_XOR_EXPR, TREE_TYPE (arg1), - TREE_OPERAND (arg0, 1), arg1)); - /* Fold (~X & C) == 0 into (X & C) != 0 and (~X & C) != 0 into (X & C) == 0 when C is a single bit. */ if (TREE_CODE (arg0) == BIT_AND_EXPR --- 12406,12411 ---- *************** fold_binary_loc (location_t loc, *** 12510,12523 **** return omit_one_operand_loc (loc, type, res, arg0); } - /* Fold -X op -Y as X op Y, where op is eq/ne. */ - if (TREE_CODE (arg0) == NEGATE_EXPR - && TREE_CODE (arg1) == NEGATE_EXPR) - return fold_build2_loc (loc, code, type, - TREE_OPERAND (arg0, 0), - fold_convert_loc (loc, TREE_TYPE (arg0), - TREE_OPERAND (arg1, 0))); - /* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries. */ if (TREE_CODE (arg0) == BIT_AND_EXPR && TREE_CODE (arg1) == BIT_AND_EXPR) --- 12459,12464 ---- Index: gcc/match.pd =================================================================== *** gcc/match.pd (revision 224943) --- gcc/match.pd (working copy) *************** (define_operator_list swapped_tcc_compar *** 1197,1202 **** --- 1197,1231 ---- (if (tem && !TREE_OVERFLOW (tem)) (scmp @0 { tem; })))))) + + /* Equality compare simplifications from fold_binary */ + (for cmp (eq ne) + + /* If we have (A | C) == D where C & ~D != 0, convert this into 0. + Similarly for NE_EXPR. */ + (simplify + (cmp (convert?@3 (bit_ior @0 INTEGER_CST@1)) INTEGER_CST@2) + (if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0)) + && wi::bit_and_not (@1, @2) != 0) + { constant_boolean_node (cmp == NE_EXPR, type); })) + + /* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y. */ + (simplify + (cmp (bit_xor @0 @1) integer_zerop) + (cmp @0 @1)) + + /* (X ^ Y) == Y becomes X == 0. + Likewise (X ^ Y) == X becomes Y == 0. */ + (simplify + (cmp (bit_xor:c @0 @1) @0) + (cmp @1 { build_zero_cst (TREE_TYPE (@1)); })) + + /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */ + (simplify + (cmp (convert?@3 (bit_xor @0 INTEGER_CST@1)) INTEGER_CST@2) + (if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0))) + (cmp @0 (bit_xor @1 (convert @2)))))) + /* Simplification of math builtins. */ (define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL) Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c (revision 224942) --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c (working copy) *************** *** 1,5 **** /* { dg-do compile } */ ! /* { dg-options "-O1 -fdump-tree-forwprop1" } */ struct rtx_def; typedef struct rtx_def *rtx; --- 1,5 ---- /* { dg-do compile } */ ! /* { dg-options "-O1 -fdump-tree-cddce1" } */ struct rtx_def; typedef struct rtx_def *rtx; *************** convert_move (rtx to, rtx from, int unsi *** 37,43 **** 0 : 0)); } ! /* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} } */ ! ! ! --- 37,40 ---- 0 : 0)); } ! /* { dg-final { scan-tree-dump-not " ^ " "cddce1"} } */