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:
parent
c0503294bc
commit
146aef0b39
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
15
gcc/optabs.c
15
gcc/optabs.c
|
@ -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)),
|
||||
|
|
Loading…
Reference in New Issue