3.4 i386 code generation problem with leal

Jan Hubicka jh@suse.cz
Mon Apr 7 20:10:00 GMT 2003


> > > But that line is:
> > >    52511         leal    $1196+lf@GOTOFF, %esi
> > > 
> > > And this looks really broken,
> > 
> > Yes, that may be leftout of my PIC changes.  I will dig into this.
> 
> I filed a proper PR for this as target/10327; unfortunately, I hit
> return on the web form when I tried to hit ] and sent it with an
> incomplete subject line; maybe someone with GNATS write access can fix this.
Once again, the previous patch apparently didn't went out.
The problem is because we accept both (const (unspec GOT (const (plus
(symbol) (int))))) and (const (plus (unspec GOT (symbol)) (int)))
and get confused later.  This patch makes us to accept the second
alternative only that deals better with adjust_address and friends.
Bootstrapped/regtested with -fPIC

Mon Apr  7 21:52:54 CEST 2003  Jan Hubicka  <jh@suse.cz>
	* i386.c (legitimate_pic_address_disp_p): Do not accept PLUS in the
	GOTOFF operand.
	(legitimize_pic_address): Move plus outside the unspec.
	* i386.c (legitimate_constant_p):  Check (CONST (PLUS (UNSPEC ...
	for validity.
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.557
diff -c -3 -p -r1.557 i386.c
*** config/i386/i386.c	3 Apr 2003 17:40:47 -0000	1.557
--- config/i386/i386.c	7 Apr 2003 19:52:33 -0000
*************** legitimate_pic_address_disp_p (disp)
*** 5833,5838 ****
--- 5833,5840 ----
  	return false;
        return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
      case UNSPEC_GOTOFF:
+       if (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
+ 	  || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
        return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
      case UNSPEC_GOTTPOFF:
      case UNSPEC_GOTNTPOFF:
*************** legitimize_pic_address (orig, reg)
*** 6146,6152 ****
  
        if (reload_in_progress)
  	regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
!       new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
        new = gen_rtx_CONST (Pmode, new);
        new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
  
--- 6148,6162 ----
  
        if (reload_in_progress)
  	regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
!       if (GET_CODE (addr) == CONST)
! 	addr = XEXP (addr, 0);
!       if (GET_CODE (addr) == PLUS)
! 	  {
!             new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)), UNSPEC_GOTOFF);
! 	    new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
! 	  }
! 	else
!           new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
        new = gen_rtx_CONST (Pmode, new);
        new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
*** 5674,5679 ****
--- 5674,5686 ----
  	  && tls_symbolic_operand (XEXP (inner, 0), Pmode))
  	return false;
  
+       if (GET_CODE (inner) == PLUS)
+ 	{
+ 	  if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
+ 	    return false;
+ 	  inner = XEXP (inner, 0);
+ 	}
+ 
        /* Only some unspecs are valid as "constants".  */
        if (GET_CODE (inner) == UNSPEC)
  	switch (XINT (inner, 1))
*************** legitimate_pic_address_disp_p (disp)
*** 5833,5838 ****
--- 5840,5847 ----
  	return false;
        return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
      case UNSPEC_GOTOFF:
+       if (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
+ 	  || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
        return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
      case UNSPEC_GOTTPOFF:
      case UNSPEC_GOTNTPOFF:



More information about the Gcc-bugs mailing list