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

Reply via email to