[Bug 242067] r354823 riscv64 libC has a fault in printf() where IEEE754-2008 fp128 data is output wrong
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Tue Nov 19 03:15:08 UTC 2019
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 at FreeBSD.org
Reporter: dclarke at 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 at 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 at 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.
More information about the freebsd-bugs
mailing list