https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96559
--- Comment #1 from Ulrich Weigand <uweigand at gcc dot gnu.org> --- > [...] as __clzdi2 points to the very same place as _Z11CeilingLog2v. How do you get to that conclusion? Nothing in that assembler source sets __clzdi2 to point to the same place as _Z11CeilingLog2v. The ".globl" simply declares that there is a globally visible definition, from someplace outside this file. And in fact if I compile all the way to an object file and look at it using "objdump --disassemble --reloc", I see: 0000000000000000 <_Z11CeilingLog2v>: 0: eb cf f0 60 00 24 stmg %r12,%r15,96(%r15) 6: a7 fb ff 60 aghi %r15,-160 a: c0 c0 00 00 00 00 larl %r12,a <_Z11CeilingLog2v+0xa> c: R_390_PC32DBL .bss+0x2 10: e3 20 c0 00 00 04 lg %r2,0(%r12) 16: c0 e5 00 00 00 00 brasl %r14,16 <_Z11CeilingLog2v+0x16> 18: R_390_PC32DBL __clzdi2+0x2 1c: 42 20 c0 08 stc %r2,8(%r12) 20: e3 40 f1 10 00 04 lg %r4,272(%r15) 26: eb cf f1 00 00 04 lmg %r12,%r15,256(%r15) 2c: 07 f4 br %r4 And "nm" shows: U __clzdi2 0000000000000008 B compute___trans_tmp_3 0000000000000000 B CountLeadingZeroes64_aValue 0000000000000000 T _Z11CeilingLog2v So if the call to __clzdi2 ends up going to the wrong place, something must have gone wrong at the link stage.