re PR middle-end/49489 (gcc.c-torture/execute/builtin-bitops-1.c fails on x86_64-linux)

PR middle-end/49489
	* builtins.c (expand_builtin_unop): Call expand_unop with 0 as
	unsignedp argument instead of 1 for clrsb_optab.
	(fold_builtin_bitop): Fix masking for width > HOST_BITS_PER_WIDE_INT
	and < 2 * HOST_BITS_PER_WIDE_INT.  Optimize BUILT_IN_CLRSB*.
	(fold_builtin_1): Call fold_builtin_binop for BUILT_IN_CLRSB*.
	* optabs.c (widen_leading): Call widen_operand and expand_unop
	with 0 as unsignedp argument instead of 1 for clrsb_optab.
	(expand_unop): Subtract difference of mode sizes also for
	clrsb_optab.

From-SVN: r175265
This commit is contained in:
Jakub Jelinek 2011-06-21 18:25:57 +02:00 committed by Jakub Jelinek
parent c0503294bc
commit 146aef0b39
3 changed files with 46 additions and 8 deletions

View File

@ -1,3 +1,16 @@
2011-06-21 Jakub Jelinek <jakub@redhat.com>
PR middle-end/49489
* builtins.c (expand_builtin_unop): Call expand_unop with 0 as
unsignedp argument instead of 1 for clrsb_optab.
(fold_builtin_bitop): Fix masking for width > HOST_BITS_PER_WIDE_INT
and < 2 * HOST_BITS_PER_WIDE_INT. Optimize BUILT_IN_CLRSB*.
(fold_builtin_1): Call fold_builtin_binop for BUILT_IN_CLRSB*.
* optabs.c (widen_leading): Call widen_operand and expand_unop
with 0 as unsignedp argument instead of 1 for clrsb_optab.
(expand_unop): Subtract difference of mode sizes also for
clrsb_optab.
2011-06-21 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.md (*jcindirect_jump): Fix build warning.

View File

@ -4578,7 +4578,7 @@ expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
/* Compute op, into TARGET if possible.
Set TARGET to wherever the result comes back. */
target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
op_optab, op0, target, 1);
op_optab, op0, target, op_optab != clrsb_optab);
gcc_assert (target);
return convert_to_mode (target_mode, target, 0);
@ -7265,7 +7265,8 @@ fold_builtin_bitop (tree fndecl, tree arg)
{
hi = TREE_INT_CST_HIGH (arg);
if (width < 2 * HOST_BITS_PER_WIDE_INT)
hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
hi &= ~((unsigned HOST_WIDE_INT) (-1)
<< (width - HOST_BITS_PER_WIDE_INT));
}
else
{
@ -7303,6 +7304,26 @@ fold_builtin_bitop (tree fndecl, tree arg)
result = width;
break;
CASE_INT_FN (BUILT_IN_CLRSB):
if (width > HOST_BITS_PER_WIDE_INT
&& (hi & ((unsigned HOST_WIDE_INT) 1
<< (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
{
hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
<< (width - HOST_BITS_PER_WIDE_INT - 1));
lo = ~lo;
}
else if (width <= HOST_BITS_PER_WIDE_INT
&& (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
if (hi != 0)
result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
else if (lo != 0)
result = width - floor_log2 (lo) - 2;
else
result = width - 1;
break;
CASE_INT_FN (BUILT_IN_POPCOUNT):
result = 0;
while (lo)
@ -9737,6 +9758,7 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
CASE_INT_FN (BUILT_IN_FFS):
CASE_INT_FN (BUILT_IN_CLZ):
CASE_INT_FN (BUILT_IN_CTZ):
CASE_INT_FN (BUILT_IN_CLRSB):
CASE_INT_FN (BUILT_IN_POPCOUNT):
CASE_INT_FN (BUILT_IN_PARITY):
return fold_builtin_bitop (fndecl, arg0);

View File

@ -1,7 +1,7 @@
/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011 Free Software Foundation, Inc.
This file is part of GCC.
@ -2350,8 +2350,10 @@ widen_leading (enum machine_mode mode, rtx op0, rtx target, optab unoptab)
if (target == 0)
target = gen_reg_rtx (mode);
xop0 = widen_operand (op0, wider_mode, mode, true, false);
temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX, true);
xop0 = widen_operand (op0, wider_mode, mode,
unoptab != clrsb_optab, false);
temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
unoptab != clrsb_optab);
if (temp != 0)
temp = expand_binop (wider_mode, sub_optab, temp,
GEN_INT (GET_MODE_BITSIZE (wider_mode)
@ -3075,8 +3077,9 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
unsignedp);
/* If we are generating clz using wider mode, adjust the
result. */
if (unoptab == clz_optab && temp != 0)
result. Similarly for clrsb. */
if ((unoptab == clz_optab || unoptab == clrsb_optab)
&& temp != 0)
temp = expand_binop (wider_mode, sub_optab, temp,
GEN_INT (GET_MODE_BITSIZE (wider_mode)
- GET_MODE_BITSIZE (mode)),