Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perl 5.34 fails to build with GCC 12.0.1 on ppc64le (ext/XS-APItest/t/printf.t) #19373

Closed
jplesnik opened this issue Jan 27, 2022 · 26 comments
Closed

Comments

@jplesnik
Copy link

Module:
XS-APItest

Description

On Fedora, the build of perl 5.34 fails with GCC 12.0.1, but only on ppc64le. The failure is caused by test ext/XS-APItest/t/printf.t

../ext/XS-APItest/t/postinc.t ........................................ ok
#   Failed test 'print_long_double'
#   at t/printf.t line 44.
#          got: '0.000'
#     expected: '7.000'
#   Failed test 'print_long_doubleL'
#   at t/printf.t line 45.
#          got: '0.000'
#     expected: '7.000'
# Looks like you failed 2 tests of 13.
../ext/XS-APItest/t/printf.t ......................................... 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/13 subtests 

Steps to Reproduce

# perl -Ilib ext/XS-APItest/t/printf.t 
1..13
ok 1 - use XS::APItest;
ok 2 - saving STDOUT
ok 3 - redirecting STDOUT
ok 4 - restore STDOUT
ok 5 - open foo.out
ok 6 - captured at least four output lines
ok 7 - print_double
ok 8 - print_int
ok 9 - print_long
ok 10 - print_float
not ok 11 - print_long_double
#   Failed test 'print_long_double'
#   at ext/XS-APItest/t/printf.t line 44.
#          got: '0.000'
#     expected: '7.000'
not ok 12 - print_long_doubleL
#   Failed test 'print_long_doubleL'
#   at ext/XS-APItest/t/printf.t line 45.
#          got: '0.000'
#     expected: '7.000'
ok 13 - check types for IV_MAX and UV_MAX match IVdf/UVuf
# Looks like you failed 2 tests of 13.

Expected behavior

The test should pass on all architectures.

Perl configuration

# gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/ppc64le-redhat-linux/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: ppc64le-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-targets=powerpcle-linux --disable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-12.0.1-20220118/obj-ppc64le-redhat-linux/isl-install --enable-offload-targets=nvptx-none --without-cuda-driver --enable-offload-defaulted --enable-gnu-indirect-function --enable-secureplt --with-long-double-128 --with-long-double-format=ieee --with-cpu-32=power8 --with-tune-32=power8 --with-cpu-64=power8 --with-tune-64=power8 --build=ppc64le-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.0.1 20220118 (Red Hat 12.0.1-0) (GCC) 

# ./perl -V
Summary of my perl5 (revision 5 version 34 subversion 0) configuration:
   
  Platform:
    osname=linux
    osvers=5.12.13-300.fc34.ppc64le
    archname=ppc64le-linux-thread-multi
    uname='linux buildvm-ppc64le-28.iad2.fedoraproject.org 5.12.13-300.fc34.ppc64le #1 smp wed jun 23 16:02:05 utc 2021 ppc64le ppc64le ppc64le gnulinux '
    config_args='-des -Doptimize=none -Dccflags=-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Dldflags=-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Dlddlflags=-shared -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.34.0 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5/5.34 -Dsitearch=/usr/local/lib64/perl5/5.34 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=ppc64le-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize -Duse64bitint'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='gcc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='  -g'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -fwrapv -fno-strict-aliasing -I/usr/local/include'
    ccversion=''
    gccversion='11.2.1 20210728 (Red Hat 11.2.1-1)'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=7
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='gcc'
    ldflags ='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib
    libs=-lpthread -lresolv -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lresolv -ldl -lm -lcrypt -lutil -lc
    libc=/lib/../lib64/libc.so.6
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.34.9000'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 '
    cccdlflags='-fPIC'
    lddlflags='-lpthread -shared -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_TIMES
    MULTIPLICITY
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_IMPLICIT_CONTEXT
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_ITHREADS
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
    USE_REENTRANT_API
    USE_SITECUSTOMIZE
    USE_THREAD_SAFE_LOCALE
  Built under linux
  Compiled at Oct 18 2021 00:00:00
  @INC:
    /usr/local/lib64/perl5/5.34
    /usr/local/share/perl5/5.34
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5
@hvds
Copy link
Contributor

hvds commented Jan 27, 2022

That's curious - I think it should be equivalent to this C code:

#include <stdio.h>
  
int main(int argc, char** argv) {
    long double val = 7.0;
    printf("%5.3Lf\n", val);
    return 0;
}

Does that work on the affected system? It sounds likely to be a library or compiler bug.

@jplesnik
Copy link
Author

@hvds the output is 7.000. I really don't understand what could be wrong.

@Leont
Copy link
Contributor

Leont commented Jan 27, 2022

That is weird, because @hvds 's snipplet is exactly what the second test does internally.

Did you compile it with the same flags and such?

@sisyphus
Copy link
Contributor

sisyphus commented Jan 28, 2022

longdblkind=7

@jplesnik, that longdblkind setting is as I would expect, but do you know for sure that it's correct ?
A value of 7 indicates that perl thinks that the "long double" is a pair of little-endian doubles, with that pair arranged in big-endian order - ie (7, 0) not (0, 7).

It looks to me that either perl itself has not correctly recognized the long double format, or PERL_PRIfldbl is not defined appropriately.

I would actually install Inline::C to facilitate the probing of this perl's handling of long double.
You could start with something like:

UPDATED: Original script failed to link to -lm, which adversely affected the result.
I've now edited the script to fix that ... and edited the results to match the new (corrected) behaviour.

use strict;
use warnings;

use Inline C => Config =>
  USING => 'ParseRegExp',
  LIBS => '-lm',
  BUILD_NOISY => 1,
  ;

use Inline C => <<'EOC';

void foo(SV * in) {
   int i;
   long double val = (long double)SvNV(in);
   void *p = &val;

   val = sqrtl(val);

   if(sizeof(long double) != 16)
     croak ("'long double' not correctly recognized\n");

   printf("%5.3Lf\n", val);

   for(i = 0; i < 16; i++)
     printf("%02x", ((unsigned char*)p)[i]);

  printf("\n");
}

EOC

foo(2.0);

For perl-5.35.4, on my ppc64be machine (longdblkind=6, nvtype='double'), that outputs:

1.414
3ff6a09e667f3bcdbc9bdd3413b26456

What do you get ?

Correct output (if I'm thinking correctly) on your machine would be:

1.414
cd3b7f669ea0f63f5664b21334dd9bbc

But, given the strange test failure, I wouldn't be surprised if that hex output you get will begin with 16 zeros.

Afterthought:
@jplesnik, you could also try:

$ perl -le 'print  unpack "h*", pack "D", 7.0;'

which, for you, should output:

000000000000c1040000000000000000

@Leont
Copy link
Contributor

Leont commented Jan 28, 2022

or PERL_PRIfldbl is not defined appropriately.

If that was the case the second test wouldn't also fail

@sisyphus
Copy link
Contributor

sisyphus commented Jan 28, 2022 via email

@sisyphus
Copy link
Contributor

sisyphus commented Jan 28, 2022

I really don't understand what could be wrong.

I've just noticed that perl reports that it was built using a different version of gcc:

gccversion='11.2.1 20210728 (Red Hat 11.2.1-1)'

I don't know if that has any connection to the problem and/or its solution

@jplesnik
Copy link
Author

The system libperl.so was used for builded ./perl -V. There is a correct output for perl which is used for tests.

# LD_LIBRARY_PATH=/builddir/build/BUILD/perl-5.34.0 /builddir/build/BUILD/perl-5.34.0/preload /builddir/build/BUILD/perl-5.34.0/libperl.so  ./perl -Ilib -I. -V
Summary of my perl5 (revision 5 version 34 subversion 0) configuration:
   
  Platform:
    osname=linux
    osvers=5.15.16-100.fc34.x86_64
    archname=ppc64le-linux-thread-multi
    uname='linux 7654c5d44886461a9719c83e806c2e68 5.15.16-100.fc34.x86_64 #1 smp thu jan 20 16:34:27 utc 2022 ppc64le ppc64le ppc64le gnulinux '
    config_args='-des -Doptimize=none -Dccflags=-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Dldflags=-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/perl-5.34.0/.package_note-perl-1.04-483.fc36.ppc64le.ld -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/perl-5.34.0/.package_note-perl-1.04-483.fc36.ppc64le.ld -Dlddlflags=-shared -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/perl-5.34.0/.package_note-perl-1.04-483.fc36.ppc64le.ld -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.34.0 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5/5.34 -Dsitearch=/usr/local/lib64/perl5/5.34 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=ppc64le-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize -Duse64bitint'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='gcc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='  -g'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -fwrapv -fno-strict-aliasing -I/usr/local/include'
    ccversion=''
    gccversion='12.0.1 20220118 (Red Hat 12.0.1-0)'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=1
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='gcc'
    ldflags ='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/perl-5.34.0/.package_note-perl-1.04-483.fc36.ppc64le.ld -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib
    libs=-lpthread -lresolv -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lresolv -ldl -lm -lcrypt -lutil -lc
    libc=/lib/../lib64/libc.so.6
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.34.9000'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/perl-5.34.0/.package_note-perl-1.04-483.fc36.ppc64le.ld'
    cccdlflags='-fPIC'
    lddlflags='-lpthread -shared -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/perl-5.34.0/.package_note-perl-1.04-483.fc36.ppc64le.ld -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_TIMES
    MULTIPLICITY
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_IMPLICIT_CONTEXT
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_ITHREADS
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
    USE_REENTRANT_API
    USE_SITECUSTOMIZE
    USE_THREAD_SAFE_LOCALE
  Built under linux
  Compiled at Jan 20 2022 00:00:00
  @INC:
    lib
    .
    /usr/local/lib64/perl5/5.34
    /usr/local/share/perl5/5.34
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5

@sisyphus
Copy link
Contributor

longdblkind=1

Ok ... this perl that was built with gcc-12.0.1 is reporting that the long double is actually the "IEEE" 754 128-bit little endian long double.

I'd still like to get some idea of the internal structure of this long double.
When you built perl, you would have entered the top level perl source directory and run Configure, followed by make.
Can you cd to that directory and provide the output of:

./perl -I./lib -le 'print  unpack "h*", pack "D", 7.0;'

If it is, indeed, the "IEEE" 754 128-bit little endian long double, then it should output:

000000000000000000000000000c1004

@jplesnik
Copy link
Author

The output is like you expected
000000000000000000000000000c1004

@tuliom
Copy link

tuliom commented Jan 31, 2022

Ok ... this perl that was built with gcc-12.0.1 is reporting that the long double is actually the "IEEE" 754 128-bit little endian long double.

It is indeed IEEE 128-bit floating point. Fedora is transitioning the default long double for ppc64le. It's the first distro doing this.

@sisyphus
Copy link
Contributor

sisyphus commented Jan 31, 2022

It is indeed IEEE 128-bit floating point. Fedora is transitioning the default long double for ppc64le. It's the first distro doing this.

@tuliom, I wonder if XS-APITest.xs is aware of this. (I think it would be, so long as it has been compiled with the perl that's executing the test scripts.)

The thing that hits me is that if a program that's expecting a longdblkind of 7 receives 000000000000000000000000000c1004, then it's going to report that value as zero - because it thinks it's receiving a doubledouble of (0, 2.21875), which is actually an invalid doubledouble for that platform.
Sure, the less significant double is non-zero - but because the more significant double is zero, it will just ignore the less significant one and report "0.0". (At least that's what happens on my Debian box when the more significant double is 0, and the less significant one is 2.21875.)

And I'm wondering whether that's precisely what's happening in @jplesnik's case .... but it's a little hard to see from here ;-)

I think the next thing for @jplesnik to do is to now cd to the ext/XS-APItest folder and execute t/printf.t using the very same perl executable (with a longdblkind of 1), by running:

../../perl -I../../lib t/printf.t

@jplesnik, what happens with that ?

@jplesnik
Copy link
Author

LD_LIBRARY_PATH=/root/rpmbuild/BUILD/perl-5.34.0 /root/rpmbuild/BUILD/perl-5.34.0/preload /root/rpmbuild/BUILD/perl-5.34.0/libperl.so ../../perl -I../../lib t/printf.t 
1..13
ok 1 - use XS::APItest;
ok 2 - saving STDOUT
ok 3 - redirecting STDOUT
ok 4 - restore STDOUT
ok 5 - open foo.out
ok 6 - captured at least four output lines
ok 7 - print_double
ok 8 - print_int
ok 9 - print_long
ok 10 - print_float
not ok 11 - print_long_double
#   Failed test 'print_long_double'
#   at t/printf.t line 44.
#          got: '0.000'
#     expected: '7.000'
not ok 12 - print_long_doubleL
#   Failed test 'print_long_doubleL'
#   at t/printf.t line 45.
#          got: '0.000'
#     expected: '7.000'
ok 13 - check types for IV_MAX and UV_MAX match IVdf/UVuf
# Looks like you failed 2 tests of 13.

If you want to look at complete build log from ppc64le, please check https://jplesnik.fedorapeople.org/perl-gcc12/

@tuliom
Copy link

tuliom commented Jan 31, 2022

The thing that hits me is that if a program that's expecting a longdblkind of 7 receives 000000000000000000000000000c1004, then it's going to report that value as zero - because it thinks it's receiving a doubledouble of (0, 2.21875), which is actually an invalid doubledouble for that platform.

@sisyphus That's correct. However, as Fedora is in the middle of the long double migration, I think the questions that we have to answer in order to continue moving with the migration are:

  1. Which program is expecting a longdblkind of 7?
  2. What needs to be done for that program to expect a longdblkind of 1?

@sisyphus
Copy link
Contributor

sisyphus commented Feb 1, 2022

I think the questions that we have to answer in order to continue moving with the migration are:

Which program is expecting a longdblkind of 7?
What needs to be done for that program to expect a longdblkind of 1?

Sorry - I've probably allowed the the difference in the perl configurations that have been presented here to throw me more than it should have.

There's nothing in the build log, to which @jplesnik has just provided a link, that helps me to understand what's going wrong. (There might of course be clues in there that I haven't picked up on.)

As I said, I'd want to use Inline::C to probe what's happening.

I guess you could also hack at XS-APItest.xs so that it provides additional diagnostics. Or even just hack ext/XS-APItest/t/printf.t to check some other long double values, and see if those results confirm the hypothesis that the IEEE 128-bit little endian is being treated as a doubledouble. ( To my mind, it is only an hypothesis at this stage. Select valid doubledouble values that also have valid internal structure for the IEEE 128-bit le type ... and see which one is reported by print_long_doubleL() ... assuming it will report either one or the other ;-)

If you try to build this perl with the addition of the -Duselongdouble switch, you'll possibly get a better idea of what's going awry. (There's not a lot of probing of the 'long double' being done when building a perl whose nvtype is 'double'.)

@Leont's question "Did you compile it with the same flags and such?" is, I think, somewhat ominous. (Is there a flag that allows this gcc to switch between the 2 long double types ? Or is it hard coded to "IEEE 128-bit little endian" ?)

@jplesnik
Copy link
Author

jplesnik commented Feb 1, 2022

As I said, I'd want to use Inline::C to probe what's happening.

Sorry that I did not provide it earlier, the output from Inline::C script is
ppc64le - longdblkind=1, nvtype='double'

1.414
95ea6613fbb208c9bcf367e6096aff3f

s390x - longdblkind=2, nvtype='double', ext/XS-APItest/t/printf.t pass on s390x

1.414
3fff6a09e667f3bcc908b2fb1366ea95

@sisyphus
Copy link
Contributor

sisyphus commented Feb 1, 2022

@jplesnik , that all looks sane.
The only insane thing is this refusal of t/printf.t to pass all of its tests.
It's as though ext/XS-APItest has been compiled for a perl with a different long double configuration.
If that's not the case, then it looks like there's a mysterious bug in XS-APItest.

All I can suggest is that you keep poking at it until you hit some behaviour that's helpful. (Great advice, I know ;-)

I'm a bit loath to suggest anything specific, as it will probably just turn out to be a waste of your time.
However, whilst the test suite is telling us that print_long_double() and print_long_doubleL() aren't doing the right thing, we haven't actually directly seen what those 2 functions are outputting.
We can pretty cheaply see what they are outputting, so it's probably worth the effort.
Just cd to ext/XS-APItest and run

$ ../../perl -I../../lib  -le 'use XS::APItest; print_long_double(); print_long_doubleL();'

and verify that it really is outputting zeros. (Of course, I feel quite sure that it is.)

@sisyphus
Copy link
Contributor

sisyphus commented Feb 1, 2022

@jplesnik, it occurs to me that you should try this Inline::C script which is just a reproduction of the 2 failing routines from APItest.xs:

use strict;
use warnings;

use Inline C => Config =>
  USING => 'ParseRegExp',
  LIBS => '-lm',
  BUILD_NOISY => 1,
  ;

use Inline C => <<'EOC';

void print_long_double() {
#ifdef HAS_LONG_DOUBLE
#   if defined(PERL_PRIfldbl) && (LONG_DOUBLESIZE > DOUBLESIZE)
        long double val = 7.0;
        printf("%5.3" PERL_PRIfldbl "\n",val);
#   else
        double val = 7.0;
        printf("%5.3f\n",val);
#   endif
#endif
}

void print_long_doubleL() {
#ifdef HAS_LONG_DOUBLE
        /* used to test we allow the length modifier required by the standard */
        long double val = 7.0;
        printf("%5.3Lf\n",val);
#else
        double val = 7.0;
        printf("%5.3f\n",val);
#endif
}

EOC

print_long_double();
print_long_doubleL();

Based on the test failures, one would expect the output to be:

0.000
0.000 

However, based on your result with the earlier Inline::C script I provided, one would expect the output to be:

7.000
7.000

What do you get ?

@jplesnik
Copy link
Author

jplesnik commented Feb 2, 2022

@sisyphus The output of your script is

7.000
7.000

@sisyphus
Copy link
Contributor

sisyphus commented Feb 3, 2022

I don't know why the same code is compiling differently inside ext/XS-APItest than it does inside the Inline::C script.
Normally that sort of anomaly would indicate that different perl configurations or different C toolchains are being used in those two cases - and I'm inclined to believe that must be the case here, but only because I can't think of a reasonable alternative.

At this point (earlier, in fact) I would want to be sure that the perl source that was used was "fresh" - ie had not been used, cleaned, and then re-used ... and had also not been altered in any way.
If that was not the case, I'd extract fresh perl source directly from the perl source tarball, and repeat the build process.

There's much mention of miniperl during the building of ext/XS-APItest so I would also check that miniperl agrees that longdblkind is 1.
I cannot conceive that miniperl could consider that longdblkind is not 1, but it's something that can be checked easily:

./miniperl -le 'print unpack "h*", pack "F", 7.0;"

which should output the familiar 000000000000000000000000000c1004 .

Other than that, I would try hacking APItest.xs to allow us to glean more information about the long double 7.0 that is being seen as 0.000.
Does it need to be assigned as 7.0L ?
What would be reported for a hard coded long double of 7.1 ?
Does it make a difference if the value of 7.0 is passed in from perl (as opposed to hard coded to 7) ?

It's this lack of access to the long double assigned inside APItest,xs that led me to suggest that you try a -Duselongdouble build, as the long double will then be subjected to much more scrutiny during the building and testing ... but that could well turn out to be as fruitless as anything else that I've suggested.

@hvds
Copy link
Contributor

hvds commented Feb 3, 2022

@sisyphus I don't know offhand what headers Inline::C inserts, are you sure the #ifdef will do what you want? I'd be inclined to replace that successively with #if 1 and #if 0 so we know which branch we're taking.

@sisyphus
Copy link
Contributor

sisyphus commented Feb 3, 2022

@hvds I suppose I could make it more explicit - though we do know that, with the Inline::C script, the print_long_doubleL() output of 7.000 is from printf("%5.3Lf\n",val);.
We know this because the fact that print_long_double() produces any output at all, indicates that HAS_LONG_DOUBLE is defined.

Similarly, we reason that the reported 0.000 output of print_long_doubleL() in t/printf.t must come from the same printf("%5.3Lf\n",val); in APItest.xs.

Admittedly, neither this Inline::C script nor APItest.xs provides the means to establish whether PERL_PRIfldbl is defined, but I think that the anomaly with the "%5.3Lf" outputs is plenty to ponder over.
I think this would spell it out more clearly:

use strict;
use warnings;

use Inline C => Config =>
  USING => 'ParseRegExp',
  LIBS => '-lm',
  BUILD_NOISY => 1,
  ;

use Inline C => <<'EOC';

void print_long_double() {

#ifdef HAS_LONG_DOUBLE
#   if defined(PERL_PRIfldbl) && (LONG_DOUBLESIZE > DOUBLESIZE)
        long double val = 7.0;
        printf("PRIfldbl: %5.3" PERL_PRIfldbl "\n",val);
#   else
        double val = 7.0;
        printf("double: %5.3f\n",val);
#   endif
#endif

}

void print_long_doubleL() {

#ifdef HAS_LONG_DOUBLE
        /* used to test we allow the length modifier required by the standard */
        long double val = 7.0;
        printf("Lf: %5.3Lf\n",val);
#else
        double val = 7.0;
        printf("double: %5.3f\n",val);
#endif

}

EOC

print_long_double();
print_long_doubleL();

Inline::C is just an automated building of a perl extension.
It autogenerates an XS file that inserts the standard EXTERN.h, perl.h and XSUB.h, followed by any headers that the script requests (ie none, in this particular case).
Compilation is done as per the usual procedure for perl extensions, using xsubpp and the "make", "cc", compilation options, etc. as specified in %Config.

@jplesnik
Copy link
Author

jplesnik commented Feb 3, 2022

I built Perl without Fedora patches and the test failed again.

./miniperl -le 'print unpack "h*", pack "F", 7.0;'
000000000000c104

Inline-C output:

PRIfldbl: 7.000
Lf: 7.000

@sisyphus
Copy link
Contributor

sisyphus commented Feb 3, 2022

./miniperl -le 'print unpack "h*", pack "F", 7.0;'
000000000000c104

Duh ... sorry, that just unpacks the double 7.0.
I meant

./miniperl -le 'print unpack "h*", pack "D", 7.0;'

which should unpack the long double 7.0.

Inline-C output:

PRIfldbl: 7.000
Lf: 7.000

Yes, that's as I expected.
We (or I, at least) need some way to reproduce the bizarre t/printf.t failures you're getting during your build.

UPDATE - What follows here should probably be ignored. I think it's just me getting stuck in the wrong rabbit hole.

Can I take you back to your original post.
You posted results (which included those 2 failing tests) that you got in response to running the command:

# perl -Ilib ext/XS-APItest/t/printf.t

and you also posted the output of running

# ./perl -V

The latter showed a longdblkind of 7.
Were those 2 commands run from the same directory ? (I assume they were.)
Could you also post the outputs of running the same commands, from the same directory, but with the perls reversed.
That is, I'm seeking the outputs of:

# ./perl -Ilib ext/XS-APItest/t/printf.t

and

# perl -V

We know that ./perl has longdblkind of 7. If the "other" perl has longdblkind of 1, then what we're seeing probably makes sense - because you'd be running the XS-APItest tests that have been compiled for a longdblkind of 7, against a perl that has a longdblkind of 1.
If "perl" and "./perl" have different longdblkind values, then they can't be interchanged.
Interchanging them won't break very much (because both of those perls have an nvtype of double) - but it would break those API tests.

Do you understand my point ? If you do understand that point, and you're quite certain that it does not apply to your issue, then please tell me so.
(Otherwise it's going to keep bugging me ;-)

@tuliom
Copy link

tuliom commented Feb 7, 2022

I can't reproduce this issue after updating to gcc-12.0.1-0.6.fc36.
@jplesnik , are the tests passing for you too?

@jplesnik
Copy link
Author

jplesnik commented Feb 7, 2022

@tuliom You are correct, the issue is solved with updated gcc.

# LD_LIBRARY_PATH=/root/rpmbuild/BUILD/perl-5.34.0 /root/rpmbuild/BUILD/perl-5.34.0/preload /root/rpmbuild/BUILD/perl-5.34.0/libperl.so ./perl -Ilib -V
Summary of my perl5 (revision 5 version 34 subversion 0) configuration:
   
  Platform:
    osname=linux
    osvers=5.17.0-0.rc2.20220204gitdcb85f85fa6f.86.fc36.ppc64le
    archname=ppc64le-linux-thread-multi
    uname='linux ibm-p9z-23-lp9.virt.pnr.lab.eng.rdu2.redhat.com 5.17.0-0.rc2.20220204gitdcb85f85fa6f.86.fc36.ppc64le #1 smp fri feb 4 16:42:46 utc 2022 ppc64le ppc64le ppc64le gnulinux '
    config_args='-des -Doptimize=none -Dccflags=-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Dldflags=-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1  -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1  -Dlddlflags=-shared -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1  -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.34.0 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5/5.34 -Dsitearch=/usr/local/lib64/perl5/5.34 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=ppc64le-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize -Duse64bitint'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='gcc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='  -g'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -fwrapv -fno-strict-aliasing -I/usr/local/include'
    ccversion=''
    gccversion='12.0.1 20220205 (Red Hat 12.0.1-0)'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=1
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='gcc'
    ldflags ='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1  -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib
    libs=-lpthread -lresolv -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lresolv -ldl -lm -lcrypt -lutil -lc
    libc=/lib/../lib64/libc.so.6
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.34.9000'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 '
    cccdlflags='-fPIC'
    lddlflags='-lpthread -shared -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1  -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_TIMES
    MULTIPLICITY
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_IMPLICIT_CONTEXT
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_ITHREADS
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
    USE_REENTRANT_API
    USE_SITECUSTOMIZE
    USE_THREAD_SAFE_LOCALE
  Built under linux
  Compiled at Feb  7 2022 00:00:00
  @INC:
    lib
    /usr/local/lib64/perl5/5.34
    /usr/local/share/perl5/5.34
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants