Commit a94400fd by Kazu Hirata Committed by Kazu Hirata

re PR tree-optimization/14846 ([tree-ssa] don't use a shift in A &…

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
parent fcda2002
2005-04-21 Kazu Hirata <kazu@cs.umass.edu>
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 <wilson@specifixinc.com> 2005-04-20 James E Wilson <wilson@specifixinc.com>
PR c++/20805 PR c++/20805
......
...@@ -5929,30 +5929,23 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) ...@@ -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 /* If CODE with arguments ARG0 and ARG1 represents a single bit
equality/inequality test, then return a simplified form of equality/inequality test, then return a simplified form of the test
the test using shifts and logical operations. Otherwise return using a sign testing. Otherwise return NULL. TYPE is the desired
NULL. TYPE is the desired result type. */ result type. */
tree static tree
fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, fold_single_bit_test_into_sign_test (enum tree_code code, tree arg0, tree arg1,
tree result_type) tree result_type)
{ {
/* If this is testing a single bit, we can optimize the test. */ /* If this is testing a single bit, we can optimize the test. */
if ((code == NE_EXPR || code == EQ_EXPR) if ((code == NE_EXPR || code == EQ_EXPR)
&& TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1) && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
&& integer_pow2p (TREE_OPERAND (arg0, 1))) && 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 /* 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. */ 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 if (arg00 != NULL_TREE
/* This is only a win if casting to a signed type is cheap, /* This is only a win if casting to a signed type is cheap,
i.e. when arg00's type is not a partial mode. */ 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, ...@@ -5964,6 +5957,39 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
result_type, fold_convert (stype, arg00), result_type, fold_convert (stype, arg00),
fold_convert (stype, integer_zero_node)); 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, /* Otherwise we have (A & C) != 0 where C is a single bit,
convert that into ((A >> C2) & 1). Where C2 = log2(C). 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) ...@@ -9447,9 +9473,9 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
arg0, fold_convert (TREE_TYPE (arg0), arg0, fold_convert (TREE_TYPE (arg0),
integer_zero_node)); integer_zero_node));
/* If we have (A & C) != 0 or (A & C) == 0 and C is a power of /* If we have (A & C) != 0 or (A & C) == 0 and C is the sign
2, then fold the expression into shifts and logical operations. */ bit, then fold the expression into A < 0 or A >= 0. */
tem = fold_single_bit_test (code, arg0, arg1, type); tem = fold_single_bit_test_into_sign_test (code, arg0, arg1, type);
if (tem) if (tem)
return tem; return tem;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment