Re: -ffast-math in Ports and wrong generated code
On 04/05/12 01:46, Andrey Simonenko wrote: On Wed, Apr 04, 2012 at 09:45:25AM -0500, Pedro Giffuni wrote: On 04/04/12 04:29, Andrey Simonenko wrote: On Tue, Apr 03, 2012 at 06:43:00AM -0700, Steve Kargl wrote: The SVN commit http://svnweb.freebsd.org/base?view=revision&revision=228756 will point you to this: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796 and we are keeping consistency with both upstream and Apple's gcc. Well, I've found exact commit to upstream gcc source tree that corrects the bug described above: http://gcc.gnu.org/viewcvs/trunk/gcc/builtins.c?r1=117751&r2=117929 Aha!.. OK I needed to be sure we would still be consistent with upstream. The upstream patch is under GPLv2 so it can be committed. Thanks Andrey for your patience and persistence in finding this! Pedro. ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
Re: -ffast-math in Ports and wrong generated code
On Wed, Apr 04, 2012 at 09:45:25AM -0500, Pedro Giffuni wrote: > On 04/04/12 04:29, Andrey Simonenko wrote: > > On Tue, Apr 03, 2012 at 06:43:00AM -0700, Steve Kargl wrote: > >> On Tue, Apr 03, 2012 at 02:21:11PM +0300, Andrey Simonenko wrote: > >>> I use one port from the Ports Collection, that works with FP. Having > >>> reinstalled it (its version was not changed) I noticed that it started > >>> to work incorrectly. After debugging and disassembling its code I found > >>> out that the -ffast-math option used for building was the result of > >>> wrongly generated code (I did not specify this option in /etc/make.conf). > >>> > >>> At least finite() function call was eliminated from the result Assembler > >>> code when -ffast-math option is used, tested on 9.0-STABLE and > >>> 10.0-CURRENT. > >>> > >>> Example test source code and generated code under 9.0-STABLE on amd64 > >>> by gcc from the base system: > >>> > >>> - > >>> #include > >>> #include > >>> > >>> void > >>> check_finite(double x) > >>> { > >>> printf("%d\n", finite(x)); > >>> } > >>> - > >>> > >>> % gcc -Wall -O2 -S finite.c > >>> - > >>> check_finite: > >>> .LFB3: > >>> subq$8, %rsp > >>> .LCFI0: > >>> callfinite <-- call to finite() > >>> movl$.LC0, %edi > >>> movl%eax, %esi > >>> addq$8, %rsp > >>> xorl%eax, %eax > >>> jmp printf > >>> .LFE3: > >>> .size check_finite, .-check_finite > >>> - > >>> > >>> % gcc -Wall -O2 -ffast-math -S finite.c > >>> - > >>> check_finite: > >>> .LFB3: > >>> xorl%esi, %esi <-- fake result from finite() > >>> movl$.LC0, %edi > >>> xorl%eax, %eax > >>> jmp printf > >>> .LFE3: > >>> .size check_finite, .-check_finite > >>> - > >>> > >>> Can somebody comment this? > >> Read the man page for gcc. With --fast-math, > >> gcc assumes that the result of any FP operation > >> is finite. So, the function call to finite() > >> is eliminated as it is always true. > > Looks like that I was misunderstood. I did not ask why finite() was > > eliminated, I asked why fake result from finite() is wrong. Obviously > > that -ffast-math can optimize FP arithmetics and as a result some functions > > can be eliminated. The problem is not respecting IEEE specifications for > > FP, the problem is wrongly generated code when -ffast-math is used. > > > > Actually there is a bug in GCC used in the base system. There was made > > a change to builtins.c from gcc in revision 1.12 [1] and as a result gcc > > started to eliminate finite() function calls with -ffinite-math-only. > > > > ... > > > > After this change the corresponding Assembler code for my test file is: > > > > % gcc -Wall -O2 -ffast-math -S finite.c > > - > > check_finite: > > .LFB3: > > movl$1, %esi<-- fake result from finite() > > movl$.LC0, %edi > > xorl%eax, %eax > > jmp printf > > .LFE3: > > .size check_finite, .-check_finite > > - > > > > What do you think? If there is no objections, I'll create PR. > > > > [1] > > http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/gcc/builtins.c.diff?r1=1.11;r2=1.12 > > ___ > > The SVN commit > > http://svnweb.freebsd.org/base?view=revision&revision=228756 > > will point you to this: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796 > > and we are keeping consistency with both upstream and Apple's gcc. Well, I've found exact commit to upstream gcc source tree that corrects the bug described above: http://gcc.gnu.org/viewcvs/trunk/gcc/builtins.c?r1=117751&r2=117929 I think that nobody even tried to run my test program, so I'll post here results from my system (I did not post this test before just to make the post brief): % uname -omr FreeBSD 9.0-STABLE amd64 % cc -v Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD] % cat finite.c #include #include void check_finite(double x) { printf(" %d ", finite(x)); } int main(void) { double x; for (x = -2; x < 2; x += 0.5) { printf("%.1f", x); check_finite(x); } printf("\n"); return (0); } % cc -Wall -O2 finite.c -lm % ./a.out -2.0 1 -1.5 1 -1.0 1 -0.5 1 0.0 1 0.5 1 1.0 1 1.5 1 % cc -Wall -O2 -ffinite-math-only finite.c -lm % ./a.out -2.0 0 -1.5 0 -1.0 0 -0.5 0 0.0 0 0.5 0 1.0 0 1.5 0 Should not both results be the same? ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
Re: -ffast-math in Ports and wrong generated code
On 04/04/12 04:29, Andrey Simonenko wrote: On Tue, Apr 03, 2012 at 06:43:00AM -0700, Steve Kargl wrote: On Tue, Apr 03, 2012 at 02:21:11PM +0300, Andrey Simonenko wrote: I use one port from the Ports Collection, that works with FP. Having reinstalled it (its version was not changed) I noticed that it started to work incorrectly. After debugging and disassembling its code I found out that the -ffast-math option used for building was the result of wrongly generated code (I did not specify this option in /etc/make.conf). At least finite() function call was eliminated from the result Assembler code when -ffast-math option is used, tested on 9.0-STABLE and 10.0-CURRENT. Example test source code and generated code under 9.0-STABLE on amd64 by gcc from the base system: - #include #include void check_finite(double x) { printf("%d\n", finite(x)); } - % gcc -Wall -O2 -S finite.c - check_finite: .LFB3: subq$8, %rsp .LCFI0: callfinite <-- call to finite() movl$.LC0, %edi movl%eax, %esi addq$8, %rsp xorl%eax, %eax jmp printf .LFE3: .size check_finite, .-check_finite - % gcc -Wall -O2 -ffast-math -S finite.c - check_finite: .LFB3: xorl%esi, %esi <-- fake result from finite() movl$.LC0, %edi xorl%eax, %eax jmp printf .LFE3: .size check_finite, .-check_finite - Can somebody comment this? Read the man page for gcc. With --fast-math, gcc assumes that the result of any FP operation is finite. So, the function call to finite() is eliminated as it is always true. Looks like that I was misunderstood. I did not ask why finite() was eliminated, I asked why fake result from finite() is wrong. Obviously that -ffast-math can optimize FP arithmetics and as a result some functions can be eliminated. The problem is not respecting IEEE specifications for FP, the problem is wrongly generated code when -ffast-math is used. Actually there is a bug in GCC used in the base system. There was made a change to builtins.c from gcc in revision 1.12 [1] and as a result gcc started to eliminate finite() function calls with -ffinite-math-only. ... After this change the corresponding Assembler code for my test file is: % gcc -Wall -O2 -ffast-math -S finite.c - check_finite: .LFB3: movl$1, %esi<-- fake result from finite() movl$.LC0, %edi xorl%eax, %eax jmp printf .LFE3: .size check_finite, .-check_finite - What do you think? If there is no objections, I'll create PR. [1] http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/gcc/builtins.c.diff?r1=1.11;r2=1.12 ___ The SVN commit http://svnweb.freebsd.org/base?view=revision&revision=228756 will point you to this: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796 and we are keeping consistency with both upstream and Apple's gcc. Which is the affected port again? It should be fixed there or else the problem will continue with future compilers. Pedro. ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
Re: -ffast-math in Ports and wrong generated code
On Tue, Apr 03, 2012 at 06:43:00AM -0700, Steve Kargl wrote: > On Tue, Apr 03, 2012 at 02:21:11PM +0300, Andrey Simonenko wrote: > > > > I use one port from the Ports Collection, that works with FP. Having > > reinstalled it (its version was not changed) I noticed that it started > > to work incorrectly. After debugging and disassembling its code I found > > out that the -ffast-math option used for building was the result of > > wrongly generated code (I did not specify this option in /etc/make.conf). > > > > At least finite() function call was eliminated from the result Assembler > > code when -ffast-math option is used, tested on 9.0-STABLE and 10.0-CURRENT. > > > > Example test source code and generated code under 9.0-STABLE on amd64 > > by gcc from the base system: > > > > - > > #include > > #include > > > > void > > check_finite(double x) > > { > > printf("%d\n", finite(x)); > > } > > - > > > > % gcc -Wall -O2 -S finite.c > > - > > check_finite: > > .LFB3: > > subq$8, %rsp > > .LCFI0: > > callfinite <-- call to finite() > > movl$.LC0, %edi > > movl%eax, %esi > > addq$8, %rsp > > xorl%eax, %eax > > jmp printf > > .LFE3: > > .size check_finite, .-check_finite > > - > > > > % gcc -Wall -O2 -ffast-math -S finite.c > > - > > check_finite: > > .LFB3: > > xorl%esi, %esi <-- fake result from finite() > > movl$.LC0, %edi > > xorl%eax, %eax > > jmp printf > > .LFE3: > > .size check_finite, .-check_finite > > - > > > > Can somebody comment this? > > Read the man page for gcc. With --fast-math, > gcc assumes that the result of any FP operation > is finite. So, the function call to finite() > is eliminated as it is always true. Looks like that I was misunderstood. I did not ask why finite() was eliminated, I asked why fake result from finite() is wrong. Obviously that -ffast-math can optimize FP arithmetics and as a result some functions can be eliminated. The problem is not respecting IEEE specifications for FP, the problem is wrongly generated code when -ffast-math is used. Actually there is a bug in GCC used in the base system. There was made a change to builtins.c from gcc in revision 1.12 [1] and as a result gcc started to eliminate finite() function calls with -ffinite-math-only. The true result from finite() is non-zero value, but GCC generated always false value, so any program that uses finite() and has -ffinite-math-only works incorrectly if it was built by this version of gcc. Here is the correction for builtins.c: --- builtins.c.orig 2012-01-06 14:50:41.0 +0200 +++ builtins.c 2012-04-04 10:27:23.0 +0300 @@ -8738,7 +8738,7 @@ fold_builtin_classify (tree fndecl, tree case BUILT_IN_FINITE: if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))) && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg - return omit_one_operand (type, integer_zero_node, arg); + return omit_one_operand (type, integer_one_node, arg); if (TREE_CODE (arg) == REAL_CST) { After this change the corresponding Assembler code for my test file is: % gcc -Wall -O2 -ffast-math -S finite.c - check_finite: .LFB3: movl$1, %esi<-- fake result from finite() movl$.LC0, %edi xorl%eax, %eax jmp printf .LFE3: .size check_finite, .-check_finite - What do you think? If there is no objections, I'll create PR. [1] http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/gcc/builtins.c.diff?r1=1.11;r2=1.12 ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
Re: -ffast-math in Ports and wrong generated code
Am 03.04.2012 13:21, schrieb Andrey Simonenko: > Hello, > > I use one port from the Ports Collection, that works with FP. Having > reinstalled it (its version was not changed) I noticed that it started > to work incorrectly. After debugging and disassembling its code I found > out that the -ffast-math option used for building was the result of > wrongly generated code (I did not specify this option in /etc/make.conf). > > At least finite() function call was eliminated from the result Assembler > code when -ffast-math option is used, tested on 9.0-STABLE and 10.0-CURRENT. > > Example test source code and generated code under 9.0-STABLE on amd64 > by gcc from the base system: - Which port is affected? - Any idea whence the -ffast-math option came on your system? /etc/src.conf? Port's "make config"? ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
Re: -ffast-math in Ports and wrong generated code
On Tue, 3 Apr 2012 14:21:11 +0300, Andrey Simonenko wrote: > At least finite() function call was eliminated from the result Assembler > code when -ffast-math option is used, tested on 9.0-STABLE and 10.0-CURRENT. The documentation for -ffast-math once (GCC 3.x?) contained -ffast-math Might allow some programs designed to not be too dependent on IEEE behavior for floating-point to run faster, or die trying. which seems like what you're observing. -ffast-math includes -ffinite-math-only which assumes that floating-point arguments and results are never NaNs or +-Infs. Compiling your code with "-ffast-math -fno-finite-math-only" should restore the call to finite(). -- Thomas Mueller ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
Re: -ffast-math in Ports and wrong generated code
On Tue, Apr 03, 2012 at 02:21:11PM +0300, Andrey Simonenko wrote: > > I use one port from the Ports Collection, that works with FP. Having > reinstalled it (its version was not changed) I noticed that it started > to work incorrectly. After debugging and disassembling its code I found > out that the -ffast-math option used for building was the result of > wrongly generated code (I did not specify this option in /etc/make.conf). > > At least finite() function call was eliminated from the result Assembler > code when -ffast-math option is used, tested on 9.0-STABLE and 10.0-CURRENT. > > Example test source code and generated code under 9.0-STABLE on amd64 > by gcc from the base system: > > - > #include > #include > > void > check_finite(double x) > { > printf("%d\n", finite(x)); > } > - > > % gcc -Wall -O2 -S finite.c > - > check_finite: > .LFB3: > subq$8, %rsp > .LCFI0: > callfinite <-- call to finite() > movl$.LC0, %edi > movl%eax, %esi > addq$8, %rsp > xorl%eax, %eax > jmp printf > .LFE3: > .size check_finite, .-check_finite > - > > % gcc -Wall -O2 -ffast-math -S finite.c > - > check_finite: > .LFB3: > xorl%esi, %esi <-- fake result from finite() > movl$.LC0, %edi > xorl%eax, %eax > jmp printf > .LFE3: > .size check_finite, .-check_finite > - > > Can somebody comment this? Read the man page for gcc. With --fast-math, gcc assumes that the result of any FP operation is finite. So, the function call to finite() is eliminated as it is always true. -- Steve ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
-ffast-math in Ports and wrong generated code
Hello, I use one port from the Ports Collection, that works with FP. Having reinstalled it (its version was not changed) I noticed that it started to work incorrectly. After debugging and disassembling its code I found out that the -ffast-math option used for building was the result of wrongly generated code (I did not specify this option in /etc/make.conf). At least finite() function call was eliminated from the result Assembler code when -ffast-math option is used, tested on 9.0-STABLE and 10.0-CURRENT. Example test source code and generated code under 9.0-STABLE on amd64 by gcc from the base system: - #include #include void check_finite(double x) { printf("%d\n", finite(x)); } - % gcc -Wall -O2 -S finite.c - check_finite: .LFB3: subq$8, %rsp .LCFI0: callfinite <-- call to finite() movl$.LC0, %edi movl%eax, %esi addq$8, %rsp xorl%eax, %eax jmp printf .LFE3: .size check_finite, .-check_finite - % gcc -Wall -O2 -ffast-math -S finite.c - check_finite: .LFB3: xorl%esi, %esi <-- fake result from finite() movl$.LC0, %edi xorl%eax, %eax jmp printf .LFE3: .size check_finite, .-check_finite - Can somebody comment this? ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"