[committed] Fix a MIPS16 hard-float optimisation

Message ID 87ehv094zz.fsf@firetop.home
State New
Headers show

Commit Message

Richard Sandiford Jan. 15, 2012, 6:48 p.m.
gcc.dg/torture/stackalign/builtin-apply-4.c was failing for MIPS16
hard-float with -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects.
We created a specialised out-of-line version of bar() that was
called by (rather than inlined into) main().  So we had the
equivalent of:

  static double __attribute__((noinline)) bar (void) { return 1.0; }
  double foo (void) { return bar (); }

Compiled without -fpic this worked fine, but compiled with -fpic it hit:

      /* If this is a locally-defined and locally-binding function,
	 avoid the stub by calling the local alias directly.  */
      if (mips16_local_function_p (fn))
	  *fn_ptr = mips16_local_alias (fn);
	  return NULL_RTX;

The problem is that these local aliases are only defined (and only
needed) for functions that take arguments in floating-point registers,
so we got a link error trying to call bar()'s local alias.

Tested on mips64-linux-gnu and applied.


	* config/mips/mips.c (mips16_build_call_stub): Don't use a stub
	for calls to locally-binding MIPS16 functions if only the return
	type uses float regs.


Index: gcc/config/mips/mips.c
--- gcc/config/mips/mips.c	2012-01-15 18:22:47.000000000 +0000
+++ gcc/config/mips/mips.c	2012-01-15 18:31:58.000000000 +0000
@@ -6172,6 +6172,13 @@  mips16_build_call_stub (rtx retval, rtx
   if (mips16_stub_function_p (fn))
     return NULL_RTX;
+  /* If we're calling a locally-defined MIPS16 function, we know that
+     it will return values in both the "soft-float" and "hard-float"
+     registers.  There is no need to use a stub to move the latter
+     to the former.  */
+  if (fp_code == 0 && mips16_local_function_p (fn))
+    return NULL_RTX;
   /* This code will only work for o32 and o64 abis.  The other ABI's
      require more sophisticated support.  */
   gcc_assert (TARGET_OLDABI);