This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
regression for 3.1: bad sign extension?
- From: Bob Wilson <bwilson at tensilica dot com>
- To: aoliva at redhat dot com, gcc at gcc dot gnu dot org
- Date: Wed, 13 Mar 2002 16:08:53 -0800
- Subject: regression for 3.1: bad sign extension?
- Organization: Tensilica, Inc.
I am tracking down some regressions for 3.1 in the Xtensa port. There
are several testsuite failures caused by the following change:
2001-04-12 Alexandre Oliva <aoliva@redhat.com>
* varasm.c (immed_double_const): Don't require words to be
narrower than host wide ints to properly sign-extend
CONST_INTs.
The 3.1 code looks like:
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will
look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to
be
represented as a 64 bit value -1, and not as
0x00000000ffffffff.
The later confuses the sparc backend. */
if (width < HOST_BITS_PER_WIDE_INT
&& (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
i0 |= ((HOST_WIDE_INT) (-1) << width);
The 3.0 code is:
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD ==
width
&& (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
i0 |= ((HOST_WIDE_INT) (-1) << width);
If nothing else, the comment needs to be fixed since it describes the
3.0 version, and the 3.1 code behaves quite differently. Moreover, at
least for the Xtensa port, the problem goes beyond the inaccurate
comment.
The problem occurs when there is an unsigned short (16-bits, HI mode)
that gets (incorrectly?) sign-extended by this code. (I'm testing this
on a 32-bit host.) The sign-extended constant gets put into a constant
pool. Xtensa processors only access the constant pool with SI mode
loads, which is fine in the initial RTL because the SI mode load is
followed by a zero-extend. At certain levels of optimization, however,
the zero-extend is optimized away and the code becomes incorrect.
Why was this change made? Based on the comment, it is certainly doing
something different than it was originally intended to do, and it looks
suspicious to me.
Unless this change is modified somehow, I'm not sure how to deal with
the resulting problems for the Xtensa port. It seems to me that the
right thing to do is to have the values in the constant pool
sign-extended or zero-extended depending on the type of the value. I
don't see how I can do this in the Xtensa .md file since only the mode
information is available.
The other possibility is to look into why the zero-extend is getting
optimized away. Regardless of that, putting the sign-extended value in
the constant pool will result in worse code because an explicit
zero-extend operation will be required.