https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120908
Bug ID: 120908 Summary: *tls_global_dynamic_64_<mode> has an implicit RDI clobber Product: gcc Version: 15.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com CC: liuhongt at gcc dot gnu.org, ubizjak at gmail dot com Target Milestone: --- Target: x86-64 There is: (define_insn "*tls_global_dynamic_64_<mode>" [(set (match_operand:P 0 "register_operand" "=a") (call:P (mem:QI (match_operand 2 "constant_call_address_operand" "Bz")) (match_operand 3))) (unspec:P [(match_operand 1 "tls_symbolic_operand") (reg:P SP_REG)] UNSPEC_TLS_GD)] "TARGET_64BIT" { if (!TARGET_X32) /* The .loc directive has effect for 'the immediately following assembly instruction'. So for a sequence: .loc f l .byte x insn1 the 'immediately following assembly instruction' is insn1. We want to emit an insn prefix here, but if we use .byte (as shown in 'ELF Handling For Thread-Local Storage'), a preceding .loc will point inside the insn sequence, rather than to the start. After relaxation of the sequence by the linker, the .loc might point inside an insn. Use data16 prefix instead, which doesn't have this problem. */ fputs ("\tdata16", asm_out_file); output_asm_insn ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It clobbers RDI, but the pattern doesn't show it. if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) fputs (ASM_SHORT "0x6666\n", asm_out_file); else fputs (ASM_BYTE "0x66\n", asm_out_file); fputs ("\trex64\n", asm_out_file); if (TARGET_SUN_TLS) return "call\t%p2@plt"; if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) return "call\t%P2"; return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}"; } [(set_attr "type" "multi") (set (attr "length") (symbol_ref "TARGET_X32 ? 15 : 16"))])