[llvm] [PAC][ELF] Support R_AARCH64_AUTH_TLSDESC_CALL relocation (PR #198327)

Daniil Kovalev via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 02:25:04 PDT 2026


https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/198327

>From 99a890b8285a1d65c9fc5fa358538759fd9bacc6 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 18 May 2026 18:41:23 +0300
Subject: [PATCH 1/5] [PAC][ELF] Support R_AARCH64_AUTH_TLSDESC_CALL relocation

The R_AARCH64_AUTH_TLSDESC_CALL is introduced to allow linker relaxation of
AUTH TLSDESC call sequences for non-preemptible undefined weak symbols.

The lld patch introducing the relaxation: #194636

Corresponding ARM docs PR: https://github.com/ARM-software/abi-aa/pull/395
---
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp   | 15 ++++++++++++---
 llvm/lib/Target/AArch64/AArch64InstrInfo.td     |  8 ++++++++
 .../AArch64/AsmParser/AArch64AsmParser.cpp      | 17 +++++++++++------
 .../MCTargetDesc/AArch64MCCodeEmitter.cpp       |  9 +++++++++
 .../AArch64/ptrauth-arm64-tls-dynamics.ll       | 15 ++++++++++-----
 .../MC/AArch64/directives-case_insensitive.s    |  3 +++
 6 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 005f69b08a4d3..5e95d5150c242 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3600,13 +3600,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     ///    adrp  x0, :tlsdesc_auth:var
     ///    ldr   x16, [x0, #:tlsdesc_auth_lo12:var]
     ///    add   x0, x0, #:tlsdesc_auth_lo12:var
+    ///    .tlsdescauthcall var
     ///    blraa x16, x0
     ///    (TPIDR_EL0 offset now in x0)
     const MachineOperand &MO_Sym = MI->getOperand(0);
     MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
-    MCOperand SymTLSDescLo12, SymTLSDesc;
+    MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
     MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF);
     MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
+    MCInstLowering.lowerOperand(MO_Sym, Sym);
     MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
     MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
 
@@ -3632,8 +3634,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     Add.addOperand(MCOperand::createImm(AArch64_AM::getShiftValue(0)));
     EmitToStreamer(*OutStreamer, Add);
 
-    // Authenticated TLSDESC accesses are not relaxed.
-    // Thus, do not emit .tlsdesccall for AUTH TLSDESC.
+    // Emit a relocation-annotation. This expands to no code, but requests
+    // the following instruction gets an R_AARCH64_AUTH_TLSDESC_CALL.
+    MCInst TLSDescAuthCall;
+    TLSDescAuthCall.setOpcode(AArch64::TLSDESCAUTHCALL);
+    TLSDescAuthCall.addOperand(Sym);
+    EmitToStreamer(*OutStreamer, TLSDescAuthCall);
+#ifndef NDEBUG
+    --InstsEmitted; // no code emitted
+#endif
 
     MCInst Blraa;
     Blraa.setOpcode(AArch64::BLRAA);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index ac2f9b16ca229..b1badc89bd5e1 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3773,6 +3773,14 @@ def TLSDESCCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
   let AsmString = ".tlsdesccall $sym";
 }
 
+// This is a directive-like pseudo-instruction. The purpose is to insert an
+// R_AARCH64_AUTH_TLSDESC_CALL relocation at the offset of the following instruction
+// (which in the usual case is a BLRAA).
+let hasSideEffects = 1 in
+def TLSDESCAUTHCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
+  let AsmString = ".tlsdescauthcall $sym";
+}
+
 // Pseudo instruction to tell the streamer to emit a 'B' character into the
 // augmentation string.
 def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {}
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 6da40a4fffd55..252f4d2d78c42 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -191,7 +191,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseDirectiveCPU(SMLoc L);
   bool parseDirectiveInst(SMLoc L);
 
-  bool parseDirectiveTLSDescCall(SMLoc L);
+  bool parseDirectiveTLSDescCall(SMLoc L, bool IsAuth);
 
   bool parseDirectiveLOH(StringRef LOH, SMLoc L);
   bool parseDirectiveLtorg(SMLoc L);
@@ -7074,7 +7074,9 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
   else if (IDVal == ".cpu")
     parseDirectiveCPU(Loc);
   else if (IDVal == ".tlsdesccall")
-    parseDirectiveTLSDescCall(Loc);
+    parseDirectiveTLSDescCall(Loc, /*IsAuth=*/false);
+  else if (IDVal == ".tlsdescauthcall")
+    parseDirectiveTLSDescCall(Loc, /*IsAuth=*/true);
   else if (IDVal == ".ltorg" || IDVal == ".pool")
     parseDirectiveLtorg(Loc);
   else if (IDVal == ".unreq")
@@ -7399,8 +7401,9 @@ bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
 }
 
 // parseDirectiveTLSDescCall:
-//   ::= .tlsdesccall symbol
-bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
+//   ::= .tlsdesccall symbol (if IsAuth is false)
+//   ::= .tlsdescauthcall symbol (if IsAuth is true)
+bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L, bool IsAuth) {
   StringRef Name;
   if (check(getParser().parseIdentifier(Name), L, "expected symbol") ||
       parseToken(AsmToken::EndOfStatement))
@@ -7408,10 +7411,12 @@ bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
 
   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
-  Expr = MCSpecifierExpr::create(Expr, AArch64::S_TLSDESC, getContext());
+  Expr = MCSpecifierExpr::create(
+      Expr, IsAuth ? AArch64::S_TLSDESC_AUTH : AArch64::S_TLSDESC,
+      getContext());
 
   MCInst Inst;
-  Inst.setOpcode(AArch64::TLSDESCCALL);
+  Inst.setOpcode(IsAuth ? AArch64::TLSDESCAUTHCALL : AArch64::TLSDESCCALL);
   Inst.addOperand(MCOperand::createExpr(Expr));
 
   getParser().getStreamer().emitInstruction(Inst, getSTI());
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
index 21ff55e9d9a7f..0183b826c1cb0 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
@@ -738,6 +738,15 @@ void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI,
     return;
   }
 
+  if (MI.getOpcode() == AArch64::TLSDESCAUTHCALL) {
+    // This is a directive which applies an R_AARCH64_AUTH_TLSDESC_CALL to the
+    // following (BLRAA) instruction. It doesn't emit any code itself so it
+    // doesn't go through the normal TableGenerated channels.
+    addFixup(Fixups, 0, MI.getOperand(0).getExpr(),
+             ELF::R_AARCH64_AUTH_TLSDESC_CALL);
+    return;
+  }
+
   if (MI.getOpcode() == AArch64::SPACE) {
     // SPACE just increases basic block size, in both cases no actual code.
     return;
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll b/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
index 981864ce78cc4..5f3747c843e6e 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
@@ -18,6 +18,7 @@ define i32 @test_generaldynamic() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:general_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall general_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -25,7 +26,7 @@ define i32 @test_generaldynamic() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 define ptr @test_generaldynamic_addr() {
@@ -36,6 +37,7 @@ define ptr @test_generaldynamic_addr() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:general_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall general_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs [[TP:x[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: add x0, [[TP]], x0
@@ -43,7 +45,7 @@ define ptr @test_generaldynamic_addr() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 ;; Note: with signed TLSDESC, general dynamic model is always used,
@@ -60,6 +62,7 @@ define i32 @test_localdynamic() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:local_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall local_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -67,7 +70,7 @@ define i32 @test_localdynamic() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 define ptr @test_localdynamic_addr() {
@@ -78,6 +81,7 @@ define ptr @test_localdynamic_addr() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:local_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall local_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: add x0, x[[TPIDR]], x0
@@ -85,7 +89,7 @@ define ptr @test_localdynamic_addr() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 @extern_weak_var = extern_weak thread_local global i32
@@ -99,6 +103,7 @@ define i32 @test_extern_weak() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:extern_weak_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:extern_weak_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:extern_weak_var
+; CHECK-NEXT: .tlsdescauthcall extern_weak_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -106,7 +111,7 @@ define i32 @test_extern_weak() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 ; CHECK-OBJ: 0000000000000000     0 TLS     WEAK   DEFAULT   UND extern_weak_var
 }
 
diff --git a/llvm/test/MC/AArch64/directives-case_insensitive.s b/llvm/test/MC/AArch64/directives-case_insensitive.s
index 88f70521543f9..07f6c50a6ecc7 100644
--- a/llvm/test/MC/AArch64/directives-case_insensitive.s
+++ b/llvm/test/MC/AArch64/directives-case_insensitive.s
@@ -46,5 +46,8 @@ fred .REQ x5
 .TLSDESCCALL var
 // CHECK: .tlsdesccall var
 
+.TLSDESCAUTHCALL var
+// CHECK: .tlsdescauthcall var
+
 .LTORG
 .POOL

>From 1efa5e765fce95850ea650805ac6294a850219e2 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 21 May 2026 13:04:22 +0300
Subject: [PATCH 2/5] Address review comments

---
 llvm/test/MC/AArch64/tls-auth-relocs.s | 36 ++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 llvm/test/MC/AArch64/tls-auth-relocs.s

diff --git a/llvm/test/MC/AArch64/tls-auth-relocs.s b/llvm/test/MC/AArch64/tls-auth-relocs.s
new file mode 100644
index 0000000000000..500564661ddef
--- /dev/null
+++ b/llvm/test/MC/AArch64/tls-auth-relocs.s
@@ -0,0 +1,36 @@
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -show-encoding < %s | FileCheck %s
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -filetype=obj < %s -o - | \
+// RUN:   llvm-readobj -r --symbols - | FileCheck --check-prefix=CHECK-ELF %s
+
+        adrp x8, :tlsdesc_auth:var
+        ldr x7, [x6, :tlsdesc_auth_lo12:var]
+        add x5, x4, #:tlsdesc_auth_lo12:var
+        .tlsdescauthcall var
+        blraa x3, x2
+
+// CHECK:      adrp   x8, :tlsdesc_auth:var            // encoding: [0x08'A',A,A,0x90'A']
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth:var, kind: fixup_aarch64_pcrel_adrp_imm21
+// CHECK:      ldr    x7, [x6, :tlsdesc_auth_lo12:var] // encoding: [0xc7,0bAAAAAA00,0b01AAAAAA,0xf9]
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth_lo12:var, kind: fixup_aarch64_ldst_imm12_scale8
+// CHECK:      add    x5, x4, :tlsdesc_auth_lo12:var   // encoding: [0x85,0bAAAAAA00,0b00AAAAAA,0x91]
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth_lo12:var, kind: fixup_aarch64_add_imm12
+// CHECK:      .tlsdescauthcall var                    // encoding: []
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: var, relocation type: 598
+// CHECK:      blraa  x3, x2                           // encoding: [0x62,0x08,0x3f,0xd7]
+
+// CHECK-ELF:      Relocations [
+// CHECK-ELF-NEXT:   Section {{.*}} .rela.text {
+// CHECK-ELF-NEXT:     0x0 R_AARCH64_AUTH_TLSDESC_ADR_PAGE21 [[VARSYM:[^ ]+]]
+// CHECK-ELF-NEXT:     0x4 R_AARCH64_AUTH_TLSDESC_LD64_LO12 [[VARSYM]]
+// CHECK-ELF-NEXT:     0x8 R_AARCH64_AUTH_TLSDESC_ADD_LO12 [[VARSYM]]
+// CHECK-ELF-NEXT:     0xC R_AARCH64_AUTH_TLSDESC_CALL [[VARSYM]]
+
+// Make sure symbol has type STT_TLS:
+
+// CHECK-ELF:      Symbols [
+// CHECK-ELF:        Symbol {
+// CHECK-ELF:          Name: var
+// CHECK-ELF-NEXT:     Value:
+// CHECK-ELF-NEXT:     Size:
+// CHECK-ELF-NEXT:     Binding: Global
+// CHECK-ELF-NEXT:     Type: TLS

>From c2ceadd97da41919b2275b78ff68ec53f7b8852d Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 3 Aug 2026 17:13:18 +0300
Subject: [PATCH 3/5] `.tlsdescauthcall` -> `.tlsauthdesccall` (per
 documentation)

---
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp          | 10 +++++-----
 llvm/lib/Target/AArch64/AArch64InstrInfo.td            |  4 ++--
 llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp |  6 +++---
 .../AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp      |  2 +-
 .../test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll | 10 +++++-----
 llvm/test/MC/AArch64/directives-case_insensitive.s     |  4 ++--
 llvm/test/MC/AArch64/tls-auth-relocs.s                 |  4 ++--
 7 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 5e95d5150c242..35942d303c6b0 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3600,7 +3600,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     ///    adrp  x0, :tlsdesc_auth:var
     ///    ldr   x16, [x0, #:tlsdesc_auth_lo12:var]
     ///    add   x0, x0, #:tlsdesc_auth_lo12:var
-    ///    .tlsdescauthcall var
+    ///    .tlsauthdesccall var
     ///    blraa x16, x0
     ///    (TPIDR_EL0 offset now in x0)
     const MachineOperand &MO_Sym = MI->getOperand(0);
@@ -3636,10 +3636,10 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
 
     // Emit a relocation-annotation. This expands to no code, but requests
     // the following instruction gets an R_AARCH64_AUTH_TLSDESC_CALL.
-    MCInst TLSDescAuthCall;
-    TLSDescAuthCall.setOpcode(AArch64::TLSDESCAUTHCALL);
-    TLSDescAuthCall.addOperand(Sym);
-    EmitToStreamer(*OutStreamer, TLSDescAuthCall);
+    MCInst TLSAuthDescCall;
+    TLSAuthDescCall.setOpcode(AArch64::TLSAUTHDESCCALL);
+    TLSAuthDescCall.addOperand(Sym);
+    EmitToStreamer(*OutStreamer, TLSAuthDescCall);
 #ifndef NDEBUG
     --InstsEmitted; // no code emitted
 #endif
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index b1badc89bd5e1..466de279688ea 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3777,8 +3777,8 @@ def TLSDESCCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
 // R_AARCH64_AUTH_TLSDESC_CALL relocation at the offset of the following instruction
 // (which in the usual case is a BLRAA).
 let hasSideEffects = 1 in
-def TLSDESCAUTHCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
-  let AsmString = ".tlsdescauthcall $sym";
+def TLSAUTHDESCCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
+  let AsmString = ".tlsauthdesccall $sym";
 }
 
 // Pseudo instruction to tell the streamer to emit a 'B' character into the
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 252f4d2d78c42..aaa54e658bcc7 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -7075,7 +7075,7 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
     parseDirectiveCPU(Loc);
   else if (IDVal == ".tlsdesccall")
     parseDirectiveTLSDescCall(Loc, /*IsAuth=*/false);
-  else if (IDVal == ".tlsdescauthcall")
+  else if (IDVal == ".tlsauthdesccall")
     parseDirectiveTLSDescCall(Loc, /*IsAuth=*/true);
   else if (IDVal == ".ltorg" || IDVal == ".pool")
     parseDirectiveLtorg(Loc);
@@ -7402,7 +7402,7 @@ bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
 
 // parseDirectiveTLSDescCall:
 //   ::= .tlsdesccall symbol (if IsAuth is false)
-//   ::= .tlsdescauthcall symbol (if IsAuth is true)
+//   ::= .tlsauthdesccall symbol (if IsAuth is true)
 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L, bool IsAuth) {
   StringRef Name;
   if (check(getParser().parseIdentifier(Name), L, "expected symbol") ||
@@ -7416,7 +7416,7 @@ bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L, bool IsAuth) {
       getContext());
 
   MCInst Inst;
-  Inst.setOpcode(IsAuth ? AArch64::TLSDESCAUTHCALL : AArch64::TLSDESCCALL);
+  Inst.setOpcode(IsAuth ? AArch64::TLSAUTHDESCCALL : AArch64::TLSDESCCALL);
   Inst.addOperand(MCOperand::createExpr(Expr));
 
   getParser().getStreamer().emitInstruction(Inst, getSTI());
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
index 0183b826c1cb0..4baa448c55127 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
@@ -738,7 +738,7 @@ void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI,
     return;
   }
 
-  if (MI.getOpcode() == AArch64::TLSDESCAUTHCALL) {
+  if (MI.getOpcode() == AArch64::TLSAUTHDESCCALL) {
     // This is a directive which applies an R_AARCH64_AUTH_TLSDESC_CALL to the
     // following (BLRAA) instruction. It doesn't emit any code itself so it
     // doesn't go through the normal TableGenerated channels.
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll b/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
index 5f3747c843e6e..0fc8588df51c8 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
@@ -18,7 +18,7 @@ define i32 @test_generaldynamic() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:general_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var
-; CHECK-NEXT: .tlsdescauthcall general_dynamic_var
+; CHECK-NEXT: .tlsauthdesccall general_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -37,7 +37,7 @@ define ptr @test_generaldynamic_addr() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:general_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var
-; CHECK-NEXT: .tlsdescauthcall general_dynamic_var
+; CHECK-NEXT: .tlsauthdesccall general_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs [[TP:x[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: add x0, [[TP]], x0
@@ -62,7 +62,7 @@ define i32 @test_localdynamic() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:local_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var
-; CHECK-NEXT: .tlsdescauthcall local_dynamic_var
+; CHECK-NEXT: .tlsauthdesccall local_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -81,7 +81,7 @@ define ptr @test_localdynamic_addr() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:local_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var
-; CHECK-NEXT: .tlsdescauthcall local_dynamic_var
+; CHECK-NEXT: .tlsauthdesccall local_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: add x0, x[[TPIDR]], x0
@@ -103,7 +103,7 @@ define i32 @test_extern_weak() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:extern_weak_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:extern_weak_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:extern_weak_var
-; CHECK-NEXT: .tlsdescauthcall extern_weak_var
+; CHECK-NEXT: .tlsauthdesccall extern_weak_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
diff --git a/llvm/test/MC/AArch64/directives-case_insensitive.s b/llvm/test/MC/AArch64/directives-case_insensitive.s
index 07f6c50a6ecc7..ee9087b846db2 100644
--- a/llvm/test/MC/AArch64/directives-case_insensitive.s
+++ b/llvm/test/MC/AArch64/directives-case_insensitive.s
@@ -46,8 +46,8 @@ fred .REQ x5
 .TLSDESCCALL var
 // CHECK: .tlsdesccall var
 
-.TLSDESCAUTHCALL var
-// CHECK: .tlsdescauthcall var
+.TLSAUTHDESCCALL var
+// CHECK: .tlsauthdesccall var
 
 .LTORG
 .POOL
diff --git a/llvm/test/MC/AArch64/tls-auth-relocs.s b/llvm/test/MC/AArch64/tls-auth-relocs.s
index 500564661ddef..1604846ccf06b 100644
--- a/llvm/test/MC/AArch64/tls-auth-relocs.s
+++ b/llvm/test/MC/AArch64/tls-auth-relocs.s
@@ -5,7 +5,7 @@
         adrp x8, :tlsdesc_auth:var
         ldr x7, [x6, :tlsdesc_auth_lo12:var]
         add x5, x4, #:tlsdesc_auth_lo12:var
-        .tlsdescauthcall var
+        .tlsauthdesccall var
         blraa x3, x2
 
 // CHECK:      adrp   x8, :tlsdesc_auth:var            // encoding: [0x08'A',A,A,0x90'A']
@@ -14,7 +14,7 @@
 // CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth_lo12:var, kind: fixup_aarch64_ldst_imm12_scale8
 // CHECK:      add    x5, x4, :tlsdesc_auth_lo12:var   // encoding: [0x85,0bAAAAAA00,0b00AAAAAA,0x91]
 // CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth_lo12:var, kind: fixup_aarch64_add_imm12
-// CHECK:      .tlsdescauthcall var                    // encoding: []
+// CHECK:      .tlsauthdesccall var                    // encoding: []
 // CHECK-NEXT:                                         // fixup A - offset: 0, value: var, relocation type: 598
 // CHECK:      blraa  x3, x2                           // encoding: [0x62,0x08,0x3f,0xd7]
 

>From d049ef8dc032709732e988b901892673d7a412f8 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 4 Aug 2026 14:28:22 +0300
Subject: [PATCH 4/5] Address review comments

---
 llvm/test/MC/AArch64/tls-auth-relocs.s | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/MC/AArch64/tls-auth-relocs.s b/llvm/test/MC/AArch64/tls-auth-relocs.s
index 1604846ccf06b..5906cb57961c7 100644
--- a/llvm/test/MC/AArch64/tls-auth-relocs.s
+++ b/llvm/test/MC/AArch64/tls-auth-relocs.s
@@ -1,5 +1,5 @@
-// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -show-encoding < %s | FileCheck %s
-// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -filetype=obj < %s -o - | \
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -show-encoding %s | FileCheck %s
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -filetype=obj %s -o - | \
 // RUN:   llvm-readobj -r --symbols - | FileCheck --check-prefix=CHECK-ELF %s
 
         adrp x8, :tlsdesc_auth:var

>From 7dd0cdb31acde32807801b00468c886afd49fb94 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 21 Sep 2026 12:05:18 +0300
Subject: [PATCH 5/5] Address review comments

---
 llvm/test/MC/AArch64/tls-auth-relocs.s | 34 ++++++++++++--------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/llvm/test/MC/AArch64/tls-auth-relocs.s b/llvm/test/MC/AArch64/tls-auth-relocs.s
index 5906cb57961c7..508bdc4b29ccf 100644
--- a/llvm/test/MC/AArch64/tls-auth-relocs.s
+++ b/llvm/test/MC/AArch64/tls-auth-relocs.s
@@ -1,12 +1,12 @@
 // RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -show-encoding %s | FileCheck %s
 // RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -filetype=obj %s -o - | \
-// RUN:   llvm-readobj -r --symbols - | FileCheck --check-prefix=CHECK-ELF %s
+// RUN:   llvm-readelf -r -s - | FileCheck --check-prefix=CHECK-ELF %s
 
-        adrp x8, :tlsdesc_auth:var
-        ldr x7, [x6, :tlsdesc_auth_lo12:var]
-        add x5, x4, #:tlsdesc_auth_lo12:var
-        .tlsauthdesccall var
-        blraa x3, x2
+adrp x8, :tlsdesc_auth:var
+ldr x7, [x6, :tlsdesc_auth_lo12:var]
+add x5, x4, #:tlsdesc_auth_lo12:var
+.tlsauthdesccall var
+blraa x3, x2
 
 // CHECK:      adrp   x8, :tlsdesc_auth:var            // encoding: [0x08'A',A,A,0x90'A']
 // CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth:var, kind: fixup_aarch64_pcrel_adrp_imm21
@@ -18,19 +18,15 @@
 // CHECK-NEXT:                                         // fixup A - offset: 0, value: var, relocation type: 598
 // CHECK:      blraa  x3, x2                           // encoding: [0x62,0x08,0x3f,0xd7]
 
-// CHECK-ELF:      Relocations [
-// CHECK-ELF-NEXT:   Section {{.*}} .rela.text {
-// CHECK-ELF-NEXT:     0x0 R_AARCH64_AUTH_TLSDESC_ADR_PAGE21 [[VARSYM:[^ ]+]]
-// CHECK-ELF-NEXT:     0x4 R_AARCH64_AUTH_TLSDESC_LD64_LO12 [[VARSYM]]
-// CHECK-ELF-NEXT:     0x8 R_AARCH64_AUTH_TLSDESC_ADD_LO12 [[VARSYM]]
-// CHECK-ELF-NEXT:     0xC R_AARCH64_AUTH_TLSDESC_CALL [[VARSYM]]
+// CHECK-ELF:      Relocation section '.rela.text' at offset 0x98 contains 4 entries:
+// CHECK-ELF-NEXT: Offset           Info             Type                              Symbol's Value   Symbol's Name + Addend
+// CHECK-ELF-NEXT: 0000000000000000 0000000200000253 R_AARCH64_AUTH_TLSDESC_ADR_PAGE21 0000000000000000 var + 0
+// CHECK-ELF-NEXT: 0000000000000004 0000000200000254 R_AARCH64_AUTH_TLSDESC_LD64_LO12  0000000000000000 var + 0
+// CHECK-ELF-NEXT: 0000000000000008 0000000200000255 R_AARCH64_AUTH_TLSDESC_ADD_LO12   0000000000000000 var + 0
+// CHECK-ELF-NEXT: 000000000000000c 0000000200000256 R_AARCH64_AUTH_TLSDESC_CALL       0000000000000000 var + 0
 
 // Make sure symbol has type STT_TLS:
 
-// CHECK-ELF:      Symbols [
-// CHECK-ELF:        Symbol {
-// CHECK-ELF:          Name: var
-// CHECK-ELF-NEXT:     Value:
-// CHECK-ELF-NEXT:     Size:
-// CHECK-ELF-NEXT:     Binding: Global
-// CHECK-ELF-NEXT:     Type: TLS
+// CHECK-ELF:      Symbol table '.symtab' contains [[#]] entries:
+// CHECK-ELF-NEXT: Num:   Value            Size Type Bind   Vis     Ndx Name
+// CHECK-ELF:      [[#]]: 0000000000000000 0    TLS  GLOBAL DEFAULT UND var



More information about the llvm-commits mailing list