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 82ca6cb44f5..e29e4c327bf 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 2ed556b2730..af1af3382ad 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5928,6 +5928,40 @@ 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 a sign testing. Otherwise return NULL. TYPE is the desired + 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))) + { + /* 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. */ + 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. */ + && TYPE_PRECISION (TREE_TYPE (arg00)) + == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00)))) + { + tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00)); + return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR, + 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 @@ -5948,22 +5982,14 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, enum machine_mode operand_mode = TYPE_MODE (type); int ops_unsigned; tree signed_type, unsigned_type, intermediate_type; - tree arg00; + tree tem; - /* 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)); - 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. */ - && TYPE_PRECISION (TREE_TYPE (arg00)) - == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00)))) - { - tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00)); - return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR, - result_type, fold_convert (stype, arg00), - fold_convert (stype, integer_zero_node)); - } + /* 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;