Segfault on s390x due to missing sign/zero extend
Summary
Building a recent stage1 compiler is successful. However, running the stage1 binary results in a segfault:
gdb --args _build/stage1/bin/ghc --version
Reading symbols from _build/stage1/bin/ghc...
(No debugging symbols found in _build/stage1/bin/ghc)
(gdb) r
Starting program: /devel/ghc/ghc-master/_build/stage1/bin/ghc --version
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x3fff367d870 (LWP 1001533)]
[New Thread 0x3fff2e7c870 (LWP 1001534)]
Thread 3 "ghc:w" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x3fff2e7c870 (LWP 1001534)]
0x000003fff42b5a3c in setIOManagerControlFd (cap_no=<optimized out>, fd=6) at rts/Capability.c:1371
1371 RELAXED_STORE(&capabilities[cap_no]->io_manager_control_wr_fd, fd);
The 32bit parameter cap_no
resides in a 64bit register where the high part is not zero. On s390x the C calling convention is that any value which is passed in a register must be sign/zero extended which is not the case here. For example, currently code like
%lnb9U = bitcast i8* @setIOManagerControlFd to void (i32, i32)*
call ccc void (i32, i32) %lnb9U( i32 %lnb9S, i32 %lnb9T ) nounwind
is emitted where the first parameter should be zero extended and the second parameter sign extended.
I assume that this was not a problem in the past since different sized integers were finally all treated as word sized integers and therefore as 64bit integers on s390x. This has changed with commit be5d74ca.
Steps to reproduce
Since commit be5d74ca run hadrian/build -c -j --flavour=quick-llvm && _build/stage1/bin/ghc --version
which results in a segfault.
Environment
- GHC version used: 8.10
Optional:
- Operating System: Fedora 33
- System Architecture: s390x