https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113991
Bug ID: 113991 Summary: [14 Regression] LTO miscompilation of vsftpd on s390x Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- Created attachment 57459 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57459&action=edit vsftpd.tar.xz We are seeing a miscompilation of vsftpd on s390x with r14-8885 Unfortunately, I haven't been able to further reduce the TUs which need -flto, to me it looks like a register allocation bug. Attached is a tarball with all the needed *.i files and a script to compile them and link. If one has Fedora s390x libraries - libssl.so.3 libpam.so.0 libcap.so.2 libcrypto.so.3 libc.so.6 libaudit.so.1 libeconf.so.0 libm.so.6 libz.so.1 ld64.so.1 libcap-ng.so.0 are needed, then the reproducer is as root gdb --args ./vsftpd -oanon_root=. -oallow_anon_ssl=true -obackground=false run and in another terminal curl ftp://localhost/ It crashes with #0 hash_pid (buckets=256, p_key=0x0) at standalone.c:338 #1 0x000002aa00010622 in hash_get_bucket (p_hash=p_hash@entry=0x2aa00031e10, p_key=0x0) at hash.c:123 #2 hash_get_node_by_key (p_hash=p_hash@entry=0x2aa00031e10, p_key=p_key@entry=0x0) at hash.c:134 #3 0x000002aa000106be in hash_lookup_entry (p_hash=0x2aa00031e10, p_key=0x0) at hash.c:54 #4 hash_add_entry (p_hash=0x2aa00031e10, p_key=p_key@entry=0x0, p_value=p_value@entry=0x2aa00032684) at hash.c:67 #5 0x000002aa00009ce0 in vsf_standalone_main () at standalone.c:202 #6 main (argc=<optimized out>, argv=<optimized out>) at main.c:158 Now, main which has vsf_standalone_main and tons of other stuff inlined into it has 2 calls to hash_add_entry, one at standalone.c:202 and one at standalone.c:350 The one that crashes here is the one at line 202, in *.optimized dump it still looks like [standalone.c:202:9] hash_add_entry (_344, [standalone.c:202:48] &new_child, _384); and so the second argument (%r3) is address of a local new_child variable. That seems to be the case also before the register allocation, e.g. asmcons has: (insn 1527 1524 1528 153 (set (reg:DI 4 %r4) (reg/f:DI 185 [ _384 ])) "standalone.c":202:9 1477 {*movdi_64} (expr_list:REG_DEAD (reg/f:DI 185 [ _384 ]) (nil))) (insn 1528 1527 1529 153 (set (reg:DI 3 %r3) (reg/f:DI 777)) "standalone.c":202:9 1477 {*movdi_64} (expr_list:REG_EQUAL (plus:DI (reg/f:DI 34 %fp) (const_int -648 [0xfffffffffffffd78])) (nil))) (insn 1529 1528 1530 153 (set (reg:DI 2 %r2) (mem/f/c:DI (const:DI (plus:DI (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) (const_int 3096 [0xc18]))) [3 s_p_pid_ip_hash+0 S8 A64])) "standalone.c":202:9 1477 {*movdi_64} (nil)) (call_insn 1530 1529 3721 153 (parallel [ (call (mem:QI (symbol_ref:DI ("hash_add_entry") [flags 0x3] <function_decl 0x3ffb41ca900 hash_add_entry>) [0 hash_add_entry S1 A8]) (const_int 0 [0])) (clobber (reg:DI 14 %r14)) ]) "standalone.c":202:9 2198 {*brasl} (expr_list:REG_DEAD (reg:DI 4 %r4) (expr_list:REG_DEAD (reg:DI 3 %r3) (expr_list:REG_DEAD (reg:DI 2 %r2) (expr_list:REG_CALL_DECL (symbol_ref:DI ("hash_add_entry") [flags 0x3] <function_decl 0x3ffb41ca900 hash_add_entry>) (nil))))) (expr_list:DI (use (reg:DI 2 %r2)) (expr_list:DI (use (reg:DI 3 %r3)) (expr_list:DI (use (reg:DI 4 %r4)) (nil))))) and pseudo 777 has a single initialization in (insn 669 668 670 73 (parallel [ (set (reg/f:DI 777) (plus:DI (reg/f:DI 34 %fp) (const_int -648 [0xfffffffffffffd78]))) (clobber (reg:CC 33 %cc)) ]) "sysutil.c":700:16 1831 {*adddi3} (expr_list:REG_UNUSED (reg:CC 33 %cc) (nil))) But in the end after RA this becomes (insn 1527 1524 1528 157 (set (reg:DI 4 %r4) (reg/f:DI 6 %r6 [orig:185 _384 ] [185])) "standalone.c":202:9 1477 {*movdi_64} (nil)) (insn 1528 1527 1529 157 (set (reg:DI 3 %r3) (reg/f:DI 7 %r7 [777])) "standalone.c":202:9 1477 {*movdi_64} (expr_list:REG_EQUAL (plus:DI (reg/f:DI 34 %fp) (const_int -648 [0xfffffffffffffd78])) (nil))) (insn 1529 1528 1530 157 (set (reg:DI 2 %r2) (mem/f/c:DI (const:DI (plus:DI (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) (const_int 3096 [0xc18]))) [3 s_p_pid_ip_hash+0 S8 A64])) "standalone.c":202:9 1477 {*movdi_64} (nil)) (call_insn 1530 1529 3721 157 (parallel [ (call (mem:QI (symbol_ref:DI ("hash_add_entry") [flags 0x3] <function_decl 0x3ffb41ca900 hash_add_entry>) [0 hash_add_entry S1 A8]) (const_int 0 [0])) (clobber (reg:DI 14 %r14)) ]) "standalone.c":202:9 2198 {*brasl} (expr_list:REG_CALL_DECL (symbol_ref:DI ("hash_add_entry") [flags 0x3] <function_decl 0x3ffb41ca900 hash_add_entry>) (nil)) (expr_list:DI (use (reg:DI 2 %r2)) (expr_list:DI (use (reg:DI 3 %r3)) (expr_list:DI (use (reg:DI 4 %r4)) (nil))))) and the %r7 contains NULL in there, while it clearly should be never NULL because it is an address of an automatic variable.