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)) ...