Hi, this fixes the tls testsuite fails on s390. Calls to __tls_get_offset require the GOT pointer to be loaded what so far only happened when building pic code. With the attached patch the GOT pointer is loaded "on demand" when calling __tls_get_offset.
Committed to mainline. Bye, -Andreas- 2011-10-07 Andreas Krebbel <andreas.kreb...@de.ibm.com> * config/s390/s390.c (s390_emit_tls_call_insn): Remove assertion. Load GOT pointer for non-pic builds. (s390_load_got): Replace pic_offset_table_rtx with hardcoded r12. (s390_emit_call): Likewise. Index: gcc/config/s390/s390.c =================================================================== *** gcc/config/s390/s390.c.orig --- gcc/config/s390/s390.c *************** s390_emit_tls_call_insn (rtx result_reg, *** 3604,3610 **** { rtx insn; ! gcc_assert (flag_pic); if (!s390_tls_symbol) s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset"); --- 3604,3611 ---- { rtx insn; ! if (!flag_pic) ! emit_insn (s390_load_got ()); if (!s390_tls_symbol) s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset"); *************** s390_load_got (void) *** 7859,7864 **** --- 7860,7871 ---- { rtx insns; + /* We cannot use pic_offset_table_rtx here since we use this + function also for non-pic if __tls_get_offset is called and in + that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx + aren't usable. */ + rtx got_rtx = gen_rtx_REG (Pmode, 12); + if (!got_symbol) { got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); *************** s390_load_got (void) *** 7869,7875 **** if (TARGET_CPU_ZARCH) { ! emit_move_insn (pic_offset_table_rtx, got_symbol); } else { --- 7876,7882 ---- if (TARGET_CPU_ZARCH) { ! emit_move_insn (got_rtx, got_symbol); } else { *************** s390_load_got (void) *** 7880,7892 **** offset = gen_rtx_CONST (Pmode, offset); offset = force_const_mem (Pmode, offset); ! emit_move_insn (pic_offset_table_rtx, offset); offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)), UNSPEC_LTREL_BASE); ! offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset); ! emit_move_insn (pic_offset_table_rtx, offset); } insns = get_insns (); --- 7887,7899 ---- offset = gen_rtx_CONST (Pmode, offset); offset = force_const_mem (Pmode, offset); ! emit_move_insn (got_rtx, offset); offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)), UNSPEC_LTREL_BASE); ! offset = gen_rtx_PLUS (Pmode, got_rtx, offset); ! emit_move_insn (got_rtx, offset); } insns = get_insns (); *************** s390_emit_call (rtx addr_location, rtx t *** 9827,9834 **** /* s390_function_ok_for_sibcall should have denied sibcalls in this case. */ gcc_assert (retaddr_reg != NULL_RTX); ! ! use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); } return insn; } --- 9834,9840 ---- /* s390_function_ok_for_sibcall should have denied sibcalls in this case. */ gcc_assert (retaddr_reg != NULL_RTX); ! use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 12)); } return insn; }