This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: CSE removing a load that is necessary


"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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]