target/10213: 3.4: optimization problem with ix86 fast prologue

snyder@fnal.gov snyder@fnal.gov
Tue Mar 25 23:50:00 GMT 2003


>Number:         10213
>Category:       target
>Synopsis:       3.4: optimization problem with ix86 fast prologue
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 25 22:06:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     scott snyder
>Release:        3.4 20030324 (experimental)
>Organization:
>Environment:
System: Linux karma 2.4.19-emp_2419p5a829i #1 Tue Sep 3 17:42:17 EST 2002 i686 i686 i386 GNU/Linux
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long --enable-languages=c,c++,f77
>Description:

gcc miscompiles the program below when compiled with -fPIC -O2.
The effect is that the function substrtest() does not preserve
the edi register as it should; the test case below demonstrates this
by printing the contents of edi before and after the call
to substrtest().

I expect that the program should print out two identical numbers.
Here's what it actually does for me:

$ g++ -fPIC -O2 -o x x.cc
$ ./x
bfffc1a4
8048411
$

Here's the relevant extract from the generated code:

_Z10substrtestv:
	pushl	%ebp
	movl	%esp, %ebp
	movl	%ebx, -12(%ebp)
	movl	%edi, -4(%ebp)
	leal	-40(%ebp), %edi
	call	__i686.get_pc_thunk.bx
	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
	movl	%esi, -8(%ebp)
	subl	$56, %esp

The prologue for this function saves edi to -4(ebp).
(This is in the red zone, since sp hasn't been adjusted yet.)
But it then makes the call to __i686.get_pc_thunk.bx to get the
current pc for the PIC base.  However, this call pushes the return
address on the stack --- which is just -4(ebp), clobbering the
saved value of edi.

This probem is new since Mar 16.  Looking through the changelog,
i would suspect these changes (though i haven't confirmed that yet).


2003-03-21  Jan Hubicka  <jh@suse.cz>

	* i386.c (ix86_compute_frame_layout): Recompute fast prologues
	only when amount of saved regs changed.
	(ix86_init_machine_status): Initialize use_fast_prologue_epilgoue_nregs.
	* i386.h (machine_function): New fields use_fast_prologue_epilgoue_nregs.

2003-03-19  Jan Hubicka  <jh@suse.cz>

	* i386.h (machine_function): New fields use_fast_prologue_epilogue.
	* i386.c (use_fast_prologue_epilogue): Remove.
	(ix86_frame): New field save_regs-using_mov;
	(ix86_compute_frame_layout):  Decide on fast prologues;
	allocate saved registers in red zone.
	(ix86_expand_epilogue, ix86_expand_prolgoues): Obey new parameters.





>How-To-Repeat:

Compile with -fPIC -O2

------------------------------------------
extern "C" int printf (...);

unsigned
length(const char* __s)
{ return 5; }


class xbasic_string
{
public:
  char* p;

  xbasic_string(const xbasic_string& __str);
  xbasic_string() {}
};


xbasic_string::
xbasic_string(const xbasic_string& __str)
  : p(0)
{ }


void replace(xbasic_string&, const char* s) {}

xbasic_string X;

void foo1() {}

void substrtest()
{
  xbasic_string x (X);

  if (x.p)
    foo1();
  
  replace (x,
           "r" + length("r")
           );
}


int main()
{
  int out;
  asm volatile ("mov %%edi,%0" : "=r" (out));
  printf ("%x\n", out);
  substrtest();
  asm volatile ("mov %%edi,%0" : "=r" (out));
  printf ("%x\n", out);
  return 0;
}
------------------------------------------

>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list