Bug 2057524 - gcc (GCC) 12.0.1 - producing wrong code for error call with long double value on ppc64le
Summary: gcc (GCC) 12.0.1 - producing wrong code for error call with long double value...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: 36
Hardware: ppc64le
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-02-23 15:11 UTC by Jiri Hladky
Modified: 2022-02-23 16:50 UTC (History)
11 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-02-23 16:50:49 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
preprocessed source for op-parser.c (365.43 KB, text/plain)
2022-02-23 16:13 UTC, Jiri Hladky
no flags Details

Description Jiri Hladky 2022-02-23 15:11:02 UTC
Description of problem:

When compiling datamash 1.7 on Fedora Rawhide of Fedora 36 for ppc64le, datamash internal test fails. 

F35 and older are not affected. RHEL-9 is also not affected. See also https://bugzilla.redhat.com/show_bug.cgi?id=2056736 for more details. 

Test:
./datamash trimmean:12  1
Wrong output:    "invalid trim mean value 8.09576e-320 (expected 0 <= X <= 0.5)"
Expected output: "invalid trim mean value 12 (expected 0 <= X <= 0.5)"

Source code line:
error(EXIT_FAILURE, 0, "invalid trim mean value %Lg (expected 0 <= X <= 0.5)", op->params.trimmed_mean);

I have tried to examine the values with gdb and everything looks OK:

(gdb) print op->params.trimmed_mean
$4 = 12
(gdb) ptype op->params.trimmed_mean
type = _Float128
(gdb) ptype op->params
type = union {
    long double bin_bucket_size;
    size_t strbin_bucket_size;
    size_t percentile;
    long double trimmed_mean;
    enum extract_number_type get_num_type;
}

However, it seems like this C source code:
error(EXIT_FAILURE, 0, "invalid trim mean value %Lg (expected 0 <= X <= 0.5)", op->params.trimmed_mean);

is translated into a wrong call: 

0x00007ffff7cd0808 in __error (status=1, errnum=0, message=0x100509f0 "invalid trim mean value %Lg (expected 0 <= X <= 0.5)") at error.c:271

When trying to create a simple reproducer, the binary behaves as expected, and this call is used:
0x00007ffff7e25a28 in ___ieee128_error (status=1, errnum=0, message=0x10020038 "invalid trim mean value %Lg (expected 0 <= X <= 0.5)") at ../sysdeps/ieee754/ldbl-128ibm-compat/ieee128-error.c:30


This is why I think the issue is caused by the GCC bug. 

Version-Release number of selected component (if applicable):
gcc (GCC) 12.0.1 20220214 (Red Hat 12.0.1-0), shipped with Fedora 36
Only the ppc64le arch is affected. 

How reproducible:

Always. Clone this Beaker job to reserve ppc64le system running Fedora36:
https://beaker.engineering.redhat.com/jobs/6331509

Install this software:

dnf install tar
dnf install gcc gettext perl pkgconfig bash-completion make
dnf install perl-devel perl-File-Temp
dnf install perl-Data-Dumper perl-Digest-MD5 perl-Digest-SHA

Steps to Reproduce:
1. wget https://ftp.gnu.org/gnu/datamash/datamash-1.7.tar.gz
2. tar xf datamash-1.7.tar.gz
3. cd datamash-1.7
4. ./configure CFLAGS="-g"
5. make
6. ./datamash trimmean:12 1

Actual results:
$ ./datamash trimmean:12 1
./datamash: invalid trim mean value 8.09576e-320 (expected 0 <= X <= 0.5)


Expected results:
$ ./datamash trimmean:12 1
./datamash: invalid trim mean value 0 (expected 0 <= X <= 0.5)


Additional info:

Debugging with gdb:

gdb ./datamash
(gdb) break src/op-parser.c:205
(gdb) set args trimmean:12 1
(gdb) r

Step up to this line:
die (EXIT_FAILURE, 0, _("invalid trim mean value %Lg "

(gdb) print op->params.trimmed_mean
$1 = 12
(gdb)c
/root/A/datamash-1.7-orig/datamash: invalid trim mean value 1.32788e-315 (expected 0 <= X <= 0.5)

=> wrong value. Expected "12", got "1.32788e-315".

Comment 2 Florian Weimer 2022-02-23 15:21:25 UTC
If this is a bug in Fedora GCC, shouldn't it be filed against Fedora, not AROS? Thanks.

Comment 4 Jakub Jelinek 2022-02-23 15:30:44 UTC
Also, can you please attach preprocessed source for op-parser.c (e.g. add -save-temps to the gcc command line through which op-parser.c is compiled) and also mention the gcc options?

Comment 5 Jiri Hladky 2022-02-23 15:31:16 UTC
One more observation. On RHEL-9, with 
gcc --version
gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7)

everything works as expected. gdb shows that ptype of op->params.trimmed_mean is "long double" whereas on F36 with GCC 12.0.1 it's "_Float128":

RHEL-9:

$ ./datamash trimmean:12 1
(gdb) set args trimmean:12 1
(gdb) break src/op-parser.c:205
Breakpoint 1 at 0x10007b38: file src/op-parser.c, line 205.
(gdb) r
Starting program: /root/datamash-1.7/datamash trimmean:12 1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, set_op_params (op=0x10065750) at src/op-parser.c:205
205             op->params.trimmed_mean = _params[0].f;
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.34-16.el9.ppc64le
(gdb) s
206           if (op->params.trimmed_mean<0 || op->params.trimmed_mean>0.5)
(gdb) print op->params.trimmed_mean
$1 = 12
(gdb) ptype op->params.trimmed_mean
type = long double
(gdb) s
207             die (EXIT_FAILURE, 0, _("invalid trim mean value %Lg " \
(gdb) s
/root/datamash-1.7/datamash: invalid trim mean value 12 (expected 0 <= X <= 0.5)

Comment 6 Jiri Hladky 2022-02-23 15:34:26 UTC
C(In reply to Florian Weimer from comment #2)
> If this is a bug in Fedora GCC, shouldn't it be filed against Fedora, not
> AROS? Thanks.

Yeah, you are right. Thanks for the hint. I have fixed it now.

Comment 7 Jakub Jelinek 2022-02-23 15:39:17 UTC
My bet is that this is a dup of #2044656 - having a stale gnulib copy in the tree that messes up the glibc redirections.

Comment 8 Jiri Hladky 2022-02-23 16:13:16 UTC
Created attachment 1863028 [details]
preprocessed source for op-parser.c

Relevant lines:

grep -20 "invalid trim" datamash-op-parser.i

      if (op->params.trimmed_mean<0 || op->params.trimmed_mean>0.5)






 error(
# 213 "src/op-parser.c" 3 4
      1
# 213 "src/op-parser.c"
                  , 0, "invalid trim mean value %Lg (expected 0 <= X <= 0.5)", op->params.trimmed_mean);


gcc options:

gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DHAVE_CONFIG_H -I.  -Ilib -I./lib -Isrc -I./src  -Wall -Wextra -Wformat-security -Wswitch-enum -Wswitch-default -Wunused-parameter -Wfloat-equal -fdiagnostics-show-option -funit-at-a-time -W
missing-format-attribute -Wstrict-overflow -Wsuggest-attribute=const -Wsuggest-attribute=pure   -g -save-temps -MT src/datamash-op-parser.o -MD -MP -MF src/.deps/datamash-op-parser.Tpo -c -o src/datamash-op-parser.o `test -f 'src/op-pa
rser.c' || echo './'`src/op-parser.c

Comment 10 Jakub Jelinek 2022-02-23 16:43:19 UTC
Ah, so it is a different bug, but still a bug on the datamash/gnulib side.
For error declaration it uses #include "error.h" in src/system.h which picks up "lib/error.h":

# 75 "src/system.h" 2
# 1 "lib/error.h" 1
# 52 "lib/error.h"
extern void error (int __status, int __errnum, const char *__format, ...)
     __attribute__ ((__format__ (__printf__, 3, 4)));

extern void error_at_line (int __status, int __errnum, const char *__fname,
                           unsigned int __lineno, const char *__format, ...)
     __attribute__ ((__format__ (__printf__, 5, 6)));

but that is some gnulib prototype for the function, not the glibc one, which is in <error.h>
(i.e. /usr/include/error.h).
That header provides similar declaration, but also includes <bits/error-ldbl.h> header
in certain conditions which makes sure to redirect the error call to __ieee128_error for -mabi=ieeelongdouble
on ppc64le (which is now the default in F36 and later).
Now, it would be fine to use the ?gnulib? error.h if its implementation would be also used,
but that doesn't seem to be the case and you are instead using the glibc definition.

In any way, this has really nothing to do with gcc, it is a glibc vs. gnulib vs. the package issue.

Comment 11 Jiri Hladky 2022-02-23 16:50:49 UTC
Hi Jakub,

thanks a lot for looking into it! I will contact datamash upstream developer to get this resolved. 

I'm going to close this bug. 

Thanks a lot!
Jirka


Note You need to log in before you can comment on or make changes to this bug.