Commit e2f00837 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/50161 (wrong code with -fno-tree-ter and __builtin_popcountl)

	PR middle-end/50161
	* simplify-rtx.c (simplify_const_unary_operation): If
	op is CONST_INT, don't look at op_mode, but use instead
	mode.
	* optabs.c (add_equal_note): For FFS, CLZ, CTZ,
	CLRSB, POPCOUNT, PARITY and BSWAP use operand mode for
	operation and TRUNCATE/ZERO_EXTEND if needed.
	* doc/rtl.texi (ffs, clrsb, clz, ctz, popcount, parity, bswap):
	Document that operand mode must be same as operation mode,
	or VOIDmode.
	* config/avr/avr.md (paritysi2, *parityqihi2.libgcc,
	*paritysihi2.libgcc, popcountsi2, *popcountsi2.libgcc,
	*popcountqihi2.libgcc, clzsi2, *clzsihi2.libgcc, ctzsi2,
	*ctzsihi2.libgcc, ffssi2, *ffssihi2.libgcc): For unary ops
	use the mode of operand for the operation and add truncate
	or zero_extend around if needed.
	* config/c6x/c6x.md (ctzdi2): Likewise.
	* config/bfin/bfin.md (clrsbsi2, signbitssi2): Likewise.

	* gcc.dg/pr50161.c: New test.

From-SVN: r177991
parent e70e0b60
2011-08-23 Jakub Jelinek <jakub@redhat.com>
PR middle-end/50161
* simplify-rtx.c (simplify_const_unary_operation): If
op is CONST_INT, don't look at op_mode, but use instead
mode.
* optabs.c (add_equal_note): For FFS, CLZ, CTZ,
CLRSB, POPCOUNT, PARITY and BSWAP use operand mode for
operation and TRUNCATE/ZERO_EXTEND if needed.
* doc/rtl.texi (ffs, clrsb, clz, ctz, popcount, parity, bswap):
Document that operand mode must be same as operation mode,
or VOIDmode.
* config/avr/avr.md (paritysi2, *parityqihi2.libgcc,
*paritysihi2.libgcc, popcountsi2, *popcountsi2.libgcc,
*popcountqihi2.libgcc, clzsi2, *clzsihi2.libgcc, ctzsi2,
*ctzsihi2.libgcc, ffssi2, *ffssihi2.libgcc): For unary ops
use the mode of operand for the operation and add truncate
or zero_extend around if needed.
* config/c6x/c6x.md (ctzdi2): Likewise.
* config/bfin/bfin.md (clrsbsi2, signbitssi2): Likewise.
2011-08-12 Michael Matz <matz@suse.de>
* cfgexpand.c (expand_one_register_var): Use get_pointer_alignment.
......
;; Machine description for GNU compiler,
;; for ATMEL AVR micro controllers.
;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
;; 2009, 2010 Free Software Foundation, Inc.
;; 2009, 2010, 2011 Free Software Foundation, Inc.
;; Contributed by Denis Chertykov (chertykov@gmail.com)
;; This file is part of GCC.
......@@ -4124,7 +4124,7 @@
[(set (reg:SI 22)
(match_operand:SI 1 "register_operand" ""))
(set (reg:HI 24)
(parity:HI (reg:SI 22)))
(truncate:HI (parity:SI (reg:SI 22))))
(set (match_dup 2)
(reg:HI 24))
(set (match_operand:SI 0 "register_operand" "")
......@@ -4144,7 +4144,7 @@
(define_insn "*parityqihi2.libgcc"
[(set (reg:HI 24)
(parity:HI (reg:QI 24)))]
(zero_extend:HI (parity:QI (reg:QI 24))))]
""
"%~call __parityqi2"
[(set_attr "type" "xcall")
......@@ -4152,7 +4152,7 @@
(define_insn "*paritysihi2.libgcc"
[(set (reg:HI 24)
(parity:HI (reg:SI 22)))]
(truncate:HI (parity:SI (reg:SI 22))))]
""
"%~call __paritysi2"
[(set_attr "type" "xcall")
......@@ -4175,7 +4175,7 @@
[(set (reg:SI 22)
(match_operand:SI 1 "register_operand" ""))
(set (reg:HI 24)
(popcount:HI (reg:SI 22)))
(truncate:HI (popcount:SI (reg:SI 22))))
(set (match_dup 2)
(reg:HI 24))
(set (match_operand:SI 0 "register_operand" "")
......@@ -4195,7 +4195,7 @@
(define_insn "*popcountsi2.libgcc"
[(set (reg:HI 24)
(popcount:HI (reg:SI 22)))]
(truncate:HI (popcount:SI (reg:SI 22))))]
""
"%~call __popcountsi2"
[(set_attr "type" "xcall")
......@@ -4211,7 +4211,7 @@
(define_insn_and_split "*popcountqihi2.libgcc"
[(set (reg:HI 24)
(popcount:HI (reg:QI 24)))]
(zero_extend:HI (popcount:QI (reg:QI 24))))]
""
"#"
""
......@@ -4238,7 +4238,7 @@
[(set (reg:SI 22)
(match_operand:SI 1 "register_operand" ""))
(parallel [(set (reg:HI 24)
(clz:HI (reg:SI 22)))
(truncate:HI (clz:SI (reg:SI 22))))
(clobber (reg:QI 26))])
(set (match_dup 2)
(reg:HI 24))
......@@ -4260,7 +4260,7 @@
(define_insn "*clzsihi2.libgcc"
[(set (reg:HI 24)
(clz:HI (reg:SI 22)))
(truncate:HI (clz:SI (reg:SI 22))))
(clobber (reg:QI 26))]
""
"%~call __clzsi2"
......@@ -4284,7 +4284,7 @@
[(set (reg:SI 22)
(match_operand:SI 1 "register_operand" ""))
(parallel [(set (reg:HI 24)
(ctz:HI (reg:SI 22)))
(truncate:HI (ctz:SI (reg:SI 22))))
(clobber (reg:QI 22))
(clobber (reg:QI 26))])
(set (match_dup 2)
......@@ -4307,7 +4307,7 @@
(define_insn "*ctzsihi2.libgcc"
[(set (reg:HI 24)
(ctz:HI (reg:SI 22)))
(truncate:HI (ctz:SI (reg:SI 22))))
(clobber (reg:QI 22))
(clobber (reg:QI 26))]
""
......@@ -4332,7 +4332,7 @@
[(set (reg:SI 22)
(match_operand:SI 1 "register_operand" ""))
(parallel [(set (reg:HI 24)
(ffs:HI (reg:SI 22)))
(truncate:HI (ffs:SI (reg:SI 22))))
(clobber (reg:QI 22))
(clobber (reg:QI 26))])
(set (match_dup 2)
......@@ -4355,7 +4355,7 @@
(define_insn "*ffssihi2.libgcc"
[(set (reg:HI 24)
(ffs:HI (reg:SI 22)))
(truncate:HI (ffs:SI (reg:SI 22))))
(clobber (reg:QI 22))
(clobber (reg:QI 26))]
""
......
;;- Machine description for Blackfin for GNU compiler
;; Copyright 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;; Copyright 2005, 2006, 2007, 2008, 2011 Free Software Foundation, Inc.
;; Contributed by Analog Devices.
;; This file is part of GCC.
......@@ -1463,7 +1463,7 @@
(define_expand "clrsbsi2"
[(set (match_dup 2)
(clrsb:HI (match_operand:SI 1 "register_operand" "d")))
(truncate:HI (clrsb:SI (match_operand:SI 1 "register_operand" "d"))))
(set (match_operand:SI 0 "register_operand")
(zero_extend:SI (match_dup 2)))]
""
......@@ -1473,7 +1473,7 @@
(define_insn "signbitssi2"
[(set (match_operand:HI 0 "register_operand" "=d")
(clrsb:HI (match_operand:SI 1 "register_operand" "d")))]
(truncate:HI (clrsb:SI (match_operand:SI 1 "register_operand" "d"))))]
""
"%h0 = signbits %1%!"
[(set_attr "type" "dsp32")])
......
......@@ -2014,7 +2014,7 @@
(define_expand "ctzdi2"
[(set (match_operand:DI 0 "register_operand" "")
(ctz:SI (match_operand:DI 1 "register_operand" "")))]
(ctz:DI (match_operand:DI 1 "register_operand" "")))]
"TARGET_INSNS_64"
{
rtx tmpreg = gen_reg_rtx (DImode);
......
@c Copyright (C) 1988, 1989, 1992, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
@c 2003, 2004, 2005, 2006, 2007, 2008, 2010
@c 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
......@@ -2408,9 +2408,8 @@ Most often @var{m} will be a floating point mode.
@item (ffs:@var{m} @var{x})
Represents one plus the index of the least significant 1-bit in
@var{x}, represented as an integer of mode @var{m}. (The value is
zero if @var{x} is zero.) The mode of @var{x} need not be @var{m};
depending on the target machine, various mode combinations may be
valid.
zero if @var{x} is zero.) The mode of @var{x} must be @var{m}
or @code{VOIDmode}.
@findex clrsb
@item (clrsb:@var{m} @var{x})
......@@ -2418,7 +2417,7 @@ Represents the number of redundant leading sign bits in @var{x},
represented as an integer of mode @var{m}, starting at the most
significant bit position. This is one less than the number of leading
sign bits (either 0 or 1), with no special cases. The mode of @var{x}
will usually be an integer mode and may differ from @var{m}.
must be @var{m} or @code{VOIDmode}.
@findex clz
@item (clz:@var{m} @var{x})
......@@ -2427,7 +2426,7 @@ integer of mode @var{m}, starting at the most significant bit position.
If @var{x} is zero, the value is determined by
@code{CLZ_DEFINED_VALUE_AT_ZERO} (@pxref{Misc}). Note that this is one of
the few expressions that is not invariant under widening. The mode of
@var{x} will usually be an integer mode.
@var{x} must be @var{m} or @code{VOIDmode}.
@findex ctz
@item (ctz:@var{m} @var{x})
......@@ -2436,23 +2435,24 @@ integer of mode @var{m}, starting at the least significant bit position.
If @var{x} is zero, the value is determined by
@code{CTZ_DEFINED_VALUE_AT_ZERO} (@pxref{Misc}). Except for this case,
@code{ctz(x)} is equivalent to @code{ffs(@var{x}) - 1}. The mode of
@var{x} will usually be an integer mode.
@var{x} must be @var{m} or @code{VOIDmode}.
@findex popcount
@item (popcount:@var{m} @var{x})
Represents the number of 1-bits in @var{x}, represented as an integer of
mode @var{m}. The mode of @var{x} will usually be an integer mode.
mode @var{m}. The mode of @var{x} must be @var{m} or @code{VOIDmode}.
@findex parity
@item (parity:@var{m} @var{x})
Represents the number of 1-bits modulo 2 in @var{x}, represented as an
integer of mode @var{m}. The mode of @var{x} will usually be an integer
mode.
integer of mode @var{m}. The mode of @var{x} must be @var{m} or
@code{VOIDmode}.
@findex bswap
@item (bswap:@var{m} @var{x})
Represents the value @var{x} with the order of bytes reversed, carried out
in mode @var{m}, which must be a fixed-point machine mode.
The mode of @var{x} must be @var{m} or @code{VOIDmode}.
@end table
@node Comparisons
......
......@@ -216,7 +216,32 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
}
if (GET_RTX_CLASS (code) == RTX_UNARY)
note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
switch (code)
{
case FFS:
case CLZ:
case CTZ:
case CLRSB:
case POPCOUNT:
case PARITY:
case BSWAP:
if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
{
note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
if (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (GET_MODE (target)))
note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
note, GET_MODE (op0));
else
note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
note, GET_MODE (op0));
break;
}
/* FALLTHRU */
default:
note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
break;
}
else
note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
......
......@@ -1373,8 +1373,7 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
}
if (CONST_INT_P (op)
&& width <= HOST_BITS_PER_WIDE_INT
&& op_width <= HOST_BITS_PER_WIDE_INT && op_width > 0)
&& width <= HOST_BITS_PER_WIDE_INT && width > 0)
{
HOST_WIDE_INT arg0 = INTVAL (op);
HOST_WIDE_INT val;
......@@ -1394,50 +1393,50 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
break;
case FFS:
arg0 &= GET_MODE_MASK (op_mode);
arg0 &= GET_MODE_MASK (mode);
val = ffs_hwi (arg0);
break;
case CLZ:
arg0 &= GET_MODE_MASK (op_mode);
if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (op_mode, val))
arg0 &= GET_MODE_MASK (mode);
if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (mode, val))
;
else
val = GET_MODE_PRECISION (op_mode) - floor_log2 (arg0) - 1;
val = GET_MODE_PRECISION (mode) - floor_log2 (arg0) - 1;
break;
case CLRSB:
arg0 &= GET_MODE_MASK (op_mode);
arg0 &= GET_MODE_MASK (mode);
if (arg0 == 0)
val = GET_MODE_PRECISION (op_mode) - 1;
val = GET_MODE_PRECISION (mode) - 1;
else if (arg0 >= 0)
val = GET_MODE_PRECISION (op_mode) - floor_log2 (arg0) - 2;
val = GET_MODE_PRECISION (mode) - floor_log2 (arg0) - 2;
else if (arg0 < 0)
val = GET_MODE_PRECISION (op_mode) - floor_log2 (~arg0) - 2;
val = GET_MODE_PRECISION (mode) - floor_log2 (~arg0) - 2;
break;
case CTZ:
arg0 &= GET_MODE_MASK (op_mode);
arg0 &= GET_MODE_MASK (mode);
if (arg0 == 0)
{
/* Even if the value at zero is undefined, we have to come
up with some replacement. Seems good enough. */
if (! CTZ_DEFINED_VALUE_AT_ZERO (op_mode, val))
val = GET_MODE_PRECISION (op_mode);
if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, val))
val = GET_MODE_PRECISION (mode);
}
else
val = ctz_hwi (arg0);
break;
case POPCOUNT:
arg0 &= GET_MODE_MASK (op_mode);
arg0 &= GET_MODE_MASK (mode);
val = 0;
while (arg0)
val++, arg0 &= arg0 - 1;
break;
case PARITY:
arg0 &= GET_MODE_MASK (op_mode);
arg0 &= GET_MODE_MASK (mode);
val = 0;
while (arg0)
val++, arg0 &= arg0 - 1;
......
2011-08-23 Jakub Jelinek <jakub@redhat.com>
PR middle-end/50161
* gcc.dg/pr50161.c: New test.
2011-08-23 Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
PR c++/50055
......
/* PR middle-end/50161 */
/* { dg-do run } */
/* { dg-options "-O2 -fno-tree-ter -funroll-loops" } */
extern void abort (void);
int
main ()
{
unsigned i;
unsigned long a[16];
for (i = 0; i < 16; i++)
a[i] = ~0UL;
for (i = 0; i < 16; i++)
if (__builtin_popcountl (a[i]) != sizeof (a[i]) * 8)
abort ();
return 0;
}
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