https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66616

            Bug ID: 66616
           Summary: fipa-cp-clone ignores thunk
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Created attachment 35821
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35821&action=edit
test-case

I.

attached test-case g++.dg/ipa/pr60640-5.C (based on g++.dg/ipa/pr60640-3.C) 
fails for x86_64, both with and without -m32:
...
FAIL: g++.dg/ipa/pr60640-5.C  -std=gnu++11 execution test
PASS: g++.dg/ipa/pr60640-5.C  -std=gnu++14 (test for excess errors)
FAIL: g++.dg/ipa/pr60640-5.C  -std=gnu++14 execution test
PASS: g++.dg/ipa/pr60640-5.C  -std=gnu++98 (test for excess errors)
FAIL: g++.dg/ipa/pr60640-5.C  -std=gnu++98 execution test
...


II.

With -fno-ipa-cp-clone -g, we see that p is gb2 + 16 in main, but once we get
to B::foo, 'this' is gb2:
...
Breakpoint 1, main () at src/gcc/testsuite/g++.dg/ipa/pr60640-5.C:45
45      {
(gdb) n
49            p->foo (0);
(gdb) p p
$1 = (A *) 0x600d70 <gb2+16>
(gdb) s
B::foo (this=0x600d60 <gb2>, p=0) at
/home/vries/gcc_versions/devel/devel2/src/gcc/testsuite/g++.dg/ipa/pr60640-5.C:33
33          for (int i = 0; i < p; i++)
...

By using layout asm and stepi to go from main to 'B::foo', we see that we
actually pass over the 'non-virtual thunk to B::foo(int) ()' which subtracts 16
from the 'this' argument, before landing in 'B::foo':
...
0x400740 <_ZThn16_N1B3fooEi>    sub    $0x10,%rdi          
0x400744 <_ZThn16_N1B3fooEi+4>  jmp    0x400710 <B::foo(int)>
...


III.

With -fipa-cp-clone, B::foo is cloned and inlined into main. We have at
fixup_cfg4:
...
  <bb 4>:
  o_8 = MEM[(struct B *)&gb2 + 16B].D.2389.fi;
...

This is supposed to load the '2' from fi. We can see at expand in the static
initializers bit that fi is located at gb2 + 24:
...
(insn 5 2 6 2
  (set
    (reg/f:DI 87)
    (symbol_ref:DI ("gb2") [flags 0x2]  <var_decl 0x7fc7dfed0bd0 gb2>))
  (nil))
(insn 6 5 7 2
  (set
    (mem/c:SI
      (plus:DI (reg/f:DI 87)
               (const_int 24 [0x18]))
      [3 MEM[(struct A *)&gb2 + 16B].fi+0 S4 A64])
    (const_int 2 [0x2]))
  (nil))
...


But the o_8 assignment translates to gb2 + 40, in other words, gb2 + 16 + 24:
...
(insn 5 2 6 2
  (set
    (reg/f:DI 89)
    (symbol_ref:DI ("gb2") [flags 0x2]  <var_decl 0x7fc7dfed0bd0 gb2>))
  (nil))
(insn 6 5 7 2
  (set
    (reg/v:SI 87 [ o ])
    (mem/c:SI
      (plus:DI (reg/f:DI 89)
               (const_int 40 [0x28]))
      [3 MEM[(struct B *)&gb2 + 16B].D.2389.fi+0 S4 A64]))
  (nil))
...

Reply via email to