From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2575 invoked by alias); 22 Dec 2008 16:30:56 -0000 Received: (qmail 1778 invoked by uid 48); 22 Dec 2008 16:29:35 -0000 Date: Mon, 22 Dec 2008 16:30:00 -0000 Message-ID: <20081222162935.1777.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug fortran/37472] bad output on default-format write of double in common block with -m64 flag i In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "dominiq at lps dot ens dot fr" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2008-12/txt/msg02069.txt.bz2 ------- Comment #16 from dominiq at lps dot ens dot fr 2008-12-22 16:29 ------- >>From http://gcc.gnu.org/ml/fortran/2008-12/msg00284.html: > With Steve Kargl's help, the following simple patch was found to eliminate this output > problem on x86-64. I plan to commit under simple and makes sense to do rule. Is not the same problem lurking in if ((m > 0.0 && m < 0.1 - 0.05 / exp_d) || (m >= exp_d - 0.5 ) ||\ with 0.1 and 0.05? Also there is probably some room for optimization in this piece of code. For instance calculate_exp_* computes 10**d through an algorithm linear in d, while it could be computed in O(log2(d)) (see poweri in gcc/builtins.c). Also the following change: --- /opt/gcc/_gcc_clean/libgfortran/io/write_float.def 2008-12-21 22:31:05.000000000 +0100 +++ /opt/gcc/gcc-4.4-work/libgfortran/io/write_float.def 2008-12-22 16:27:10.000000000 +0100 @@ -640,8 +640,8 @@ GFC_REAL_ ## x temp;\ mid = (low + high) / 2;\ \ - temp = 0.1 * calculate_exp_ ## x (mid) - 0.5\ - * calculate_exp_ ## x (mid - d - 1);\ + temp = calculate_exp_ ## x (mid) \ + * (1.0 - 0.5 / exp_d) / 10;\ \ if (m < temp)\ { \ speeds up by ~2s the following test: character(80) s real*8 x, y integer i x=1.0 y=0.0 do i = 1, 10000000 write(s,*) y y = y + x end do print *, s end (still twice slower with gfortran than ifort or g77). Note that "temp = calculate_exp_ ## x (mid-1) * (1.0 - 0.5 / exp_d)" is slightly slower. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37472