From owner-freebsd-current@FreeBSD.ORG Wed Apr 4 09:29:26 2012 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3778E106564A for ; Wed, 4 Apr 2012 09:29:26 +0000 (UTC) (envelope-from simon@comsys.ntu-kpi.kiev.ua) Received: from comsys.kpi.ua (comsys.kpi.ua [77.47.192.42]) by mx1.freebsd.org (Postfix) with ESMTP id A5E288FC0C for ; Wed, 4 Apr 2012 09:29:25 +0000 (UTC) Received: from pm513-1.comsys.kpi.ua ([10.18.52.101] helo=pm513-1.comsys.ntu-kpi.kiev.ua) by comsys.kpi.ua with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.63) (envelope-from ) id 1SFMWq-0001QY-3G; Wed, 04 Apr 2012 12:29:24 +0300 Received: by pm513-1.comsys.ntu-kpi.kiev.ua (Postfix, from userid 1001) id C301B1CC36; Wed, 4 Apr 2012 12:29:23 +0300 (EEST) Date: Wed, 4 Apr 2012 12:29:23 +0300 From: Andrey Simonenko To: Steve Kargl Message-ID: <20120404092923.GA1087@pm513-1.comsys.ntu-kpi.kiev.ua> References: <20120403112111.GA39616@pm513-1.comsys.ntu-kpi.kiev.ua> <20120403134300.GA98102@troutmask.apl.washington.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20120403134300.GA98102@troutmask.apl.washington.edu> User-Agent: Mutt/1.5.21 (2010-09-15) X-Authenticated-User: simon@comsys.ntu-kpi.kiev.ua X-Authenticator: plain X-Sender-Verify: SUCCEEDED (sender exists & accepts mail) X-Exim-Version: 4.63 (build at 28-Apr-2011 07:11:12) X-Date: 2012-04-04 12:29:24 X-Connected-IP: 10.18.52.101:12908 X-Message-Linecount: 122 X-Body-Linecount: 106 X-Message-Size: 4396 X-Body-Size: 3652 Cc: freebsd-current@freebsd.org Subject: Re: -ffast-math in Ports and wrong generated code X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Apr 2012 09:29:26 -0000 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: > > call finite <-- 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.000000000 +0200 +++ builtins.c 2012-04-04 10:27:23.000000000 +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