Fix PR64876, regressions in powerpc64 Go testsuite
Alan Modra
amodra@gmail.com
Tue Feb 3 13:57:00 GMT 2015
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
More information about the Gcc-patches
mailing list