This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: fp->int folding broken. again.
- From: Roger Sayle <roger at eyesopen dot com>
- To: Richard Henderson <rth at twiddle dot net>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 16 Oct 2003 09:15:53 -0600 (MDT)
- Subject: Re: fp->int folding broken. again.
Hi Richard,
On Thu, 16 Oct 2003, Richard Henderson wrote:
> I think we've done this about 10 times now.
But you've never had anyone as clever as me working on it before :>
> We cannot bound conversion from float to integer at their signed bounds.
> This breaks code within gcc that expects conversion to unsigned integer
> to work. This patch causes
>
> FAIL: gcc.c-torture/execute/conversion.c execution, -O3 -fomit-frame-pointer
> FAIL: gcc.c-torture/execute/conversion.c execution, -O3 -g
> FAIL: gcc.c-torture/execute/ieee/rbug.c execution, -O3 -fomit-frame-pointer
> FAIL: gcc.c-torture/execute/ieee/rbug.c execution, -O3 -g
>
> to fail on alpha-linux.
>
> I don't care how this gets fixed, but every other time we've gone
> round this hobby horse, we've decided that the saturation thing
> just isn't worth it.
It looks like the bug is in alpha backend, which is why we're only seeing
problems under alpha-linux. Consider the initial RTL generated for this
example test program:
unsigned long long foo(double x)
{
return (unsigned long long)x;
}
which on the alpha generates the sequence:
(insn 11 10 12 (set (reg:DI 71)
(fix:DI (reg/v:DF 70 [ x ]))) -1 (nil)
(nil))
(insn 12 11 13 (set (reg:DI 69 [ <result> ])
(reg:DI 71)) -1 (nil)
(nil))
The problem is that the conversion is an floating point to unsigned
conversion which means that the first instruction should be using
the unsigned_fix:DI operator in RTL.
I'll try and track down how this happens, and why the alpha backend
ends up lying about the behaviour of this instruction, and then relies
on overflow semantics that's even documented in the internals manual
as being undefined.
Hopefully, I'll have a fix soon.
Roger
--