http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57088



             Bug #: 57088

           Summary: Post-reload instruction splitting clobbers live

                    register

    Classification: Unclassified

           Product: gcc

           Version: 4.9.0

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: target

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: era...@google.com





Created attachment 29952

  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29952

Test case



$ ./trunk_gcc --version

trunk_gcc (GCC) 4.9.0 20130423 (experimental)

$ ./trunk_gcc  -fno-exceptions    -m32  -O2   -fpermissive  -fPIC   -S

reduced.ii



In the source, the LargeObjectCacheInterface::Update method has the following

statement:



IOBuffer *save_buf = new VIOBuffer(buffer->Length());



This gets translated to the following assembly fragment:



(...)

        call    _Znwj@PLT

        movl    -44(%ebp), %ecx

        movl    -48(%ebp), %edx

        movl    $0, 12(%esp)

        movl    $16, 8(%esp)

        movl    %ecx, (%esp)

        movl    %edx, 4(%esp)

        movl    %ecx, -52(%ebp)

        call    _ZN8IOBufferC2Eiii@PLT

(...)



Note that the output of operator new is not passed to IOBuffer constructor. 



Here is the RTL from reduced.ii.210r.postreload:



(call_insn 21 20 22 2 (set (reg:SI 0 ax)

        (call (mem:QI (symbol_ref:SI ("_Znwj") [flags 0x41]  <function_decl

0x7f42c2d77100 operator new>) [0 operator new S1 A8])

            (const_int 4 [0x4]))) reduced.ii:50 652 {*call_value}

     (nil)

    (expr_list:REG_DEP_TRUE (use (reg:SI 3 bx))

        (expr_list:REG_BR_PRED (use (mem:SI (reg/f:SI 7 sp) [0 S4 A32]))

            (nil))))

(insn 22 21 23 2 (set (reg/v/f:SI 2 cx [orig:59 save_buf ] [59])

        (reg:SI 0 ax)) reduced.ii:50 85 {*movsi_internal}

     (expr_list:REG_DEAD (reg:SI 0 ax)

        (nil)))

(insn 23 22 24 2 (set (mem:SI (plus:SI (reg/f:SI 7 sp)

                (const_int 12 [0xc])) [0 S4 A32])

        (const_int 0 [0])) reduced.ii:41 85 {*movsi_internal}

     (nil))

(insn 24 23 59 2 (set (mem:SI (plus:SI (reg/f:SI 7 sp)

                (const_int 8 [0x8])) [0 S4 A32])

        (const_int 16 [0x10])) reduced.ii:41 85 {*movsi_internal}

     (nil))

(insn 59 24 25 2 (set (reg:DI 1 dx [orig:78 n ] [78])

        (mem/c:DI (plus:SI (reg/f:SI 6 bp)

                (const_int -48 [0xffffffffffffffd0])) [9 %sfp+-48 S8 A64]))

reduced.ii:41 84 {*movdi_internal}

     (expr_list:REG_DEAD (reg:DI 92)

        (nil)))

(insn 25 59 26 2 (set (mem:SI (plus:SI (reg/f:SI 7 sp)

                (const_int 4 [0x4])) [0 S4 A32])

        (reg:SI 1 dx [orig:78 n ] [78])) reduced.ii:41 85 {*movsi_internal}

     (expr_list:REG_DEAD (reg:DI 1 dx [orig:78 n ] [78])

        (nil)))

(insn 26 25 56 2 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32])

        (reg/v/f:SI 2 cx [orig:59 save_buf ] [59])) reduced.ii:41 85

{*movsi_internal}

     (nil))

(insn 56 26 27 2 (set (mem/c:SI (plus:SI (reg/f:SI 6 bp)

                (const_int -52 [0xffffffffffffffcc])) [9 %sfp+-52 S4 A32])

        (reg/v/f:SI 2 cx [orig:59 save_buf ] [59])) reduced.ii:41 85

{*movsi_internal}

     (expr_list:REG_DEAD (reg/v/f:SI 2 cx [orig:59 save_buf ] [59])

        (nil)))

(call_insn 27 56 28 2 (call (mem:QI (symbol_ref:SI ("_ZN8IOBufferC2Eiii")

[flags 0x41]  <function_decl 0x7f42c2d82d00 __base_ctor >) [0 __base_ctor  S1

A8])





The dump from the next pass (split2) shows that insn 59 above is split into:



(insn 69 24 70 2 (set (reg:SI 1 dx [orig:78 n ] [78])

        (mem/c:SI (plus:SI (reg/f:SI 6 bp)

                (const_int -48 [0xffffffffffffffd0])) [9 %sfp+-48 S4 A64]))

reduced.ii:41 85 {*movsi_internal}

     (nil))

(insn 70 69 25 2 (set (reg:SI 2 cx [ n+4 ])

        (mem/c:SI (plus:SI (reg/f:SI 6 bp)

                (const_int -44 [0xffffffffffffffd4])) [9 %sfp+-44 S4 A32]))

reduced.ii:41 85 {*movsi_internal}

     (nil))





But here, cx is actually live and the split_after_reload pass clobbers it.

Reply via email to