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]

PATCH: Fix 20000724-1.c



This test was nominally a regression from GCC 2.95.x.

The problem was that our code to combine stack-adjustments moves an
adjustment across a call expressed as inline assembly, essentially
putting a variable out of scope sooner that it should.

In looking at it carefully, I think the extended asm is bogus.  In
particular, we have:

  !   asm volatile("call ___checkme" : : "c" (x) : "memory");

where `__checkme' is a function which fiddles around with the stack.
The asm doesn't clobber the stack pointer, which is wrong; GCC has no
way to know that this instruction messes with that register.
According to the manual, `volatile' is not documented to have this
affect.  (Well, you could argue that since a volatile asm cannot be
"moved significantly" that the combination shouldn't be done across
the asm, but that seems like a stretch to me.  Note that a volatile
asm "can be moved in ways that appear insignificant to the compiler".
Basically, the documentation doesn't say much about what the semantics
of volatile are here, except that the instruction is assumed to have
important side-effects and won't be removed.)

So, I changed the test to use:

!   asm volatile("call ___checkme" : : "c" (x) : "esp", "memory");

But, that didn't fix it.  That's because when we expand the clobbers,
we clobber the register in QImode, and in regmove.c we check for a
clobber of stack_pointer_rtx, which is (naturally) in SImode.

So, we need the attached patch to fix the compiler.

Tested on i686-pc-linux-gnu, installed on the mainline and the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2001-04-30  Mark Mitchell  <mark@codesourcery.com>

	* regmove.c (record_stack_memrefs): Catch all references to the
	stack pointer.

2001-04-30  Mark Mitchell  <mark@codesourcery.com>

	* gcc.dg/20000724-1.c: Add a clobber of `esp'.

Index: gcc/regmove.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regmove.c,v
retrieving revision 1.96
diff -c -p -r1.96 regmove.c
*** regmove.c	2001/01/31 00:20:44	1.96
--- regmove.c	2001/04/30 14:37:31
*************** record_stack_memrefs (xp, data)
*** 2297,2307 ****
  	}
        return 1;
      case REG:
!       /* ??? We want be able to handle non-memory stack pointer references
!          later.  For now just discard all insns refering to stack pointer
!          outside mem expressions.  We would probably want to teach
! 	 validate_replace to simplify expressions first.  */
!       if (x == stack_pointer_rtx)
  	return 1;
        break;
      default:
--- 2297,2312 ----
  	}
        return 1;
      case REG:
!       /* ??? We want be able to handle non-memory stack pointer
! 	 references later.  For now just discard all insns refering to
! 	 stack pointer outside mem expressions.  We would probably
! 	 want to teach validate_replace to simplify expressions first.
! 
! 	 We can't just compare with STACK_POINTER_RTX because the
! 	 reference to the stack pointer might be in some other mode.
! 	 In particular, an explict clobber in an asm statement will
! 	 result in a QImode clober.  */
!       if (REGNO (x) == STACK_POINTER_REGNUM)
  	return 1;
        break;
      default:
Index: gcc/testsuite/gcc.dg/20000724-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20000724-1.c,v
retrieving revision 1.1.8.1
diff -c -p -r1.1.8.1 20000724-1.c
*** 20000724-1.c	2001/03/07 01:07:22	1.1.8.1
--- 20000724-1.c	2001/04/30 14:37:35
*************** NT	"ret"
*** 51,57 ****
  
  extern inline void do_asm(struct s * x)
  {
!   asm volatile("call ___checkme" : : "c" (x) : "memory");
  }
  
  int foo(void)
--- 51,57 ----
  
  extern inline void do_asm(struct s * x)
  {
!   asm volatile("call ___checkme" : : "c" (x) : "esp", "memory");
  }
  
  int foo(void)


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