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.

Reply via email to