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]
Other format: [Raw text]

Fix PR64876, regressions in powerpc64 Go testsuite


This fixes a large number of Go testsuite failures on powerpc64 ELFv1,
caused by loading r11 from a function descriptor and thus trashing the
value set up from CALL_EXPR_STATIC_CHAIN.  So don't load r11 if it
already contains a useful value.  Whether r11 has been set is found
directly by examining rtl.  Conveniently, looking at the previous
sequence on the rtl sequence stack lets us skip over anything already
emitted for GEN_CALL, and the static chain assignment, if present,
happens to be the last insn of that sequence (calls.c emit_call_1
stuff).

Alternative approaches considered:
1) Turn off TARGET_POINTERS_TO_NESTED_FUNCTIONS for Go in
   rs6000_option_override_internal, similar to the hack posted in the
   PR.  That fixes Go, but leaves __builtin_call_with_static_chain
   broken.
2) Turn off TARGET_POINTERS_TO_NESTED_FUNCTIONS everywhere.  This
   means rewriting rs6000_trampoline_init to not put the static chain
   value into the trampoline function descriptor, and possibly other
   code.  Might also affect user code.
3) Arrange to have a new flag set in the third arg of rs6000_call_aix.
   This isn't simple due to none of INIT_CUMULATIVE_ARGS or various
   targetm.calls hooks having access to the call expression.  We don't
   have a function decl either, since this is an indirect call.

Bootstrapped and regression tested powerpc64-linux.  OK to apply?

	PR target/64876
	* config/rs6000/rs6000.c (chain_already_loaded): New function.
	(rs6000_call_aix): Use it.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 220358)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -32919,7 +32987,29 @@ rs6000_legitimate_constant_p (machine_mode mode, r
 }
 
 
+/* Return TRUE iff the sequence ending in LAST sets the static chain.  */
 
+static bool
+chain_already_loaded (rtx_insn *last)
+{
+  if (last != NULL)
+    {
+      rtx patt = PATTERN (last);
+
+      if (GET_CODE (patt) == SET)
+	{
+	  rtx lhs = XEXP (patt, 0);
+
+	  if (REG_P (lhs) && REGNO (lhs) == STATIC_CHAIN_REGNUM)
+	    return true;
+	}
+    }
+  /* This function is only called when we are about to emit a call,
+     and we know that the static chain is set just before a call, so
+     there is no need to look at previous insns.  */
+  return false;
+}
+
 /* Expand code to perform a call under the AIX or ELFv2 ABI.  */
 
 void
@@ -33002,7 +33092,9 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx fla
 	     originally direct, the 3rd word has not been written since no
 	     trampoline has been built, so we ought not to load it, lest we
 	     override a static chain value.  */
-	  if (!direct_call_p && TARGET_POINTERS_TO_NESTED_FUNCTIONS)
+	  if (!direct_call_p
+	      && TARGET_POINTERS_TO_NESTED_FUNCTIONS
+	      && !chain_already_loaded (crtl->emit.sequence_stack->last))
 	    {
 	      rtx sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
 	      rtx func_sc_offset = GEN_INT (2 * GET_MODE_SIZE (Pmode));

-- 
Alan Modra
Australia Development Lab, IBM


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