test results (mips-sgi-irix5.2)

Jim Wilson wilson@chestnut.cygnus.com
Thu Sep 4 19:37:00 GMT 1997


	mips-sgi-irix5.2 has two regressions in the g++ tests with haifa
	enabled (eh25, eh49).  The gcc tests were the same with and without
	haifa.

I looked into this.  The problem is happening in builtin_expand_setjmp.

While trying to restore the execution context after a longjmp, it emits
RTL to restore the FP, and then it emits code to perform a call.  The call
is really not necessary.  However, on some systems, such as irix5 (and
perhaps the alpha), a function call as a side effect will cause the GP
(global pointer) register to be restored because the GP is always loaded
from the stack after a call.  Unfortunately, there is no explicit dependence
between a call insn and the fp register, so it is possible for the instruction
scheduler to move the fp restore after the call, which causes the gp register
to be corrupted because it is loaded from the wrong address.

This whole thing is pretty hoaky.  It really should use a
nonlocal_goto_receiver pattern to restore the gp, and then the entire
function call sequence is unnecessary, but that is a lot of potentially
unsafe changes, which I would rather not make at this time.

The simplest way to fix the problem is to emit a scheduling barrier at
the problematic point.  The following patch does this.

Thu Sep  4 19:12:32 1997  Jim Wilson  <wilson@cygnus.com>

	* mips.md (nonlocal_goto_receiver): Define.

*** mips.md.orig	Thu Sep  4 18:23:27 1997
--- mips.md	Thu Sep  4 19:13:03 1997
*************** move\\t%0,%z4\\n\\
*** 6392,6397 ****
--- 6392,6415 ----
     (set_attr "mode"	"none")
     (set_attr "length"	"6")])
  
+ ;; ??? This is a hack to work around a problem with expand_builtin_setjmp.
+ ;; It restores the frame pointer, and then does a call to restore the global
+ ;; pointer (gp) register.  The call insn implicitly (via the assembler) reloads
+ ;; gp from the stack.  However, call insns do not depend on $fp, so it is
+ ;; possible for the instruction scheduler to move the fp restore after the
+ ;; call, which then causes gp to be corrupted.  We fix this by emitting a
+ ;; scheduler barrier.  A better fix is to put code here that restores the
+ ;; $gp, and then the call is unnecessary.  This is only a problem when PIC
+ ;; (TARGET_ABICALLS), and only when the gp register is caller-saved
+ ;; (irix5/o32, but not irix6/n32/n64).
+ 
+ (define_expand "nonlocal_goto_receiver"
+   [(const_int 0)]
+   ""
+   "
+ {
+   emit_insn (gen_blockage ());
+ }")
  
  ;;
  ;;  ....................






More information about the Gcc mailing list