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"))])