Skip site navigation (1)Skip section navigation (2)
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/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D242067

            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=3D209239&action=
=3Dedit
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 :=20


/*************************************************
 * 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=20
     *   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 =3D 3.14159265358979323846264338327950288419716939937510=
L;

    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 =3D %s\n", uname_data.sysname );
        printf ( "          node name =3D %s\n", uname_data.nodename );
        printf ( "            release =3D %s\n", uname_data.release );
        printf ( "            version =3D %s\n", uname_data.version );
        printf ( "            machine =3D %s\n", uname_data.machine );
        printf ( "-------------------------------" );
        printf ( "------------------------------" );
    }
    printf ("\n");

    uint8_t x86_fp80[16] =3D { 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0x=
c9,
                             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=3D0; 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] =3D { 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0=
x40,
                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0=
0 };
    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=3D0; 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] =3D { 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0=
x18,
                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0=
0 };
    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=3D0; 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] =3D { 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, =
0x84,
                               0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x=
40
};
    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=3D0; 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);=20
    printf("-------------------------------------------------\n");

    uint8_t pi_fp128be[16] =3D { 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, =
0xd1,
                               0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0x=
b8
};
    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=3D0; j<16; j++ ) {
        printf("0x%02x ", ((uint8_t *)&pi_fp128be)[j] );
    }
    printf("\n");=20=20=20=20=20=20=20
    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=3D0; 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=20
correctly :=20

beta $=20
beta $ /opt/bw/gcc9/bin/gcc -std=3Diso9899:1999 -pedantic -fno-builtin -g -=
m64 -o
hex_hack hex_hack.c=20
beta $=20
beta $ ./hex_hack
-------------------------------------------------------------
        system name =3D SunOS
          node name =3D beta
            release =3D 5.10
            version =3D Generic_150400-65
            machine =3D 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 0=
x00
0x00=20
    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 0=
x00
0x00=20
   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 0=
x00
0x00=20
   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 0=
x00
0x40=20
  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 0=
x01
0xb8=20
  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=20
pi may be 3.1415926535897932384626433832795028e+00
beta $=20

Whereas the AMD Opteron based FreeBSD 12.1 release will report the best
intel fp80 format data thus :=20

vesta$=20
vesta$ ./hex_hack
-------------------------------------------------------------
        system name =3D FreeBSD
          node name =3D vesta
            release =3D 12.1-RELEASE
            version =3D FreeBSD 12.1-RELEASE r354233 GENERIC
            machine =3D 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 0=
x00
0x00=20
    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 0=
x00
0x00=20
   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 0=
x00
0x00=20
   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 0=
x00
0x40=20
  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 0=
x01
0xb8=20
  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=20
pi may be 3.1415926535897932385128089594061862e+00
vesta$=20

The recent ( and older r350568 ) r354823 reports the very wrong data
in spite of having flawless perfect little endian fp128 in memory=20
representation :=20
#=20
# uname -apKU
FreeBSD  13.0-CURRENT FreeBSD 13.0-CURRENT #0 r354823: Mon Nov 18 19:49:20 =
UTC
2019=20=20=20=20
jenkins@FreeBSD-head-riscv64-build.jail.ci.FreeBSD.org:/tmp/obj/workspace/s=
rc/riscv.riscv64/sys/RISCVTEST
 riscv riscv64 1300058 1300058
#=20
#=20
# ./hex_hack.rv64imafdc
-------------------------------------------------------------
        system name =3D FreeBSD
          node name =3D=20
            release =3D 13.0-CURRENT
            version =3D FreeBSD 13.0-CURRENT #0 r354823: Mon Nov 18 19:49:2=
0 UTC
2019=20=20=20=20
jenkins@FreeBSD-head-riscv64-build.jail.ci.FreeBSD.org:/tmp/obj/workspace/s=
rc/riscv.riscv64/sys/RISCVTEST
            machine =3D 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 0=
x00
0x00=20
    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 0=
x00
0x00=20
   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 0=
x00
0x00=20
   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 0=
x00
0x40=20
  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 0=
x01
0xb8=20
  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=20
pi may be 2.0000076405016834831430856216761921e+00
#=20

I checked the assembly and the static data given to the assembler is
bit for bit perfect :=20

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$=20

The static data at LC5 is correct thus :=20

rv64g$ echo '16o 1073779231p 3041149649p 2221509004p 3306619320pq' | dc=20
4000921F
B54442D1
8469898C
C51701B8
rv64g$=20

However the output from printf("pi may be %38.34Le\n", pi) is clearly
wrong.=20



--=20
Dennis Clarke
RISC-V/SPARC/PPC/ARM/CISC
UNIX and Linux spoken
GreyBeard and suspenders optional

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-242067-227>