D.gnu - Floating point constant folding bug?
- Johannes Pfau <nospam example.com> Mar 15 2013
- Iain Buclaw <ibuclaw ubuntu.com> Mar 15 2013
- Johannes Pfau <nospam example.com> Mar 15 2013
- Iain Buclaw <ibuclaw ubuntu.com> Mar 15 2013
- Johannes Pfau <nospam example.com> Mar 15 2013
- Iain Buclaw <ibuclaw ubuntu.com> Mar 15 2013
writefln("%f\n%f", cast(float)cast(int)float.infinity, float.infinity);
writes
---
2147483648.000000
inf
---
-fdump-tree-original
---
writefln ({.length=5, .ptr="%f\n%f"}, 2.147483647e+9, Inf);
---
The same conversion at runtime produces the expected result.
Is this a gdc or gcc bug or is this expected?
Mar 15 2013
--047d7bea32822a98f704d7f84e8d Content-Type: text/plain; charset=ISO-8859-1 On 15 March 2013 15:15, Johannes Pfau <nospam example.com> wrote:writefln("%f\n%f", cast(float)cast(int)float.infinity, float.infinity); writes --- 2147483648.000000 inf --- -fdump-tree-original --- writefln ({.length=5, .ptr="%f\n%f"}, 2.147483647e+9, Inf); --- The same conversion at runtime produces the expected result. Is this a gdc or gcc bug or is this expected?
GCC bug, try the same in C and see if it produces the same result. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; --047d7bea32822a98f704d7f84e8d Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 1= 5 March 2013 15:15, Johannes Pfau <span dir=3D"ltr"><<a href=3D"mailto:n= ospam example.com" target=3D"_blank">nospam example.com</a>></span> wrot= e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"> writefln("%f\n%f", cast(float)cast(int)float.infinity, float.infi= nity);<br> <br> writes<br> ---<br> 2147483648.000000<br> inf<br> ---<br> <br> -fdump-tree-original<br> ---<br> writefln ({.length=3D5, .ptr=3D"%f\n%f"}, 2.147483647e+9, =A0Inf)= ;<br> ---<br> <br> The same conversion at runtime produces the expected result.<br> <br> Is this a gdc or gcc bug or is this expected?<br> </blockquote></div><br></div><div class=3D"gmail_extra">GCC bug, try the sa= me in C and see if it produces the same result.<br clear=3D"all"></div><div= class=3D"gmail_extra"><br>-- <br>Iain Buclaw<br><br>*(p < e ? p++ : p) = =3D (c & 0x0f) + '0'; </div></div> --047d7bea32822a98f704d7f84e8d--
Mar 15 2013
Forget what I've said, I somehow read that code as a bitwise/reinterpret
cast but of course the code does an integer/float conversion so it's
probably OK.
This is more interesting:
---
float f = float.infinity;
float f2 = float.max;
int i = cast(int) f;
int i2 = cast(int) f2;
writefln("0x%x == int.min(0x%x)", i, int.min);
writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max);
writefln("0x%x == int.min(0x%x)", i2, int.min);
writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max);
---
const folding expands to int.max, but the same code at runtime expands
to int.min. C does not define what happens if too large float values
are cast into ints. Do you know if D somehow defines this?
(There's a failing test in the test suite which assumes that the result
is int.min in all cases above)
Mar 15 2013
--20cf3074b7ccf599ed04d7fc5dcf Content-Type: text/plain; charset=ISO-8859-1 On 15 March 2013 18:35, Johannes Pfau <nospam example.com> wrote:Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)
I think the behaviour from DMD is more incidental than intended. They use C's FLOAT_INFINITY, etc, macros. But because of the way it's written, gcc doesn't optimise the use of the value. Whereas with gdc, because it uses gcc's real_t types, values of extreme numbers may change to be either 2147483647 or -2147483648 depending on whether -O is used. As I said, in most cases you can see the same behaviour in C. I can see if there might be some flag I can set to try and make gcc's codegen more safe for floats, but that might have impact on runtime. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; --20cf3074b7ccf599ed04d7fc5dcf Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 1= 5 March 2013 18:35, Johannes Pfau <span dir=3D"ltr"><<a href=3D"mailto:n= ospam example.com" target=3D"_blank">nospam example.com</a>></span> wrot= e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b= order-left:1px solid rgb(204,204,204);padding-left:1ex"> Forget what I've said, I somehow read that code as a bitwise/reinterpre= t<br> cast but of course the code does an integer/float conversion so it's<br=
<br> This is more interesting:<br> <br> ---<br> =A0 =A0 float f =3D float.infinity;<br> =A0 =A0 float f2 =3D float.max;<br> =A0 =A0 int i =3D cast(int) f;<br> =A0 =A0 int i2 =3D cast(int) f2;<br> =A0 =A0 writefln("0x%x =3D=3D int.min(0x%x)", i, int.min);<br> =A0 =A0 writefln("0x%x =3D=3D int.max(0x%x)", cast(int)float.infi= nity, int.max);<br> =A0 =A0 writefln("0x%x =3D=3D int.min(0x%x)", i2, int.min);<br> =A0 =A0 writefln("0x%x =3D=3D int.max(0x%x)", cast(int)float.max,= int.max);<br> ---<br> <br> const folding expands to int.max, but the same code at runtime expands<br> to int.min. C does not define what happens if too large float values<br> are cast into ints. Do you know if D somehow defines this?<br> <br> (There's a failing test in the test suite which assumes that the result= <br> is int.min in all cases above)<br> </blockquote></div><br><br></div><div class=3D"gmail_extra">I think the beh= aviour from DMD is more incidental than intended.=A0 They use C's FLOAT= _INFINITY, etc, macros. But because of the way it's written, gcc doesn&= #39;t optimise the use of the value.=A0=A0 Whereas with gdc, because it use= s gcc's real_t types, values of extreme numbers may change to be either= 2147483647 or -2147483648 depending on whether -O is used.=A0 As I said, i= n most cases you can see the same behaviour in C.<br> <br></div><div class=3D"gmail_extra">I can see if there might be some flag = I can set to try and make gcc's codegen more safe for floats, but that = might have impact on runtime.<br></div><div class=3D"gmail_extra"><br></div=
p) =3D (c & 0x0f) + '0'; </div></div> --20cf3074b7ccf599ed04d7fc5dcf--
Mar 15 2013
Am Fri, 15 Mar 2013 20:20:14 +0000 schrieb Iain Buclaw <ibuclaw ubuntu.com>:On 15 March 2013 18:35, Johannes Pfau <nospam example.com> wrote:Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)
I think the behaviour from DMD is more incidental than intended. They use C's FLOAT_INFINITY, etc, macros. But because of the way it's written, gcc doesn't optimise the use of the value. Whereas with gdc, because it uses gcc's real_t types, values of extreme numbers may change to be either 2147483647 or -2147483648 depending on whether -O is used. As I said, in most cases you can see the same behaviour in C. I can see if there might be some flag I can set to try and make gcc's codegen more safe for floats, but that might have impact on runtime.
I think in this case GCC might intentionally use saturating overflows. I just found this message: http://gcc.gnu.org/ml/gcc-patches/2003-09/msg02090.html (This doesn't explain though what the test (constfold.d:test2) in the dmd testsuite is actually supposed to test...)
Mar 15 2013
--047d7b5dbce20b461704d7fe796b Content-Type: text/plain; charset=ISO-8859-1 On 15 March 2013 22:00, Johannes Pfau <nospam example.com> wrote:Am Fri, 15 Mar 2013 20:20:14 +0000 schrieb Iain Buclaw <ibuclaw ubuntu.com>:On 15 March 2013 18:35, Johannes Pfau <nospam example.com> wrote:Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)
I think the behaviour from DMD is more incidental than intended. They use C's FLOAT_INFINITY, etc, macros. But because of the way it's written, gcc doesn't optimise the use of the value. Whereas with gdc, because it uses gcc's real_t types, values of extreme numbers may change to be either 2147483647 or -2147483648 depending on whether -O is used. As I said, in most cases you can see the same behaviour in C. I can see if there might be some flag I can set to try and make gcc's codegen more safe for floats, but that might have impact on runtime.
I think in this case GCC might intentionally use saturating overflows. I just found this message: http://gcc.gnu.org/ml/gcc-patches/2003-09/msg02090.html (This doesn't explain though what the test (constfold.d:test2) in the dmd testsuite is actually supposed to test...)
It tests an incidental feature of dmd-generated code that got turned into a test case. Rather than something defined in the spec. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; --047d7b5dbce20b461704d7fe796b Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 1= 5 March 2013 22:00, Johannes Pfau <span dir=3D"ltr"><<a href=3D"mailto:n= ospam example.com" target=3D"_blank">nospam example.com</a>></span> wrot= e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"> Am Fri, 15 Mar 2013 20:20:14 +0000<br> schrieb Iain Buclaw <<a href=3D"mailto:ibuclaw ubuntu.com">ibuclaw ubunt= u.com</a>>:<br> <div class=3D"im"><br> > On 15 March 2013 18:35, Johannes Pfau <<a href=3D"mailto:nospam exa= mple.com">nospam example.com</a>> wrote:<br> ><br> </div><div><div class=3D"h5">> > Forget what I've said, I somehow= read that code as a<br> > > bitwise/reinterpret cast but of course the code does an<br> > > integer/float conversion so it's probably OK.<br> > ><br> > > This is more interesting:<br> > ><br> > > ---<br> > > =A0 =A0 float f =3D float.infinity;<br> > > =A0 =A0 float f2 =3D float.max;<br> > > =A0 =A0 int i =3D cast(int) f;<br> > > =A0 =A0 int i2 =3D cast(int) f2;<br> > > =A0 =A0 writefln("0x%x =3D=3D int.min(0x%x)", i, int.mi= n);<br> > > =A0 =A0 writefln("0x%x =3D=3D int.max(0x%x)", cast(int)= float.infinity,<br> > > int.max); writefln("0x%x =3D=3D int.min(0x%x)", i2, int= .min);<br> > > =A0 =A0 writefln("0x%x =3D=3D int.max(0x%x)", cast(int)= float.max, int.max);<br> > > ---<br> > ><br> > > const folding expands to int.max, but the same code at runtime<br=
r> > > float values are cast into ints. Do you know if D somehow defines= <br> > > this?<br> > ><br> > > (There's a failing test in the test suite which assumes that = the<br> > > result is int.min in all cases above)<br> > ><br> ><br> ><br> </div></div><div class=3D"im">> I think the behaviour from DMD is more i= ncidental than intended.<br> > They use C's FLOAT_INFINITY, etc, macros. But because of the way i= t's<br> > written, gcc doesn't optimise the use of the value. =A0 Whereas wi= th<br> > gdc, because it uses gcc's real_t types, values of extreme numbers= <br> > may change to be either 2147483647 or -2147483648 depending on<br> > whether -O is used. =A0As I said, in most cases you can see the same<b= r> > behaviour in C.<br> ><br> > I can see if there might be some flag I can set to try and make gcc= 9;s<br> > codegen more safe for floats, but that might have impact on runtime.<b= r> ><br> ><br> <br> </div>I think in this case GCC might intentionally use saturating overflows= .<br> I just found this message:<br> <br> <a href=3D"http://gcc.gnu.org/ml/gcc-patches/2003-09/msg02090.html" target= =3D"_blank">http://gcc.gnu.org/ml/gcc-patches/2003-09/msg02090.html</a><br> <br> (This doesn't explain though what the test (constfold.d:test2) in the<b= r> dmd testsuite is actually supposed to test...)<br> </blockquote></div><br><br></div><div class=3D"gmail_extra">It tests an inc= idental feature of dmd-generated code that got turned into a test case.=A0 = Rather than something defined in the spec.<br clear=3D"all"></div><div clas= s=3D"gmail_extra"> <br>-- <br>Iain Buclaw<br><br>*(p < e ? p++ : p) =3D (c & 0x0f) + &#= 39;0'; </div></div> --047d7b5dbce20b461704d7fe796b--
Mar 15 2013









Iain Buclaw <ibuclaw ubuntu.com> 