Date: Tue, 19 Nov 2019 03:15:06 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 242067] r354823 riscv64 libC has a fault in printf() where IEEE754-2008 fp128 data is output wrong Message-ID: <bug-242067-227@https.bugs.freebsd.org/bugzilla/>
index | next in thread | raw e-mail
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242067 Bug ID: 242067 Summary: r354823 riscv64 libC has a fault in printf() where IEEE754-2008 fp128 data is output wrong Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Severity: Affects Only Me Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: dclarke@blastwave.org Created attachment 209239 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=209239&action=edit Log of compile and output of assembly and check of fp128 data. I tested this on both r351523 ppc64 and riscv r350568 as well as the recent jenkins r354823 where valid and reasonable fp128 little endian data is mis-reported via printf thus : /************************************************* * The Open Group Base Specifications Issue 6 * IEEE Std 1003.1, 2004 Edition *************************************************/ #define _XOPEN_SOURCE 600 #include <ctype.h> #include <errno.h> #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> #include <sys/utsname.h> int main ( int argc, char *argv[] ) { /* note hex representation of pi is * 0x4000 0x921f 0xb544 0x42d1 0x8469 0x898c 0xc517 0x01b8 * IEEE754-2008 binary64 hex representation of pi is * 40 09 21 fb 54 44 2d 18 */ int j; long double pi = 3.14159265358979323846264338327950288419716939937510L; struct utsname uname_data; setlocale( LC_MESSAGES, "C" ); if ( uname( &uname_data ) < 0 ) { fprintf ( stderr, "WARNING : Could not attain system uname data.\n" ); perror ( "uname" ); } else { printf ( "-------------------------------" ); printf ( "------------------------------\n" ); printf ( " system name = %s\n", uname_data.sysname ); printf ( " node name = %s\n", uname_data.nodename ); printf ( " release = %s\n", uname_data.release ); printf ( " version = %s\n", uname_data.version ); printf ( " machine = %s\n", uname_data.machine ); printf ( "-------------------------------" ); printf ( "------------------------------" ); } printf ("\n"); uint8_t x86_fp80[16] = { 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; printf("x86_fp80[16]\n"); printf(" 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9,\n"); printf(" 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&x86_fp80)[j] ); } printf("\n"); printf(" x86_fp80 may be %38.34Le\n", *(long double*)&x86_fp80); printf(" x86_fp80 or be %18.14g\n", *(double*)&x86_fp80); printf("-------------------------------------------------\n"); uint8_t pi_fp64le[16] = { 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; printf("pi_fp64le[16]\n"); printf(" 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,\n"); printf(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp64le)[j] ); } printf("\n"); printf(" pi_fp64le may be %38.34Le\n", *(long double*)&pi_fp64le); printf(" pi_fp64le or be %18.14g\n", *(double*)&pi_fp64le); printf("-------------------------------------------------\n"); uint8_t pi_fp64be[16] = { 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; printf("pi_fp64be[16]\n"); printf(" 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,\n"); printf(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp64be)[j] ); } printf("\n"); printf(" pi_fp64be may be %38.34Le\n", *(long double*)&pi_fp64be); printf(" pi_fp64be or be %18.14g\n", *(double*)&pi_fp64be); printf("-------------------------------------------------\n"); uint8_t pi_fp128le[16] = { 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 }; printf("pi_fp128le[16]\n"); printf(" 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84,\n"); printf(" 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp128le)[j] ); } printf("\n"); printf(" pi_fp128le may be %38.34Le\n", *(long double*)&pi_fp128le); printf(" pi_fp128le or be %18.14g\n", *(double*)&pi_fp128le); printf("-------------------------------------------------\n"); uint8_t pi_fp128be[16] = { 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 }; printf("pi_fp128be[16]\n"); printf(" 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1,\n"); printf(" 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp128be)[j] ); } printf("\n"); printf(" pi_fp128be may be %38.34Le\n", *(long double*)&pi_fp128be); printf(" pi_fp128be or be %18.14g\n", *(double*)&pi_fp128be); printf("-------------------------------------------------\n"); for ( j=0; j<sizeof(long double); j++ ) printf("%02x ", ((unsigned char *)&pi)[j] ); printf("\n" ); printf("pi may be %38.34Le\n", pi); return (EXIT_SUCCESS); } The output from the above on a Solaris 10 Fujitsu sparcv9 server is correctly : beta $ beta $ /opt/bw/gcc9/bin/gcc -std=iso9899:1999 -pedantic -fno-builtin -g -m64 -o hex_hack hex_hack.c beta $ beta $ ./hex_hack ------------------------------------------------------------- system name = SunOS node name = beta release = 5.10 version = Generic_150400-65 machine = sun4u ------------------------------------------------------------- x86_fp80[16] 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40 0x00 0x00 0x00 0x00 0x00 0x00 x86_fp80 may be 1.4079991028348808823621394844517895e-789 x86_fp80 or be 9.839389446594e-50 ------------------------------------------------- pi_fp64le[16] 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x18 0x2d 0x44 0x54 0xfb 0x21 0x09 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64le may be 2.5291464540223296389757969198439224e-3069 pi_fp64le or be 3.2073756306764e-192 ------------------------------------------------- pi_fp64be[16] 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x40 0x09 0x21 0xfb 0x54 0x44 0x2d 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64be may be 1.1599270182075852062553167343139648e+03 pi_fp64be or be 3.1415926535898 ------------------------------------------------- pi_fp128le[16] 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 out 0xb8 0x01 0x17 0xc5 0x8c 0x89 0x69 0x84 0xd1 0x42 0x44 0xb5 0x1f 0x92 0x00 0x40 pi_fp128le may be -1.3526724668465106417844259659978911e-616 pi_fp128le or be -6.2789244204581e-39 ------------------------------------------------- pi_fp128be[16] 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 out 0x40 0x00 0x92 0x1f 0xb5 0x44 0x42 0xd1 0x84 0x69 0x89 0x8c 0xc5 0x17 0x01 0xb8 pi_fp128be may be 3.1415926535897932384626433832795028e+00 pi_fp128be or be 2.0713495408494 ------------------------------------------------- 40 00 92 1f b5 44 42 d1 84 69 89 8c c5 17 01 b8 pi may be 3.1415926535897932384626433832795028e+00 beta $ Whereas the AMD Opteron based FreeBSD 12.1 release will report the best intel fp80 format data thus : vesta$ vesta$ ./hex_hack ------------------------------------------------------------- system name = FreeBSD node name = vesta release = 12.1-RELEASE version = FreeBSD 12.1-RELEASE r354233 GENERIC machine = amd64 ------------------------------------------------------------- x86_fp80[16] 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40 0x00 0x00 0x00 0x00 0x00 0x00 x86_fp80 may be 3.1415926535897932385128089594061862e+00 x86_fp80 or be -8.8796093704934e+43 ------------------------------------------------- pi_fp64le[16] 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x18 0x2d 0x44 0x54 0xfb 0x21 0x09 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64le may be 1.6819886204449109911174915236564559e-4932 pi_fp64le or be 3.1415926535898 ------------------------------------------------- pi_fp64be[16] 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x40 0x09 0x21 0xfb 0x54 0x44 0x2d 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64be may be 6.3503887240691950845592893794047029e-4933 pi_fp64be or be 3.2073756306764e-192 ------------------------------------------------- pi_fp128le[16] 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 out 0xb8 0x01 0x17 0xc5 0x8c 0x89 0x69 0x84 0xd1 0x42 0x44 0xb5 0x1f 0x92 0x00 0x40 pi_fp128le may be 2.2823123577349716480961329732730512e+217 pi_fp128le or be -2.0963761001907e-287 ------------------------------------------------- pi_fp128be[16] 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 out 0x40 0x00 0x92 0x1f 0xb5 0x44 0x42 0xd1 0x84 0x69 0x89 0x8c 0xc5 0x17 0x01 0xb8 pi_fp128be may be 7.2660402568558392281485015532366322e+3199 pi_fp128be or be -2.7726117564375e+83 ------------------------------------------------- 35 c2 68 21 a2 da 0f c9 00 40 00 00 00 00 00 00 pi may be 3.1415926535897932385128089594061862e+00 vesta$ The recent ( and older r350568 ) r354823 reports the very wrong data in spite of having flawless perfect little endian fp128 in memory representation : # # uname -apKU FreeBSD 13.0-CURRENT FreeBSD 13.0-CURRENT #0 r354823: Mon Nov 18 19:49:20 UTC 2019 jenkins@FreeBSD-head-riscv64-build.jail.ci.FreeBSD.org:/tmp/obj/workspace/src/riscv.riscv64/sys/RISCVTEST riscv riscv64 1300058 1300058 # # # ./hex_hack.rv64imafdc ------------------------------------------------------------- system name = FreeBSD node name = release = 13.0-CURRENT version = FreeBSD 13.0-CURRENT #0 r354823: Mon Nov 18 19:49:20 UTC 2019 jenkins@FreeBSD-head-riscv64-build.jail.ci.FreeBSD.org:/tmp/obj/workspace/src/riscv.riscv64/sys/RISCVTEST machine = riscv ------------------------------------------------------------- x86_fp80[16] 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40 0x00 0x00 0x00 0x00 0x00 0x00 x86_fp80 may be 4.5565357090895492502716873808281576e-4952 x86_fp80 or be -8.8796093704934e+43 ------------------------------------------------- pi_fp64le[16] 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x18 0x2d 0x44 0x54 0xfb 0x21 0x09 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64le may be 1.2844077354038319064254933956786494e-4937 pi_fp64le or be 3.1415926535898 ------------------------------------------------- pi_fp64be[16] 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x40 0x09 0x21 0xfb 0x54 0x44 0x2d 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64be may be 1.2844077354038319066067654139395456e-4937 pi_fp64be or be 3.2073756306764e-192 ------------------------------------------------- pi_fp128le[16] 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 out 0xb8 0x01 0x17 0xc5 0x8c 0x89 0x69 0x84 0xd1 0x42 0x44 0xb5 0x1f 0x92 0x00 0x40 pi_fp128le may be 2.0000076405016834831430856216761921e+00 pi_fp128le or be -2.0963761001907e-287 ------------------------------------------------- pi_fp128be[16] 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 out 0x40 0x00 0x92 0x1f 0xb5 0x44 0x42 0xd1 0x84 0x69 0x89 0x8c 0xc5 0x17 0x01 0xb8 pi_fp128be may be -1.2377431474242674717718477250561708e-616 pi_fp128be or be -2.7726117564375e+83 ------------------------------------------------- b8 01 17 c5 8c 89 69 84 d1 42 44 b5 1f 92 00 40 pi may be 2.0000076405016834831430856216761921e+00 # I checked the assembly and the static data given to the assembler is bit for bit perfect : rv64g$ cat hex_hack.s .file "hex_hack.c" .option nopic .text .align 1 .type uname, @function uname: addi sp,sp,-32 sd ra,24(sp) sd s0,16(sp) addi s0,sp,32 sd a0,-24(s0) ld a1,-24(s0) li a0,256 call __xuname mv a5,a0 mv a0,a5 ld ra,24(sp) ld s0,16(sp) addi sp,sp,32 jr ra .size uname, .-uname .section .rodata .align 3 .LC6: .string "C" .align 3 . . . .LC46: .string "pi may be %38.34Le\n" .align 3 . . . main: addi sp,sp,-1424 sd ra,1416(sp) sd s0,1408(sp) addi s0,sp,1424 mv a5,a0 sd a1,-1424(s0) sw a5,-1412(s0) lui a5,%hi(.LC5) ld a4,%lo(.LC5)(a5) sd a4,-48(s0) ld a5,%lo(.LC5+8)(a5) sd a5,-40(s0) lui a5,%hi(.LC6) addi a1,a5,%lo(.LC6) li a0,6 call setlocale addi a5,s0,-1328 mv a0,a5 call uname . . . . .L16: lw a5,-20(s0) mv a4,a5 li a5,15 bleu a4,a5,.L17 lui a5,%hi(.LC17) addi a0,a5,%lo(.LC17) call printf ld a5,-48(s0) ld a6,-40(s0) mv a2,a5 mv a3,a6 lui a5,%hi(.LC46) addi a0,a5,%lo(.LC46) call printf li a5,0 mv a0,a5 ld ra,1416(sp) ld s0,1408(sp) addi sp,sp,1424 jr ra .size main, .-main .section .rodata .align 4 .LC5: .word 3306619320 .word 2221509004 .word 3041149649 .word 1073779231 .ident "GCC: (GNU) 8.2.0" rv64g$ The static data at LC5 is correct thus : rv64g$ echo '16o 1073779231p 3041149649p 2221509004p 3306619320pq' | dc 4000921F B54442D1 8469898C C51701B8 rv64g$ However the output from printf("pi may be %38.34Le\n", pi) is clearly wrong. -- Dennis Clarke RISC-V/SPARC/PPC/ARM/CISC UNIX and Linux spoken GreyBeard and suspenders optional -- You are receiving this mail because: You are the assignee for the bug.help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-242067-227>
