From a94400fda31e4ac6cfa897141a4d14321fdb5fed Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 21 Apr 2005 00:39:22 +0000 Subject: [PATCH] re PR tree-optimization/14846 ([tree-ssa] don't use a shift in A & CST_POWER_OF_2 == 0 until very late in tree-ssa optimizations) PR tree-optimization/14846 * fold-const.c (fold_single_bit_test_into_sign_test): New, split out from ... (fold_single_bit_test): ... here. (fold_binary): Call fold_single_bit_test_into_sign_test instead of fold_single_bit_test. From-SVN: r98482 --- gcc/ChangeLog | 9 ++++++++ gcc/fold-const.c | 62 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 82ca6cb..e29e4c3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-04-21 Kazu Hirata + + PR tree-optimization/14846 + * fold-const.c (fold_single_bit_test_into_sign_test): New, + split out from ... + (fold_single_bit_test): ... here. + (fold_binary): Call fold_single_bit_test_into_sign_test + instead of fold_single_bit_test. + 2005-04-20 James E Wilson PR c++/20805 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2ed556b..af1af33 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5929,30 +5929,23 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) /* If CODE with arguments ARG0 and ARG1 represents a single bit - equality/inequality test, then return a simplified form of - the test using shifts and logical operations. Otherwise return - NULL. TYPE is the desired result type. */ + equality/inequality test, then return a simplified form of the test + using a sign testing. Otherwise return NULL. TYPE is the desired + result type. */ -tree -fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, - tree result_type) +static tree +fold_single_bit_test_into_sign_test (enum tree_code code, tree arg0, tree arg1, + tree result_type) { /* If this is testing a single bit, we can optimize the test. */ if ((code == NE_EXPR || code == EQ_EXPR) && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1) && integer_pow2p (TREE_OPERAND (arg0, 1))) { - tree inner = TREE_OPERAND (arg0, 0); - tree type = TREE_TYPE (arg0); - int bitnum = tree_log2 (TREE_OPERAND (arg0, 1)); - enum machine_mode operand_mode = TYPE_MODE (type); - int ops_unsigned; - tree signed_type, unsigned_type, intermediate_type; - tree arg00; - /* If we have (A & C) != 0 where C is the sign bit of A, convert this into A < 0. Similarly for (A & C) == 0 into A >= 0. */ - arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)); + tree arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)); + if (arg00 != NULL_TREE /* This is only a win if casting to a signed type is cheap, i.e. when arg00's type is not a partial mode. */ @@ -5964,6 +5957,39 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, result_type, fold_convert (stype, arg00), fold_convert (stype, integer_zero_node)); } + } + + return NULL_TREE; +} + +/* If CODE with arguments ARG0 and ARG1 represents a single bit + equality/inequality test, then return a simplified form of + the test using shifts and logical operations. Otherwise return + NULL. TYPE is the desired result type. */ + +tree +fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, + tree result_type) +{ + /* If this is testing a single bit, we can optimize the test. */ + if ((code == NE_EXPR || code == EQ_EXPR) + && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1) + && integer_pow2p (TREE_OPERAND (arg0, 1))) + { + tree inner = TREE_OPERAND (arg0, 0); + tree type = TREE_TYPE (arg0); + int bitnum = tree_log2 (TREE_OPERAND (arg0, 1)); + enum machine_mode operand_mode = TYPE_MODE (type); + int ops_unsigned; + tree signed_type, unsigned_type, intermediate_type; + tree tem; + + /* First, see if we can fold the single bit test into a sign-bit + test. */ + tem = fold_single_bit_test_into_sign_test (code, arg0, arg1, + result_type); + if (tem) + return tem; /* Otherwise we have (A & C) != 0 where C is a single bit, convert that into ((A >> C2) & 1). Where C2 = log2(C). @@ -9447,9 +9473,9 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) arg0, fold_convert (TREE_TYPE (arg0), integer_zero_node)); - /* If we have (A & C) != 0 or (A & C) == 0 and C is a power of - 2, then fold the expression into shifts and logical operations. */ - tem = fold_single_bit_test (code, arg0, arg1, type); + /* If we have (A & C) != 0 or (A & C) == 0 and C is the sign + bit, then fold the expression into A < 0 or A >= 0. */ + tem = fold_single_bit_test_into_sign_test (code, arg0, arg1, type); if (tem) return tem; -- 2.7.4