I restricted output of inline PLT sequences to when TLS marker relocs were also available, which is obviously true when just considering assembler support. However, there is a -mno-tls-markers option to disable emitting the marker relocs. Currently that option also disables inline PLT sequences, which is a bug (*). This patch fixes that problem.
*) To be honest, it was a deliberate bug. I didn't want to have to deal with inline PLT __tls_get_addr sequences lacking the marker relocs in the linker, but it turns out the existing linker support for old-style __tls_get_addr calls works reasonably well. Bootstrapped and regression tested powerpc64le-linux and powerpc64-linux, with and without -mno-tls-markers. OK to apply? * config/rs6000/rs6000.c (rs6000_indirect_call_template_1), (rs6000_pltseq_template): Guard output of TLS markers with TARGET_TLS_MARKERS. (rs6000_longcall_ref, rs6000_call_aix, rs6000_call_sysv), (rs6000_sibcall_sysv): Ignore TARGET_TLS_MARKERS when deciding to use inline PLT sequences. * config/rs6000/rs6000.md (pltseq_tocsave_<mode>), (pltseq_plt16_ha_<mode>, pltseq_plt16_lo_<mode>), (pltseq_mtctr_<mode>): Don't test TARGET_TLS_MARKERS in predicate. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4e3c5fc135f..c126734d3e6 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21618,7 +21618,7 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop, const char *rel64 = TARGET_64BIT ? "64" : ""; char tls[29]; tls[0] = 0; - if (GET_CODE (operands[funop + 1]) == UNSPEC) + if (TARGET_TLS_MARKERS && GET_CODE (operands[funop + 1]) == UNSPEC) { if (XINT (operands[funop + 1], 1) == UNSPEC_TLSGD) sprintf (tls, ".reloc .,R_PPC%s_TLSGD,%%%u\n\t", @@ -21707,7 +21707,7 @@ rs6000_pltseq_template (rtx *operands, int which) const char *rel64 = TARGET_64BIT ? "64" : ""; char tls[28]; tls[0] = 0; - if (GET_CODE (operands[3]) == UNSPEC) + if (TARGET_TLS_MARKERS && GET_CODE (operands[3]) == UNSPEC) { if (XINT (operands[3], 1) == UNSPEC_TLSGD) sprintf (tls, ".reloc .,R_PPC%s_TLSGD,%%3\n\t", @@ -32768,7 +32768,6 @@ rs6000_longcall_ref (rtx call_ref, rtx arg) } if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)) { rtx base = const0_rtx; @@ -37767,7 +37766,6 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) stack_toc_offset)); MEM_VOLATILE_P (stack_toc_mem) = 1; if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS && DEFAULT_ABI == ABI_ELFv2 && GET_CODE (func_desc) == SYMBOL_REF) { @@ -37792,7 +37790,6 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) this insn for linker plt sequence editing too. */ func_addr = gen_rtx_REG (Pmode, CTR_REGNO); if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS && GET_CODE (func_desc) == SYMBOL_REF) { rtvec v = gen_rtvec (3, abi_reg, func_desc, tlsarg); @@ -37933,8 +37930,7 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) func = rs6000_longcall_ref (func_desc, tlsarg); /* If the longcall was implemented using PLT16 relocs, then r11 needs to be valid at the call for lazy linking. */ - if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS) + if (HAVE_AS_PLTSEQ) abi_reg = func; } @@ -37948,7 +37944,6 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) this insn for linker plt sequence editing too. */ func_addr = gen_rtx_REG (Pmode, CTR_REGNO); if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS && GET_CODE (func_desc) == SYMBOL_REF) { rtvec v = gen_rtvec (3, func, func_desc, tlsarg); @@ -38005,8 +38000,7 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) func = rs6000_longcall_ref (func_desc, tlsarg); /* If the longcall was implemented using PLT16 relocs, then r11 needs to be valid at the call for lazy linking. */ - if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS) + if (HAVE_AS_PLTSEQ) abi_reg = func; } @@ -38019,7 +38013,6 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) this insn for linker plt sequence editing too. */ func_addr = gen_rtx_REG (Pmode, CTR_REGNO); if (HAVE_AS_PLTSEQ - && TARGET_TLS_MARKERS && GET_CODE (func_desc) == SYMBOL_REF) { rtvec v = gen_rtvec (3, func, func_desc, tlsarg); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 0d5ef31f9f2..58070447639 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10250,7 +10250,7 @@ (define_insn "*pltseq_tocsave_<mode>" (match_operand:P 2 "symbol_ref_operand" "s") (match_operand:P 3 "" "")] UNSPEC_PLTSEQ))] - "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + "HAVE_AS_PLTSEQ && DEFAULT_ABI == ABI_ELFv2" { return rs6000_pltseq_template (operands, 0); @@ -10262,7 +10262,7 @@ (define_insn "*pltseq_plt16_ha_<mode>" (match_operand:P 2 "symbol_ref_operand" "s") (match_operand:P 3 "" "")] UNSPEC_PLT16_HA))] - "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + "HAVE_AS_PLTSEQ && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)" { return rs6000_pltseq_template (operands, 1); @@ -10274,7 +10274,7 @@ (define_insn "*pltseq_plt16_lo_<mode>" (match_operand:P 2 "symbol_ref_operand" "s") (match_operand:P 3 "" "")] UNSPEC_PLT16_LO))] - "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + "HAVE_AS_PLTSEQ && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)" { return rs6000_pltseq_template (operands, 2); @@ -10287,7 +10287,7 @@ (define_insn "*pltseq_mtctr_<mode>" (match_operand:P 2 "symbol_ref_operand" "s") (match_operand:P 3 "" "")] UNSPEC_PLTSEQ))] - "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + "HAVE_AS_PLTSEQ && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)" { return rs6000_pltseq_template (operands, 3); -- Alan Modra Australia Development Lab, IBM