Bug 2342831 - gcc-15.0.1-0.4.fc42 breaks QEMU int128 code on s390x
Summary: gcc-15.0.1-0.4.fc42 breaks QEMU int128 code on s390x
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: s390x
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 2341787
TreeView+ depends on / blocked
 
Reported: 2025-01-29 17:41 UTC by Daniel Berrangé
Modified: 2025-02-01 13:34 UTC (History)
12 users (show)

Fixed In Version: gcc-15.0.1-0.5.fc42
Clone Of:
Environment:
Last Closed: 2025-02-01 13:34:05 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 118696 0 P1 UNCONFIRMED [15 Regression] qemu miscompilation on s390x 2025-01-29 20:10:29 UTC

Description Daniel Berrangé 2025-01-29 17:41:53 UTC
When we rebuild QEMU with gcc-15.0.1-0.4.fc42, all system binaries immediately fail on asserts in our int128 code

(gdb) bt
#0  0x000003ffacb2ebd0 in __pthread_kill_implementation () at /lib64/libc.so.6
#1  0x000003ffacad46c0 in raise () at /lib64/libc.so.6
#2  0x000003ffacab3ec2 in abort () at /lib64/libc.so.6
#3  0x000003ffacacb39e in __assert_fail_base () at /lib64/libc.so.6
#4  0x000003ffacacb694 in __assert_fail () at /lib64/libc.so.6
#5  0x000002aa2b8815b8 in int128_get64 (a=<optimized out>) at /qemu/include/qemu/int128.h:33
#6  0x000002aa2bc8a362 in int128_get64 (a=<optimized out>) at ../system/memory.c:691
#7  render_memory_region (view=view@entry=0x2aa2eba89f0, mr=mr@entry=0x2aa2ead5c30, base=<optimized out>, clip=..., readonly=<optimized out>, 
    readonly@entry=false, nonvolatile=<optimized out>, unmergeable=<optimized out>) at ../system/memory.c:652
#8  0x000002aa2bc8a440 in generate_memory_topology (mr=mr@entry=0x2aa2ead5c30) at ../system/memory.c:761
#9  0x000002aa2bc8aaac in flatviews_reset () at ../system/memory.c:1083
#10 memory_region_transaction_commit () at ../system/memory.c:1159
#11 memory_region_transaction_commit () at ../system/memory.c:1149
#12 0x000002aa2bb91ebc in vapic_realize (dev=<optimized out>, errp=<optimized out>) at ../hw/i386/vapic.c:730
#13 0x000002aa2bd0f250 in device_set_realized (obj=<optimized out>, value=<optimized out>, errp=0x3ffc5d78810) at ../hw/core/qdev.c:494
#14 0x000002aa2bd129f2 in property_set_bool
    (obj=0x2aa2eba7b40, v=<optimized out>, name=<optimized out>, opaque=0x2aa2e897ca0, errp=0x3ffc5d78810) at ../qom/object.c:2374
#15 0x000002aa2bd161e8 in object_property_set
    (obj=obj@entry=0x2aa2eba7b40, name=name@entry=0x2aa2bfe89d6 "realized", v=v@entry=0x2aa2eba8250, errp=errp@entry=0x2aa2cf72538 <error_fatal>) at ../qom/object.c:1449
#16 0x000002aa2bd1a5ac in object_property_set_qobject
    (obj=obj@entry=0x2aa2eba7b40, name=name@entry=0x2aa2bfe89d6 "realized", value=value@entry=0x2aa2eba79e0, errp=errp@entry=0x2aa2cf72538 <error_fatal>) at ../qom/qom-qobject.c:28
#17 0x000002aa2bd168b2 in object_property_set_bool
    (obj=obj@entry=0x2aa2eba7b40, name=name@entry=0x2aa2bfe89d6 "realized", value=value@entry=true, errp=0x2aa2cf72538 <error_fatal>)
    at ../qom/object.c:1519
#18 0x000002aa2bd0e8b6 in qdev_realize (dev=dev@entry=0x2aa2eba7b40, bus=<optimized out>, errp=<optimized out>) at ../hw/core/qdev.c:276
#19 0x000002aa2bd0e956 in qdev_realize_and_unref (dev=dev@entry=0x2aa2eba7b40, bus=<optimized out>, errp=<optimized out>)
    at ../hw/core/qdev.c:283
#20 0x000002aa2b91f684 in sysbus_realize_and_unref (dev=0x2aa2eba7b40, errp=<optimized out>) at ../hw/core/sysbus.c:337
#21 sysbus_create_varargs (name=name@entry=0x2aa2bfb9e4a "kvmvapic", addr=addr@entry=18446744073709551615) at ../hw/core/sysbus.c:226
#22 0x000002aa2bc35ff0 in sysbus_create_simple (name=0x2aa2bfb9e4a "kvmvapic", addr=18446744073709551615, irq=0x0)
    at /qemu/include/hw/sysbus.h:100
#23 apic_common_realize (dev=<optimized out>, errp=<optimized out>) at ../hw/intc/apic_common.c:290
#24 0x000002aa2bd0f250 in device_set_realized (obj=<optimized out>, value=<optimized out>, errp=0x3ffc5d79070) at ../hw/core/qdev.c:494
#25 0x000002aa2bd129f2 in property_set_bool
    (obj=0x2aa2eba6ee0, v=<optimized out>, name=<optimized out>, opaque=0x2aa2e897ca0, errp=0x3ffc5d79070) at ../qom/object.c:2374
--Type <RET> for more, q to quit, c to continue without paging--quit
Quit


This does not happen with gcc-15.0.1-0.3.fc42.

I noticed GCC upstream has had a whole lot of recent commits for s390x wrt int128 support, so I'm presuming there's a gcc re gression in there.

I tried to create a standalone test case, but so far have not succeeded.

It is quickly reproducible with a minimal QEMU build though.

This is blocking all QEMU builds in rawhide, since we can't do an update where s390x is 100% broken.



Reproducible: Always

Steps to Reproduce:
$ sudo dnf builddep qemu
$ git clone https://gitlab.com/qemu-project/qemu
$ cd qemu
$ ./configure --target-list=x86_64-softmmu
$ make -j 20
$ ./build/qemu-system-x86_64

Actual Results:  
qemu-system-x86_64: /qemu/include/qemu/int128.h:33: int128_get64: Assertion `r == a' failed.
Aborted (core dumped)


Expected Results:  
VNC server running on ::1:5900

Comment 1 Jakub Jelinek 2025-01-29 18:57:05 UTC
Reproduced (submodules were a nightmare for reproduction in mock chroot).
Anyway, I'd like to recompile ../system/memory.c by hand and just relink, but am not sure how.
I've preprocessed it:
cc -m64 -Ilibqemu-x86_64-softmmu.a.p -I. -I.. -Itarget/i386 -I../target/i386 -Isubprojects/libvduse -I../subprojects/libvduse -Iqapi -Itrace -Iui -Iui/shader -I/usr/include/capstone -I/usr/include/p11-kit-1 -I/usr/include/pixman-1 -I/usr/include/libpng16 -I/usr/include/SDL2 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gio-unix-2.0 -I/usr/include/slirp -I/usr/local/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cloudproviders -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/lib64/pkgconfig/../../include/dbus-1.0 -I/usr/lib64/pkgconfig/../../lib64/dbus-1.0/include -I/usr/include/fribidi -I/usr/include/libxml2 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/vte-2.91 -I/usr/include/virgl -I/usr/include/libdrm -I/usr/include/cacard -I/usr/include/nss3 -I/usr/include/nspr4 -I/usr/include/PCSC -I/usr/include/libusb-1.0 -I/usr/include/pipewire-0.3 -I/usr/include/spa-0.2 -I/usr/include/fuse3 -I/usr/include/uuid -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g -fstack-protector-strong -Wempty-body -Wendif-labels -Wexpansion-to-defined -Wformat-security -Wformat-y2k -Wignored-qualifiers -Wimplicit-fallthrough=2 -Winit-self -Wmissing-format-attribute -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls -Wshadow=local -Wstrict-prototypes -Wtype-limits -Wundef -Wvla -Wwrite-strings -Wno-missing-include-dirs -Wno-psabi -Wno-shift-negative-value -isystem /tmp/qemu/linux-headers -isystem linux-headers -iquote . -iquote /tmp/qemu -iquote /tmp/qemu/include -iquote /tmp/qemu/host/include/generic -iquote /tmp/qemu/tcg/s390x -pthread -D_GNU_SOURCE -D_LARGEFILE_SOURCE -fno-strict-aliasing -fno-common -fwrapv -ftrivial-auto-var-init=zero -fzero-call-used-regs=used-gpr -fPIE -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64 -DUSE_POSIX_ACLS=1 -DHWY_SHARED_DEFINE -DAVIF_DLL -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -DNCURSES_WIDECHAR=1 -D_GNU_SOURCE=1 -D_REENTRANT -DSTRUCT_IOVEC_DEFINED -DWITH_GZFILEOP -isystem../linux-headers -isystemlinux-headers -DCOMPILING_PER_TARGET '-DCONFIG_TARGET="x86_64-softmmu-config-target.h"' '-DCONFIG_DEVICES="x86_64-softmmu-config-devices.h"' -o /tmp/memory.i -E ../system/memory.c
and then am e.g. trying to compile it with -O0:
gcc -m64 -std=gnu11 -O0 -g -fstack-protector-strong -fno-strict-aliasing -fno-common -fwrapv -ftrivial-auto-var-init=zero -fzero-call-used-regs=used-gpr -fPIE -c /tmp/memory.i -o libqemu-x86_64-softmmu.a.p/system_memory.c.o
At this point I'd like to relink, but
make V=1
will recompile system/memory.c again for some reason:
[1/17] /tmp/qemu/build/pyvenv/bin/meson --internal exe --capture qemu-version.h -- /tmp/qemu/scripts/qemu-version.sh /tmp/qemu '' 9.2.50
[2/3] cc -m64 -Ilibqemu-x86_64-softmmu.a.p -I. -I.. -Itarget/i386 -I../target/i386 -Isubprojects/libvduse -I../subprojects/libvduse -Iqapi -Itrace -Iui -Iui/shader -I/usr/include/capstone -I/usr/include/p11-kit-1 -I/usr/include/pixman-1 -I/usr/include/libpng16 -I/usr/include/SDL2 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gio-unix-2.0 -I/usr/include/slirp -I/usr/local/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cloudproviders -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/lib64/pkgconfig/../../include/dbus-1.0 -I/usr/lib64/pkgconfig/../../lib64/dbus-1.0/include -I/usr/include/fribidi -I/usr/include/libxml2 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/vte-2.91 -I/usr/include/virgl -I/usr/include/libdrm -I/usr/include/cacard -I/usr/include/nss3 -I/usr/include/nspr4 -I/usr/include/PCSC -I/usr/include/libusb-1.0 -I/usr/include/pipewire-0.3 -I/usr/include/spa-0.2 -I/usr/include/fuse3 -I/usr/include/uuid -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g -fstack-protector-strong -Wempty-body -Wendif-labels -Wexpansion-to-defined -Wformat-security -Wformat-y2k -Wignored-qualifiers -Wimplicit-fallthrough=2 -Winit-self -Wmissing-format-attribute -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls -Wshadow=local -Wstrict-prototypes -Wtype-limits -Wundef -Wvla -Wwrite-strings -Wno-missing-include-dirs -Wno-psabi -Wno-shift-negative-value -isystem /tmp/qemu/linux-headers -isystem linux-headers -iquote . -iquote /tmp/qemu -iquote /tmp/qemu/include -iquote /tmp/qemu/host/include/generic -iquote /tmp/qemu/tcg/s390x -pthread -D_GNU_SOURCE -D_LARGEFILE_SOURCE -fno-strict-aliasing -fno-common -fwrapv -ftrivial-auto-var-init=zero -fzero-call-used-regs=used-gpr -fPIE -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64 -DUSE_POSIX_ACLS=1 -DHWY_SHARED_DEFINE -DAVIF_DLL -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -DNCURSES_WIDECHAR=1 -D_GNU_SOURCE=1 -D_REENTRANT -DSTRUCT_IOVEC_DEFINED -DWITH_GZFILEOP -isystem../linux-headers -isystemlinux-headers -DCOMPILING_PER_TARGET '-DCONFIG_TARGET="x86_64-softmmu-config-target.h"' '-DCONFIG_DEVICES="x86_64-softmmu-config-devices.h"' -MD -MQ libqemu-x86_64-softmmu.a.p/system_memory.c.o -MF libqemu-x86_64-softmmu.a.p/system_memory.c.o.d -o libqemu-x86_64-softmmu.a.p/system_memory.c.o -c ../system/memory.c
[3/3] cc -m64 @qemu-system-x86_64.rsp
And just cut and paste of cc -m64 @qemu-system-x86_64.rsp doesn't work because the file doesn't exist, so something creates it during the build, but doesn't show the command how.

Comment 2 Daniel Berrangé 2025-01-29 19:15:49 UTC
The ternary operator appears to be inverted. The following demo program works on previous gcc builds, and now fails:


#include <stdint.h>
#include <assert.h>

typedef __int128_t Int128;

static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
{
    return (__uint128_t)hi << 64 | lo;
}

int main(int argc, char **argv){
    Int128 a = int128_make128(0, 1);
    Int128 b = int128_make128(0x10000, 0);
    Int128 c = a < b ? a : b;
    assert(c == b);
}

Comment 3 Paolo Bonzini 2025-01-29 19:16:21 UTC
Use "ninja -d keeprsp qemu-system-x86_64" and it won't delete the .rsp file.

Comment 4 Jakub Jelinek 2025-01-29 19:34:13 UTC
The reduced testcase would be great, but what options can you reproduce it with?
Just -O2 or -O2 -fpie works fine for me, so does -O2 -march=z13 -mtune=z14.

Comment 5 Jakub Jelinek 2025-01-29 19:34:56 UTC
Ah, -O0.

Comment 6 Jakub Jelinek 2025-01-29 19:59:54 UTC
Thanks, so
static inline __int128
foo (unsigned long long x, unsigned long long y)
{
  return (unsigned __int128) y << 64 | x;
}

__attribute__((noipa)) __int128
bar (__int128 x, __int128 y)
{
  return x < y ? x : y;
}

int
main ()
{
  __int128 a = foo (0x10000, 0);
  if (bar (foo (0, 1), a) != a)
    __builtin_abort ();
}
is miscompiled both with -O0 and -O2 if -march=z13 is used, but not with -march=z10.
It is bar that is miscompiled (aka MIN_EXPR).

Comment 7 Daniel Berrangé 2025-01-29 20:02:42 UTC
With my demo program from comment #2 I just compiled with default GCC args. ie.

# rpm -q gcc
gcc-15.0.1-0.3.fc42.s390x
# gcc -o demo ../demo.c
# ./demo

vs

# rpm -q gcc
gcc-15.0.1-0.4.fc42.s390x
# gcc -o demo ../demo.c
# ./demo
demo: ../demo.c:16: main: Assertion `c == b' failed.
Aborted (core dumped)

Comment 8 Daniel Berrangé 2025-01-29 20:08:45 UTC
> It is bar that is miscompiled (aka MIN_EXPR).

FYI, trying the reverse comparison "x > y ? x : y" seems to be mis-compiled too.

Comment 9 Jakub Jelinek 2025-01-31 17:32:16 UTC
Should be fixed in gcc-15.0.1-0.5.fc42, except that koji ppc64le builders are misbehaving and so it finished on all arches but ppc64le:
https://koji.fedoraproject.org/koji/taskinfo?taskID=128659761


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