From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10133 invoked by alias); 11 Feb 2003 04:06:03 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 10110 invoked by uid 71); 11 Feb 2003 04:06:02 -0000 Resent-Date: 11 Feb 2003 04:06:02 -0000 Resent-Message-ID: <20030211040602.10109.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, richard@wetafx.co.nz Received: (qmail 7071 invoked by uid 48); 11 Feb 2003 03:59:43 -0000 Message-Id: <20030211035943.7070.qmail@sources.redhat.com> Date: Tue, 11 Feb 2003 04:06:00 -0000 From: richard@wetafx.co.nz Reply-To: richard@wetafx.co.nz To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: optimization/9654: extra-precision fp comparisons are less accurate X-SW-Source: 2003-02/txt/msg00480.txt.bz2 List-Id: >Number: 9654 >Category: optimization >Synopsis: extra-precision fp comparisons are less accurate >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Tue Feb 11 04:06:01 UTC 2003 >Closed-Date: >Last-Modified: >Originator: richard@wetafx.co.nz >Release: g++3 (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7) >Organization: >Environment: Linux 2.4.18-xfssmp #1 SMP i686 >Description: //////////bug.cc: #include double s(double t) throw() { double d = 0.75+t; double o = d < 1.0 ? acos(d) : 1.0/67108864.0; return sin(o*0.5)/sin(o); } int main(void) { return isnan(s(0.25-1.0/18014398509481984.0)); } //////////GNUmakefile: bug: bug.cc; g++3 -O1 -o bug bug.cc -lm >How-To-Repeat: With the two specified files, use gmake to build. With optimization turned on, the comparison between d and 1.0 on line 6 succeeds when it should fail. Essentially, the value that is computed for d is still in an fp register (with extra precision) when it is compared with 1.0. That value is less then 1.0, but by the time it is actually converted to a double, it gets rounded to 1.0. Thus, the situation that the comparison is trying to trap does not get trapped. Corresponding problems also appear with floats. This problem also shows up with: gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.2) >Fix: There are various ways to work around this. Obviously, the code can be changed slightly so that the intended effect is correct. However, other similar problems may be far more subtle than generating a NaN. The problem can be avoid using the -ffloat-store option, but that has detrimental effects on performance. It would be great if floating point comparisons (float or double) were guaranteed to be on values at the precision specified by the source code, and not on values with extra precision. If this cannot be the default, perhaps there should at least be an option like -ffloat-compare so that there is a mid-ground between the performance hit of using -ffloat-store and the reliability hit of not using -ffloat-store. >Release-Note: >Audit-Trail: >Unformatted: