This is the mail archive of the gcc-patches@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: bugfix for cselib_invalidate_regno


Richard Earnshaw <rearnsha@arm.com> writes:

> > Denis Chertykov <denisc@overta.ru> writes:
> > 
> > > I have founded a bug in cselib.c:cselib_invalidate_regno.
> > > The avr port triggers this bug.
> > > Current version of cselib_invalidate_regno didn't invalidate lower
> > > register numbers if they contain values that overlap REGNO in case
> > > that (regno < FIRST_PSEUDO_REGISTER && mode == VOIDmode). This happens
> > > if cselib_invalidate_regno called from cselib_process_insn which
> > > handle CALL_INSN.
> > > IE
> > > 
> > >   /* If this is a call instruction, forget anything stored in a
> > >      call clobbered register, or, if this is not a const call, in
> > >      memory.  */
> > >   if (GET_CODE (insn) == CALL_INSN)
> > >     {
> > >       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> > > 	if (call_used_regs[i])
> > > 	  cselib_invalidate_regno (i, VOIDmode);
> > > 
> > > 
> > > Can I apply the following patch to mainline and 3.3 branches ?
> > > 
> > > Denis.
> > > 
> > > 
> > > Index: cselib.c
> > > ===================================================================
> > > RCS file: /cvsroot/gcc/egcs/gcc/cselib.c,v
> > > retrieving revision 1.27
> > > diff -c -3 -p -r1.27 cselib.c
> > > *** cselib.c	17 Apr 2003 01:07:12 -0000	1.27
> > > --- cselib.c	19 May 2003 11:09:38 -0000
> > > *************** cselib_invalidate_regno (regno, mode)
> > > *** 1019,1032 ****
> > >        pseudos, only REGNO is affected.  For hard regs, we must take MODE
> > >        into account, and we must also invalidate lower register numbers
> > >        if they contain values that overlap REGNO.  */
> > > !   if (regno < FIRST_PSEUDO_REGISTER && mode != VOIDmode) 
> > >       {
> > >         if (regno < max_value_regs)
> > >   	i = 0;
> > >         else
> > >   	i = regno - max_value_regs;
> > >   
> > > !       endregno = regno + HARD_REGNO_NREGS (regno, mode);
> > >       }
> > >     else
> > >       {
> > > --- 1019,1033 ----
> > >        pseudos, only REGNO is affected.  For hard regs, we must take MODE
> > >        into account, and we must also invalidate lower register numbers
> > >        if they contain values that overlap REGNO.  */
> > > !   if (regno < FIRST_PSEUDO_REGISTER)
> > >       {
> > >         if (regno < max_value_regs)
> > >   	i = 0;
> > >         else
> > >   	i = regno - max_value_regs;
> > >   
> > > !       endregno = regno
> > > ! 	+ (mode != VOIDmode ? HARD_REGNO_NREGS (regno, mode) : 1);
> > >       }
> > >     else
> > >       {
> > 
> > Anybody, please, review my tiny patch.
> > 
> > Denis.
> > 
> 
> Why not change the caller to pass reg_raw_mode[regno].  That seems much 
> cleaner to me than pretending a hard register can have no mode.

Because my patch make cselib_invalidate_regno more universal.
Your example will work with my patch too.

cselib_invalidate_regno have only two callers, are you sure that the
second always pass the mode != VOIDmode ?

Denis.


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