http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57878
Bug ID: 57878 Summary: Incorrect code: live register clobbered in split2 Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: eraman at google dot com Created attachment 30493 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30493&action=edit Preprocessed source of the test case $ ./g++_4_8 --version g++_4_8 (GCC) 4.8.1 Copyright (C) 2013 Free Software Foundation, Inc. (Compiling the attached preprocessed source) $ ./g++_4_8 -m32 -O2 -fno-omit-frame-pointer -fPIC -std=gnu++11 -c r.ii $ objdump -d --no-show-raw-insn r.o > r.s In the attached r.s, in function _ZNSt6vectorIN3FDB9ChunkDataESaIS1_EE19_M_emplace_back_auxIIRKS1_EEEvDpOT_, the sub instruction at address 0xfd writes to edx, which is subsequently stored at [rbp-0x24]. edx is immediately clobbered. At 0x119, rbp-0x24 is clobbered and hence the load at 0x168 loads an incorrect value into ecx. After reload, we see the following: (insn 117 241 196 7 (parallel [ (set (reg/f:SI 1 dx [orig:138 D.3282 ] [138]) (minus:SI (reg/f:SI 1 dx [orig:138 D.3282 ] [138]) (reg/v/f:SI 5 di [orig:103 __cur ] [103]))) (clobber (reg:CC 17 flags)) ]) 309 {*subsi_1} (nil)) (insn 196 117 268 7 (set (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -36 [0xffffffffffffffdc])) [21 %sfp+-36 S4 A32]) (reg/f:SI 1 dx [orig:138 D.3282 ] [138])) 89 {*movsi_internal} (expr_list:REG_DEAD (reg/f:SI 1 dx [orig:138 D.3282 ] [138]) (nil))) ... (insn 119 274 237 7 (set (reg:DI 0 ax [193]) (mem:DI (plus:SI (reg/v/f:SI 0 ax [orig:109 __first ] [109]) (const_int 4 [0x4])) [10 MEM[base: _1, index: _28, offset: 0]+0 S8 A64])) r.ii:197 88 {*movdi_internal} (expr_list:REG_DEAD (reg/v/f:SI 0 ax [orig:109 __first ] [109]) (nil))) ... (insn 234 120 200 7 (set (reg/f:SI 1 dx [orig:138 D.3282 ] [138]) (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -36 [0xffffffffffffffdc])) [21 %sfp+-36 S4 A32])) r.ii:197 89 {*movsi_internal} (expr_list:REG_DEAD (reg/f:SI 138 [ D.3282 ]) (nil))) ... (insn 232 122 265 7 (set (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -36 [0xffffffffffffffdc])) [21 %sfp+-36 S4 A32]) (reg/f:SI 1 dx [orig:138 D.3282 ] [138])) r.ii:197 89 {*movsi_internal} (nil)) The fill in 234 and the second spill in 232 are redundant. Insn 234 gets removed by ce3 later, but 234 remains till the end. Meanwhile, 119 writes to a DI mode register and gets split by split2 into eax and edx and hence the store in 232 ends up clobbering the right value. When compiled with a trunk built 2 weeks ago, the compiler ICEs with the following stacck trace: r.ii: In member function ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {const FDB::ChunkData&}; _Tp = FDB::ChunkData; _Alloc = std::allocator<FDB::ChunkData>]’: r.ii:192:3: internal compiler error: in assign_by_spills, at lra-assigns.c:1266 } ^ 0x9ba360 assign_by_spills /usr/local/google/home/eraman/gcc/trunk/gcc/lra-assigns.c:1266 0x9bb013 lra_assign() /usr/local/google/home/eraman/gcc/trunk/gcc/lra-assigns.c:1423 0x9b71b9 lra(_IO_FILE*) /usr/local/google/home/eraman/gcc/trunk/gcc/lra.c:2342 0x97d7b8 do_reload /usr/local/google/home/eraman/gcc/trunk/gcc/ira.c:4689 0x97d7b8 rest_of_handle_reload /usr/local/google/home/eraman/gcc/trunk/gcc/ira.c:4801