Hi All,
I am working on a private port and am seeing the following problem.
For a function returning a double the value is stored by the function
in memory. cse removes one of the two loads (to retrieve this returned
value) after the function is called.

To elaborate, the following is the dump just before cse.

(insn 44 43 45 2 test.c:388 (set (reg:SI 1 $c1)
        (reg/f:SI 112 *fp*)) 44 {*movsi} (expr_list:REG_LIBCALL_ID
(const_int 2 [0x2])
        (nil)))

(insn 45 44 46 2 test.c:388 (set (reg:SI 2 $c2)
        (reg:SI 136 [ D.1517 ])) 44 {*movsi} (expr_list:REG_LIBCALL_ID
(const_int 2 [0x2])
        (nil)))

(call_insn 46 45 49 2 test.c:388 (parallel [
            (call (mem:SI (symbol_ref:SI ("__floatunsidf") [flags
0x41]) [0 S4 A32])
                (const_int 0 [0x0]))
            (use (const_int 0 [0x0]))
            (clobber (reg:SI 31 $link))
        ]) 41 {*call_direct} (expr_list:REG_LIBCALL_ID (const_int 2 [0x2])
        (expr_list:REG_EH_REGION (const_int -1 [0xffffffff])
            (nil)))
    (expr_list:REG_DEP_TRUE (use (reg:SI 2 $c2))
        (expr_list:REG_DEP_TRUE (use (reg:SI 1 $c1))
            (nil))))

(insn 49 46 116 2 test.c:388 (clobber (reg:SI 179)) -1
(expr_list:REG_LIBCALL_ID (const_int 2 [0x2])
        (nil)))

(insn 116 49 47 2 test.c:388 (clobber (reg:SI 180 [+4 ])) -1 (nil))

(insn 47 116 48 2 test.c:388 (set (reg:SI 179)
        (mem/c/i:SI (reg/f:SI 112 *fp*) [7 S4 A32])) 44 {*movsi}
(expr_list:REG_LIBCALL_ID (const_int 2 [0x2])
        (nil)))

(insn 48 47 50 2 test.c:388 (set (reg:SI 180 [+4 ])
        (mem/c/i:SI (plus:SI (reg/f:SI 112 *fp*)
                (const_int 4 [0x4])) [7 S4 A32])) 44 {*movsi}
(expr_list:REG_LIBCALL_ID (const_int 2 [0x2])
        (expr_list:REG_EQUAL (float:DF (reg:SI 136 [ D.1517 ]))



cse modifies insn 48 as

(insn 48 47 50 2 test.c:388 (set (reg:SI 180 [+4 ])
        (reg:SI 178 [+4 ])) 44 {*movsi} (expr_list:REG_LIBCALL_ID
(const_int 2 [0x2])
        (expr_list:REG_EQUAL (float:DF (reg:SI 136 [ D.1517 ]))
            (nil))))
            (nil))))

and also replaces every subsequent use of (reg:SI 180 [+4 ]) with
(reg:SI 178 [+4 ]) thus making the above load dead, which gets
subsequently removed. This way the result of the function call is
lost.

My take is that insn 48 should have a REG_RETVAL note  ( Infact it
does have this but the note is removed by lower_subreg) and cse should
be careful when  REG_RETVAL and REG_EQUAL appear in the same insn. Is
this the right way of going about it ?

Sorry for a rather verbose post.

Thanks in advance,
Pranav

Reply via email to