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