This is a place holder for the work I had done on bringing the old gcc 2.95 floating point printing code back into the library. I had gotten as far as having working code on x86 for double and long double, but we had stalled on getting configury bits in place. I've been busy for a while, but this has still been in the back of my mind. Basically, the code is about 3x faster than printf for a subset of numbers where it can be accurately printed using hardware fp. When using big ints, it was about 50% slower than printf on x86 linux. The code also contains data to print IBM and VAX fp numbers, but not for c4x fp numbers. It also had not been tested on platforms other than x86 linux. However, it showed promise :-)
Excellent to see this back in active status. Jerry, can you attach the current version of your patch here? Thanks. Have you tested this on big/small endian machines, and a 64 bit arch? FYI your approach seems sane to me. I'll review this patch today/tomorrow. -benjamin
Created attachment 7038 [details] floating point patch
So far I've only tested on x86. I promised Paolo I'd get a test program up, and I'll try to get it here today.
Created attachment 7039 [details] jq initial patch, as applied Jerry, here's your patch as applied by me. I had problems with your original patch. On this one, I'm getting: /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc: In function `int std::__dec_exponent(_T, int&, bool&)': /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:314: error: expected `;' before numeric constant /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc: In function `char* std::__dtoa(char*, _T, int, int, int, bool, int*)': /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:458: error: expected `;' before "k" /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:514: error: expected `;' before numeric constant /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:531: error: expected primary-expression before "int" /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:531: error: `'0'' cannot be used as a function /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:531: error: expected `;' before "L" /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:533: error: expected `)' before "eps" /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:580: error: expected primary-expression before "int" /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:580: error: `'0'' cannot be used as a function /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:580: error: expected `;' before "L" /mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:619: error: expected `;' before numeric constant with mainline gcc as of 20040901. Are you using 3.4 for this, or did I mangle the patch? Hmm. -benjamin
Also, if I remember correctly, there was a test program in the last drop of these sources. I'll try to dig that testsuite entry out of this tarball: http://people.redhat.com/bkoz/libstdc++-v3.jq.20040127+.tar.bz2
Created attachment 7040 [details] patch round two Whoops, I had made a mistake when hand-applying that patch. Here's the corrected copy at applies to mainline gcc. Jerry, I get some new fails with this, on x86/linux. Thoughts? FAIL: 22_locale/num_put/put/char/1.cc execution test FAIL: 22_locale/num_put/put/char/wrapped_env.cc execution test FAIL: 22_locale/num_put/put/char/wrapped_locale.cc execution test FAIL: 22_locale/num_put/put/wchar_t/1.cc execution test FAIL: 22_locale/num_put/put/wchar_t/wrapped_env.cc execution test FAIL: 22_locale/num_put/put/wchar_t/wrapped_locale.cc execution test FAIL: 27_io/basic_ostream/inserters_arithmetic/char/4402.cc execution test FAIL: 27_io/basic_ostream/inserters_arithmetic/char/5.cc execution test FAIL: 27_io/basic_ostream/inserters_arithmetic/char/6.cc execution test Is anybody else having better luck with this (Paolo?) -benjamin
This is a v2 regression. I think the last one, code-wise.
Created attachment 7046 [details] double printing test Set dorand=true for random numbers, false for integers. Set dosprintf and cmpall true to compare the library output to sprintf output.
Created attachment 7047 [details] long double test program Set dorand=true for random numbers, false for integers. Set dosprintf and cmpall true to compare the library output to sprintf output.
Weird. I left a comment before but it didn't go through... I saw no new testsuite failures when I applied the patch. But I've been blocked the last week or so with a failure on compiling libsup++/guard.cc and undeclared mutex types. This is on 686-pc-linux-gnu. I'm attaching versions of my test programs for double and long double.
Created attachment 7048 [details] fp test from libio I think this is the test I included with the previous incarnation of the patch. It was drawn from gcc 2.95 libio's testsuite.
Thanks Jerry for the tests.
Created attachment 7114 [details] patch round 3
Created attachment 7522 [details] patch as applied Last patch, as applied to cvs mainline. I get three fails with this: FAIL: 26_numerics/complex/complex_inserters_extractors.cc execution test FAIL: 27_io/basic_ostream/inserters_arithmetic/char/1.cc execution test FAIL: 27_io/basic_ostream/inserters_arithmetic/wchar_t/1.cc execution test === libstdc++ Summary === # of expected passes 3080 # of unexpected failures 3 # of unexpected successes 2 # of expected failures 5
I don't see any of those failures. I updated tonight (11/12). Did a fresh config and make (not bootstrap) on x86 pentium M. FAIL: 23_containers/bitset/input/1.cc (test for excess errors) FAIL: 23_containers/bitset/to_ulong/1.cc (test for excess errors) FAIL: 27_io/basic_filebuf/open/char/3.cc (test for excess errors) FAIL: 27_io/basic_iostream/4.cc (test for excess errors) FAIL: 27_io/basic_istream/ignore/char/6360.cc (test for excess errors) FAIL: 27_io/basic_stringstream/str/char/2.cc (test for excess errors)
Subject: Re: Floating point output is slow >I don't see any of those failures. I updated tonight (11/12). Did a fresh >config and make (not bootstrap) on x86 pentium M. Hmmm. Well, maybe I munged the floatconv.cc file again. Your patch does not apply, thus my contortions and sadness. If you'd cvs add src/floatconf.cc cvsdiff -N src/floatconv.cc when making patches this would be so much easier.... Failing that, can you attach your version of floatconv.cc to gcc bugzilla, so I can re-test? Thanks. >FAIL: 23_containers/bitset/input/1.cc (test for excess errors) >FAIL: 23_containers/bitset/to_ulong/1.cc (test for excess errors) >FAIL: 27_io/basic_filebuf/open/char/3.cc (test for excess errors) >FAIL: 27_io/basic_iostream/4.cc (test for excess errors) >FAIL: 27_io/basic_istream/ignore/char/6360.cc (test for excess errors) >FAIL: 27_io/basic_stringstream/str/char/2.cc (test for excess errors) I don't see any of these....
OK, my problem is that the patch didn't actually get applied to mainline. So it's not so surprising I didn't see the failures. I'll apply locally and debug.
Created attachment 7560 [details] patch with fix
OK - turned out to be a simple bug, not adjusting for the minus sign. Amazingly all of the above patches had the bug and I couldn't have had successful tests with it there. Here's the updated patch with floatconv.c properly included ;-) One note is I used automake-1.9.3 to regen Makefile.in. If that's an issue, I can hand-edit the .in file easily enough - just 2 changes. Fixes the regressions in make check. If you're OK with the automake stuff I'll check it in, else do the more minimal edit.
This patch applies, and passes regression testing on x86/linux. Now I can start to review it.... Paolo, any chance you can test this as well? -benjamin
Sure, and *sorry* for the delay :-( I will do that over the weekend, both on ia64 and x86_64.
Hi again. As expected, fpfinal3 regtests Ok on x86/x86_64/ia64-linux. I'm attaching what I have actually tested: doesn't include the regenerated files and avoids a warning about the unused __mod argument of _M_insert_float. Tomorrow, would like to run on the 64-bit machines the specific floating point output tests. A final note: we should add a testcase for the fixed (corner case) issue with grouping (which, basically, is a WONTFIX for 3.3 and 3.4)
Created attachment 7579 [details] Paolo's minor tweaks (__mod, formatting)
Hi again. I'm now running on the three architectures the following tests: 1-
Hi again. I'm now running on the three architectures the following tests attached to the PR. 1- fmttest1.cc 2- fptest.cc 3- lfptest.cc The second one seems basically OK, besides some problems, on x86 *only*, of this type: fd.x[0]=0x32f8c7de; fd.x[1]=0xbf19c68d; dtoa -0.0001 printf -1e-04 mismatch mode e.0 fd.x[0]=0x207c7765; fd.x[1]=0x3fef97c6; dtoa 1e+00 printf 1e-00 I think we already discussed those a bit with Jerry, seem not serious: indeed, both x86_64 and ia64 (with a *newer* glibc installed) are 100% OK. I'm having more problems with fmttest1.cc, which fails on *all* three machines (assertion at line 4098). Jerry, Benjamin, does it pass for you? Also, with lfptest.cc, that segfaults consistently on x86_64 and ia64 at line 56: if (dosprintf) sprintf(buf2, "%Lf",fd.d); Time permitting, I'd like to help investigating the last one, at least. That's all for now.
fmttest1.cc fails like this: expect[14]: -1.007830e-18 result[14]: -1.00783e-18
A bit of additional info for lfptest too: if I set outcpp to true, then, on x86_64: nan Segmentation fault On ia64: 0.000000 Segmentation fault right at the first iteration.
I finally got some free time again. The fmttest1 failure is due to showpoint handling. Specifically, there's the following hunk in float_to_char_scientific: // Insert digits after decimal point for (;__prec && *__bp; __prec--) *__sbuf++ = __digits[*__bp++ - '0']; if (__pad) while (__prec--) *__sbuf++ = __digits[0]; That if test should be if (__pad || __showpoint). I'm still having some trouble building. When I get that sorted out, I'll update the patch with this change. I don't know what's broken w/ 64 bit, though, and still don't really have 64 bit access.
Created attachment 7755 [details] Patch with showpoint fix This applies the fix for fmttest1, which now works correctly.
Trying on a power4 aix 5.2 box, in the testsuite, 27_io/basic_ostream/inserts_arithmetic/char/1.cc fails, because of a segfault in frexp(long double, int). In gdb, the args look fine. The int seems to be a valid pointer, since I can set the value without problem.
The power4 segfault occurs in frexpl() in libc, which is a result of calling __builtin_frexpl() inside std::frexp(long double). I was wondering if it might be a problem in long double representation. I think ppc uses 64 bit long double, which made me think that it should be calling frexp under the covers rather than frexpl. I also created a simple test program for frexp that sems to work for double and not for long double. This is making me think the problem isn't in this patch.
The AIX problem is PR19115. Paolo, could you see if the same issue happens on ia64 and x86-64?
(In reply to comment #31) > The power4 segfault occurs in frexpl() in libc, which is a result of calling > __builtin_frexpl() inside std::frexp(long double). I was wondering if it might > be a problem in long double representation. I think ppc uses 64 bit long > double, which made me think that it should be calling frexp under the covers > rather than frexpl. PPC AIX uses 128bit long doubles. There are a couple of different issues for 128bit long double support in gcc for PPC, see PR 19019 for one of them, in fact that might be the problem here but I don't know.
Also I should note use of long double functions on tagets where it does not does it will cause a link error so be care full with that.
Hi everyone, and sorry about the delay of the planned testing on 64-bit arches. Hopefully, I can do that before Christmas...
Hi Jerry, I'm finally ready to work again on x86_64 and ia64 but unfortunately your latest patch doesn't apply cleanly here: patching file include/bits/locale_facets.tcc Hunk #2 FAILED at 1382. Can you please rediff? Thanks!
Created attachment 7864 [details] Rediffed against 1/3/05 mainline
Thanks!
Hi again. Some good news: first, I can confirm that fmttest1.cc does not fail anymore. Morevoer, on x86-64 lfptest fails with gcc3.3 too, therefore something seems wrong in the testcase, not in fpfinal5.patch. While a I dig a little deeper on these issues (and do complete tests on ia64 too), maybe Jerry, you can try to fix lfptest: it would be nice to actually run it to success on the 64-bit machines too... The backtrace is as follows: (gdb) backtrace #0 0x0000002a95b2f10b in __printf_fp () from /lib64/tls/libc.so.6 #1 0x0000002a95b2b416 in vfprintf () from /lib64/tls/libc.so.6 #2 0x0000002a95b46659 in vsprintf () from /lib64/tls/libc.so.6 #3 0x0000002a95b31af8 in sprintf () from /lib64/tls/libc.so.6 #4 0x0000000000401114 in main () at lfptest.cc:58 And, if I print fd.d inside gdb just before the segfault: (gdb) p fd.d $1 = <invalid float value> Are we passing to sprintf a completely crazy third arg?!?
(In reply to comment #39) > seems wrong in the testcase, not in fpfinal5.patch. While a I dig a little > deeper on these issues (and do complete tests on ia64 too), maybe Jerry, you > can try to fix lfptest: it would be nice to actually run it to success on the > 64-bit machines too... The backtrace is as follows: > And, if I print fd.d inside gdb just before the segfault: > (gdb) p fd.d > $1 = <invalid float value> Hmm, I remember that I had to fiddle with the long double values to make them work on x86. Not all random bitstrings are valid x86 long doubles. This test isn't the most portable, since I generate values by creating random longs and stitching them together. I'll have to look up the format for ia64 long double, but we may end up going back and forth a couple of times to get it right.
Subject: Re: Floating point output is slow pcarlini at suse dot de wrote: > ------- Additional Comments From pcarlini at suse dot de 2005-01-03 16:41 ------- > Hi again. Some good news: first, I can confirm that fmttest1.cc does not fail > anymore. Morevoer, on x86-64 lfptest fails with gcc3.3 too, therefore something > seems wrong in the testcase, not in fpfinal5.patch. While a I dig a little > deeper on these issues (and do complete tests on ia64 too), maybe Jerry, you > can try to fix lfptest: it would be nice to actually run it to success on the > 64-bit machines too... The backtrace is as follows: > (gdb) backtrace > #0 0x0000002a95b2f10b in __printf_fp () from /lib64/tls/libc.so.6 > #1 0x0000002a95b2b416 in vfprintf () from /lib64/tls/libc.so.6 > #2 0x0000002a95b46659 in vsprintf () from /lib64/tls/libc.so.6 > #3 0x0000002a95b31af8 in sprintf () from /lib64/tls/libc.so.6 > #4 0x0000000000401114 in main () at lfptest.cc:58 > > And, if I print fd.d inside gdb just before the segfault: > (gdb) p fd.d > $1 = <invalid float value> > > Are we passing to sprintf a completely crazy third arg?!? Sorry about the delay. I'm really not sure what's wrong with the test program. The backtrace only says that it doesn't like the random long double I'm generating. It appears that x86-64 uses the same long double as x86. The only thing I can think of is that the libs get upset if the top 32 bits that are unused have junk in them. I'm attaching a copy of lfptest that zeros out the top 32 bits so that there are only 80 bits of random numbers and the rest of 128 bits are zero. The other thing you can try is to run the test with dorand=false. This makes it use the loop index as the number to print. It's also a good test to run and can flush out different problems than the random test.
Created attachment 7967 [details] Updated long double test Zero's out 4th word in long double on 80 bit values
Ok, will follow your suggestions.
*** Bug 19642 has been marked as a duplicate of this bug. ***