This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: CSE removing a load that is necessary
- From: Ian Lance Taylor <iant at google dot com>
- To: "Pranav Bhandarkar" <pranav dot bhandarkar at gmail dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: 27 Jul 2007 10:24:29 -0700
- Subject: Re: CSE removing a load that is necessary
- References: <649555d50707271007p64000747tb6c003177e4ffe1d@mail.gmail.com>
"Pranav Bhandarkar" <pranav.bhandarkar@gmail.com> writes:
> 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.
Where does reg 178 come from? It does not appear in the other insns
you listed.
> 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 ?
Am I reading your code correctly when it appears that the
__floatunsidf function returns a value in memory rather than via a
register?
If lower-subreg split up the load from memory, then it was correct to
remove the REG_RETVAL note. There may be a bug here in that it should
also remove the REG_EQUAL note in that case. It may be that
remove_retval_note needs to look for and remove a REG_EQUAL note.
Ian