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

--- Comment #4 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Uroš Bizjak from comment #3)
> The testcase from Comment #1 fails.

Got it. LRA miscompiles "f".

Function "f" of the testcase from Comment #1 compiles (-O2 -m32 -mregparm=3)
to:

f.1485:
        cmpl    $2, %eax
        je      .L6
        xorl    %eax, %eax
        ret
.L6:
        pushl   %esi
        movl    $.L3, %eax
        pushl   %ebp
        movl    %esp, %ebp
(32)    movl    4(%ebp), %edx
(14)    movl    (%edx), %ebp
(33)    movl    4(%ebp), %ecx
(17)    movl    4(%ecx), %esp
        jmp     *%eax

In the above asm, (insn 14) clobbers %ebp, which is used as temporary in (insn
32) and (insn 33).

In _.ira dump, we have:

(insn 3 2 4 2 (set (reg/f:SI 90 [ CHAIN.1 ])
        (mem/c:SI (plus:SI (reg/f:SI 16 argp)
                (const_int -8 [0xfffffffffffffff8])) [3  S4 A8])) t.c:7 90
{*movsi_internal}
     (expr_list:REG_EQUIV (mem/c:SI (plus:SI (reg/f:SI 16 argp)
                (const_int -8 [0xfffffffffffffff8])) [3  S4 A8])
        (nil)))

[...]

(insn 14 13 15 3 (set (reg/f:SI 6 bp)
        (mem:SI (reg/f:SI 90 [ CHAIN.1 ]) [0  S4 A8])) t.c:9 90
{*movsi_internal}
     (nil))

[...]

(insn 17 16 18 3 (set (reg/f:SI 7 sp)
        (mem:SI (plus:SI (reg/f:SI 90 [ CHAIN.1 ])
                (const_int 4 [0x4])) [0  S4 A8])) t.c:9 90 {*movsi_internal}
     (expr_list:REG_DEAD (reg/f:SI 90 [ CHAIN.1 ])
        (nil)))


LRA copies (insn 3) just before (insn 14) and (insn 17), eliminating argp on
the fly to HARD_FRAME_POINTER (= %ebp). Following sequence is generated:

(insn 32 13 14 3 (set (reg:SI 1 dx [94])
        (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int 4 [0x4])) [3  S4 A8])) t.c:9 90 {*movsi_internal}
     (nil))
(insn 14 32 15 3 (set (reg/f:SI 6 bp)
        (mem:SI (reg:SI 1 dx [94]) [0  S4 A8])) t.c:9 90 {*movsi_internal}
     (nil))

[...]

(insn 33 16 17 3 (set (reg:SI 2 cx [95])
        (mem/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int 4 [0x4])) [3  S4 A8])) t.c:9 90 {*movsi_internal}
     (nil))
(insn 17 33 18 3 (set (reg/f:SI 7 sp)
        (mem:SI (plus:SI (reg:SI 2 cx [95])
                (const_int 4 [0x4])) [0  S4 A8])) t.c:9 90 {*movsi_internal}
     (nil))

LRA doesn't notice that (insn 14) clobbers propagated argp (= %ebp) value, used
in (insn 33). Indeed, fixing the asm to use %edx temporary from (insn 32):

.L6:
        pushl   %esi
        movl    $.L3, %eax
        pushl   %ebp
        movl    %esp, %ebp
(32)    movl    4(%ebp), %edx
(14)    movl    (%edx), %ebp
(17)    movl    4(%edx), %esp
        jmp     *%eax

fixes the testcase.

Reply via email to