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

--- Comment #4 from Uroš Bizjak <ubizjak at gmail dot com> ---
As explained in the #Comment 0, we have the following situation in main:

        leal    .LC164@GOTOFF(%ebx), %eax       # 32    [c=5 l=6]  *leasi
        pushl   %eax    # 33    [c=4 l=1]  *pushsi2
        pushl   (%esi)  # 35    [c=4 l=2]  *pushsi2
        movl    %eax, -100(%ebp)        # 159   [c=4 l=3]  *movsi_internal/1
        call    _fprintf        # 36    [c=9 l=5]  *call_value

...

        pushl   %eax    # 123   [c=4 l=1]  *pushsi2
        pushl   -100(%ebp)      # 125   [c=8 l=3]  *pushsi2
        pushl   (%esi)  # 127   [c=4 l=2]  *pushsi2
        call    _fprintf        # 128   [c=9 l=5]  *call_value

where (insn 159) pushes value on the stack, which is later read in (insn 125).

Before LRA, we have the following sequence:

_.ira:

(insn 32 31 33 2 (set (reg/f:SI 116)
        (plus:SI (reg:SI 82)
            (const:SI (unspec:SI [
                        (symbol_ref/f:SI ("*.LC164") [flags 0x2]  <var_decl
0x7fee8274b990 *.LC164>)
                    ] UNSPEC_GOTOFF))))
"../../testsuite/libffi.bhaible/test-callback.c":2310:5 186 {*leasi}
     (expr_list:REG_EQUIV (symbol_ref/f:SI ("*.LC164") [flags 0x2]  <var_decl
0x7fee8274b990 *.LC164>)
        (nil)))
(insn 33 32 35 2 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [2  S4 A32])
        (reg/f:SI 116)) "../../testsuite/libffi.bhaible/test-callback.c":2310:5
43 {*pushsi2}
     (expr_list:REG_ARGS_SIZE (const_int 28 [0x1c])
        (nil)))
(insn 35 33 36 2 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [3  S4 A32])
        (mem/f/c:SI (reg/f:SI 109) [3 out+0 S4 A32]))
"../../testsuite/libffi.bhaible/test-callback.c":2310:5 43 {*pushsi2}
     (expr_list:REG_ARGS_SIZE (const_int 32 [0x20])
        (nil)))
(call_insn 36 35 37 2 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:SI ("_fprintf") [flags 0x3]  <function_decl
0x7fee8398d500 _fprintf>) [0 _fprintf S1 A8])
            (const_int 32 [0x20])))
"../../testsuite/libffi.bhaible/test-callback.c":2310:5 676 {*call_value}
     (expr_list:REG_UNUSED (reg:SI 0 ax)
        (expr_list:REG_CALL_DECL (symbol_ref:SI ("_fprintf") [flags 0x3] 
<function_decl 0x7fee8398d500 _fprintf>)
            (expr_list:REG_EH_REGION (const_int 0 [0])
                (nil))))
    (nil))

...

(insn 123 122 125 6 (set (mem:SI (pre_dec:SI (reg/f:SI 7 sp)) [1  S4 A32])
        (reg:SI 136 [ Cr ]))
"../../testsuite/libffi.bhaible/test-callback.c":2328:5 43 {*pushsi2}
     (expr_list:REG_DEAD (reg:SI 136 [ Cr ])
        (expr_list:REG_ARGS_SIZE (const_int 8 [0x8])
            (nil))))
(insn 125 123 127 6 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [2  S4 A32])
        (reg/f:SI 116)) "../../testsuite/libffi.bhaible/test-callback.c":2328:5
43 {*pushsi2}
     (expr_list:REG_DEAD (reg/f:SI 116)
        (expr_list:REG_ARGS_SIZE (const_int 12 [0xc])
            (nil))))
(insn 127 125 128 6 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [3  S4 A32])
        (mem/f/c:SI (reg/f:SI 109) [3 out+0 S4 A32]))
"../../testsuite/libffi.bhaible/test-callback.c":2328:5 43 {*pushsi2}
     (expr_list:REG_ARGS_SIZE (const_int 16 [0x10])
        (nil)))
(call_insn 128 127 129 6 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:SI ("_fprintf") [flags 0x3]  <function_decl
0x7fee8398d500 _fprintf>) [0 _fprintf S1 A8])
            (const_int 16 [0x10])))
"../../testsuite/libffi.bhaible/test-callback.c":2328:5 676 {*call_value}
     (expr_list:REG_UNUSED (reg:SI 0 ax)
        (expr_list:REG_CALL_DECL (symbol_ref:SI ("_fprintf") [flags 0x3] 
<function_decl 0x7fee8398d500 _fprintf>)
            (expr_list:REG_EH_REGION (const_int 0 [0])
                (nil))))
    (nil))

Please note (reg 116), which is kept alive all the way to (insn 127), where it
is pushed on stack.

LRA pass stores the value in (reg 116) to a frame with:

(insn 159 32 33 2 (set (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -100 [0xffffffffffffff9c])) [35 %sfp+-76 S4 A32])
        (reg/f:SI 0 ax [116]))
"../../testsuite/libffi.bhaible/test-callback.c":2310:5 67 {*movsi_internal}
     (nil))

and substitutes (reg 116) in (insn 125) with a new memory location:

(insn 125 123 127 7 (set (mem/f:SI (pre_dec:SI (reg/f:SI 7 sp)) [2  S4 A32])
        (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -100 [0xffffffffffffff9c])) [35 %sfp+-76 S4 A32]))
"../../testsuite/libffi.bhaible/test-callback.c":2328:5 43 {*pushsi2}
     (expr_list:REG_ARGS_SIZE (const_int 12 [0xc])
        (nil)))

The frame is correctly constructed using:

        subl    $100, %esp      # 185   [c=4 l=3] 
pro_epilogue_adjust_stack_si_add/0

It looks to me that LRA creates too small frame, perhpas it doesn't account for
preceeding (insn 123) for some reason.

Reply via email to