re PR target/18002 ('while' loop performace regression on avr target)

PR target/18002
	PR middle-end/18424
	* dojump.c (do_jump): When attempting to reverse the effects of
	fold_single_bit_test, we need to STRIP_NOPS and narrowing type
	conversions, and handle BIT_XOR_EXPR that's used to invert the
	sense of the single bit test.

From-SVN: r92024
This commit is contained in:
Roger Sayle 2004-12-11 01:49:05 +00:00 committed by Roger Sayle
parent aa6cc10ded
commit 3e5bcef316
2 changed files with 53 additions and 16 deletions

View File

@ -1,3 +1,12 @@
2004-12-10 Roger Sayle <roger@eyesopen.com>
PR target/18002
PR middle-end/18424
* dojump.c (do_jump): When attempting to reverse the effects of
fold_single_bit_test, we need to STRIP_NOPS and narrowing type
conversions, and handle BIT_XOR_EXPR that's used to invert the
sense of the single bit test.
2004-12-10 Devang Patel <dpatel@apple.com>
PR 18732

View File

@ -218,24 +218,52 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label)
/* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
See if the former is preferred for jump tests and restore it
if so. */
if (TREE_CODE (TREE_OPERAND (exp, 0)) == RSHIFT_EXPR
&& integer_onep (TREE_OPERAND (exp, 1)))
if (integer_onep (TREE_OPERAND (exp, 1)))
{
tree arg = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree shift = TREE_OPERAND (TREE_OPERAND (exp, 0), 1);
tree one = TREE_OPERAND (exp, 1);
tree argtype = TREE_TYPE (arg);
if (TREE_CODE (shift) == INTEGER_CST
&& compare_tree_int (shift, 0) > 0
&& compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
&& prefer_and_bit_test (TYPE_MODE (argtype),
TREE_INT_CST_LOW (shift)))
tree exp0 = TREE_OPERAND (exp, 0);
rtx set_label, clr_label;
/* Strip narrowing integral type conversions. */
while ((TREE_CODE (exp0) == NOP_EXPR
|| TREE_CODE (exp0) == CONVERT_EXPR
|| TREE_CODE (exp0) == NON_LVALUE_EXPR)
&& TREE_OPERAND (exp0, 0) != error_mark_node
&& TYPE_PRECISION (TREE_TYPE (exp0))
<= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
exp0 = TREE_OPERAND (exp0, 0);
/* "exp0 ^ 1" inverts the sense of the single bit test. */
if (TREE_CODE (exp0) == BIT_XOR_EXPR
&& integer_onep (TREE_OPERAND (exp0, 1)))
{
do_jump (build2 (BIT_AND_EXPR, argtype, arg,
fold (build2 (LSHIFT_EXPR, argtype,
one, shift))),
if_false_label, if_true_label);
break;
exp0 = TREE_OPERAND (exp0, 0);
clr_label = if_true_label;
set_label = if_false_label;
}
else
{
clr_label = if_false_label;
set_label = if_true_label;
}
if (TREE_CODE (exp0) == RSHIFT_EXPR)
{
tree arg = TREE_OPERAND (exp0, 0);
tree shift = TREE_OPERAND (exp0, 1);
tree argtype = TREE_TYPE (arg);
if (TREE_CODE (shift) == INTEGER_CST
&& compare_tree_int (shift, 0) >= 0
&& compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
&& prefer_and_bit_test (TYPE_MODE (argtype),
TREE_INT_CST_LOW (shift)))
{
HOST_WIDE_INT mask = (HOST_WIDE_INT) 1
<< TREE_INT_CST_LOW (shift);
do_jump (build2 (BIT_AND_EXPR, argtype, arg,
build_int_cst_type (argtype, mask)),
clr_label, set_label);
break;
}
}
}