This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Let fold_rtx's unsigned_fix be consistent with other cases
- To: Alexandre Oliva <aoliva at redhat dot com>
- Subject: Re: Let fold_rtx's unsigned_fix be consistent with other cases
- From: Geoff Keating <geoffk at geoffk dot org>
- Date: 18 Nov 2000 15:52:25 -0800
- CC: gcc-patches at gcc dot gnu dot org
- References: <ory9yg3nhs.fsf@guarana.lsd.ic.unicamp.br>
Alexandre Oliva <aoliva@redhat.com> writes:
> --=-=-=
>
> The value of `(unsigned char)((unsigned char)3 - (float)5)' is usually
> expected to be `(unsigned char)0-(unsigned char)2', even though
> technically it invokes undefined behavior. However, it is quite
> surprising that we get the expected result when the expression is
> folded upfront, in the tree level. However, if the expression is
> convoluted enough that it makes it to cse, when cse applies fold_rtx()
> to it, it gets 0 instead.
>
> Here's a patch that arranges for real.c to compute the expected value.
> Ok to install? (Will bootstrap and test on i686-pc-linux-gnu, in
> addition to the already-tested mn10300-elf, if I get encouraging
> feedback)
I don't think this is very helpful. It will ensure that on machines
where the hardware computes 0, that gcc's constant folding is
consistently inconsistent with the hardware.
A quick survey indicates that this program:
static int t(double f);
#include <stdio.h>
int main(void)
{
printf ("%d\t%d\n", t(-9.), t(4294967287.));
return 0;
}
static int t(double f)
{
return (unsigned char) f;
}
prints (`soft' means with -msoft-float):
Target CPU Result
powerpc-linux 750 247 255
powerpc-aix 603e 0 247
powerpc-aix power3 0 247
powerpc-linux soft 247 247
powerpc-eabi sim 247 255
mips-tx39-elf sim 0 247
mips-tx39-elf soft 0 247
sparc-solaris usparc 247 255
i386-linux p3 247 0 with gcc from RH 7
i386-linux k6 247 247 with gcc from RH 6.2
hpux11.0 ? 247 255
Note that these results very much depend on whether the chip has a fp
-> unsigned conversion instruction; in some cases, gcc will compile
this as '(unsigned char) (int) f' and in some as
'(unsigned char)(unsigned)f'. They may depend on the gcc version, too.
I believe the right thing to do is that when this case is detected in
the constant folder, it should produce a warning, just like in the case
of 0/0.
--
- Geoffrey Keating <geoffk@geoffk.org>