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

Reply via email to