https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117047
--- Comment #37 from David Malcolm <dmalcolm at gcc dot gnu.org> --- Created attachment 60608 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60608&action=edit Excerpt from jit-playback.s This is an excerpt from the .s file for _ZN3gcc3jit8playback7context11new_bitcastEPNS1_8locationEPNS1_6rvalueEPNS1_4typeE = gcc::jit::playback::context::new_bitcast(gcc::jit::playback::location*, gcc::jit::playback::rvalue*, gcc::jit::playback::type*) It seems to have an inlined copy of gcc::jit::playback::rvalue::get_type It calls _Z26ggc_internal_cleared_allocmPFvPvEmm@PLT The behavior I'm seeing is that the vtable ptr never seems to get written to the allocated object: _ZTVN3gcc3jit8playback6rvalueE aka "vtable for gcc::jit::playback::rvalue" leaving the vtable ptr null, and thus when eventually the finalizer is called, wrapper::finalizer's vfunc call to wrapper::finalize becomes a jump through a null fnptr. On cfarm420 I see: (gdb) p /x $rax $2 = 0x7ffff7345d50 (which is <vtable for gcc::jit::playback::rvalue>+16 0x00007ffff49f58bb <+11>: mov %rdx,%r13 0x00007ffff49f58be <+14>: xor %edx,%edx 0x00007ffff49f58c0 <+16>: push %r12 0x00007ffff49f58c2 <+18>: mov %rdi,%r12 0x00007ffff49f58c5 <+21>: mov $0x10,%edi 0x00007ffff49f58ca <+26>: push %rbp 0x00007ffff49f58cb <+27>: mov %rsi,%rbp 0x00007ffff49f58ce <+30>: lea -0x9395(%rip),%rsi # 0x7ffff49ec540 <gcc::jit::wrapper_finalizer(void*)> 0x00007ffff49f58d5 <+37>: push %rbx 0x00007ffff49f58d6 <+38>: mov %rcx,%rbx 0x00007ffff49f58d9 <+41>: mov $0x1,%ecx 0x00007ffff49f58de <+46>: sub $0x18,%rsp 0x00007ffff49f58e2 <+50>: lea 0x2950457(%rip),%rax # 0x7ffff7345d40 <_ZTVN3gcc3jit8playback6rvalueE> => 0x00007ffff49f58e9 <+57>: add $0x10,%rax 0x00007ffff49f58ed <+61>: movq %rax,%xmm0 0x00007ffff49f58f2 <+66>: punpcklqdq %xmm1,%xmm0 0x00007ffff49f58f6 <+70>: movaps %xmm0,(%rsp) 0x00007ffff49f58fa <+74>: call 0x7ffff4c48280 <_Z26ggc_internal_cleared_allocmPFvPvEmm> 0x00007ffff49f58ff <+79>: mov 0x10(%r13),%r13 0x00007ffff49f5903 <+83>: movzwl 0x0(%r13),%eax 0x00007ffff49f5908 <+88>: shl $0x6,%rax 0x00007ffff49f590c <+92>: add 0x2a8daf5(%rip),%rax # 0x7ffff7483408 0x00007ffff49f5913 <+99>: cmpb $0x0,0x1(%rax) 0x00007ffff49f5917 <+103>: je 0x7ffff415e106 <_ZN3gcc3jit8playback7context11new_bitcastEPNS1_8locationEPNS1_6rvalueEPNS1_4typeE.cold> 0x00007ffff49f591d <+109>: mov 0x8(%r13),%rdi 0x00007ffff49f5921 <+113>: lea 0x2115ff8(%rip),%rax # 0x7ffff6b0b920 <tree_code_type> 0x00007ffff49f5928 <+120>: movzwl (%rdi),%edx 0x00007ffff49f592b <+123>: cmpl $0x2,(%rax,%rdx,4) 0x00007ffff49f592f <+127>: jne 0x7ffff415e146 <_ZN3gcc3jit8playback7context11new_bitcastEPNS1_8locationEPNS1_6rvalueEPNS1_4typeE-9009002> 0x00007ffff49f5935 <+133>: mov 0x8(%rbx),%rbx stepping instructions for <+50> through <+74>: (gdb) p /x $xmm0 $4 = {v8_bfloat16 = {0x5d50, 0xf734, 0x7fff, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_half = {0x5d50, 0xf734, 0x7fff, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_float = {0xf7345d50, 0x7fff, 0x0, 0x0}, v2_double = {0x7ffff7345d50, 0x0}, v16_int8 = {0x50, 0x5d, 0x34, 0xf7, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0x5d50, 0xf734, 0x7fff, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0xf7345d50, 0x7fff, 0x0, 0x0}, v2_int64 = {0x7ffff7345d50, 0x0}, uint128 = 0x7ffff7345d50} which seems to get packed with: (gdb) p /x $xmm0 $11 = {v8_bfloat16 = {0x5d50, 0xf734, 0x7fff, 0x0, 0xca30, 0xffff, 0x7fff, 0x0}, v8_half = {0x5d50, 0xf734, 0x7fff, 0x0, 0xca30, 0xffff, 0x7fff, 0x0}, v4_float = {0xf7345d50, 0x7fff, 0xffffca30, 0x7fff}, v2_double = { 0x7ffff7345d50, 0x7fffffffca30}, v16_int8 = {0x50, 0x5d, 0x34, 0xf7, 0xff, 0x7f, 0x0, 0x0, 0x30, 0xca, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0}, v8_int16 = {0x5d50, 0xf734, 0x7fff, 0x0, 0xca30, 0xffff, 0x7fff, 0x0}, v4_int32 = { 0xf7345d50, 0x7fff, 0xffffca30, 0x7fff}, v2_int64 = {0x7ffff7345d50, 0x7fffffffca30}, uint128 = 0x7fffffffca3000007ffff7345d50} and the "memset" call within the ggc_internal_cleared_alloc overwrites $xmm0 here: Dump of assembler code for function __memset_avx2_unaligned_erms: 0x00007ffff3d7acc0 <+0>: endbr64 0x00007ffff3d7acc4 <+4>: vmovd %esi,%xmm0 => 0x00007ffff3d7acc8 <+8>: mov %rdi,%rax 0x00007ffff3d7accb <+11>: cmp $0x20,%rdx 0x00007ffff3d7accf <+15>: jb 0x7ffff3d7ada0 <__memset_avx2_unaligned_erms+224> and after the call to memset: (gdb) p /x $xmm0 $14 = {v8_bfloat16 = {0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf}, v8_half = {0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf}, v4_float = {0xafafafaf, 0xafafafaf, 0xafafafaf, 0xafafafaf}, v2_double = {0xafafafafafafafaf, 0xafafafafafafafaf}, v16_int8 = {0xaf <repeats 16 times>}, v8_int16 = {0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf, 0xafaf}, v4_int32 = {0xafafafaf, 0xafafafaf, 0xafafafaf, 0xafafafaf}, v2_int64 = {0xafafafafafafafaf, 0xafafafafafafafaf}, uint128 = 0xafafafafafafafafafafafafafafafaf} Value returned is $18 = (void *) 0x7fffee659350 ...but the <vtable for gcc::jit::playback::rvalue>+16 never seems to get written back to the allocated buffer.