[llvm] f7fd7a1 - [LFI][AArch64] Emit .tlsdesccall with the associated blr (#200903)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 16:54:05 PDT 2026


Author: Zachary Yedidia
Date: 2026-06-01T16:54:00-07:00
New Revision: f7fd7a17361ceb850a9c370df25777ba10519710

URL: https://github.com/llvm/llvm-project/commit/f7fd7a17361ceb850a9c370df25777ba10519710
DIFF: https://github.com/llvm/llvm-project/commit/f7fd7a17361ceb850a9c370df25777ba10519710.diff

LOG: [LFI][AArch64] Emit .tlsdesccall with the associated blr (#200903)

This PR fixes an issue in the LFI control-flow rewrites if a blr is
marked with `.tlsdesccall`. The `.tlsdesccall` should be moved after
rewriting so that it is associated with the rewritten `blr`, rather than
the guard instruction.

Added: 
    llvm/test/MC/AArch64/LFI/tlsdesccall.s

Modified: 
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
index a3d9c86629158..6b683be0f535e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
@@ -101,6 +101,17 @@ void AArch64MCLFIRewriter::emitBranch(unsigned Opcode, MCRegister Target,
   emitInst(Branch, Out, STI);
 }
 
+void AArch64MCLFIRewriter::emitPendingTLSDescCall(MCStreamer &Out,
+                                                  const MCSubtargetInfo &STI) {
+  if (!PendingTLSDescCall)
+    return;
+  MCInst Marker;
+  Marker.setOpcode(AArch64::TLSDESCCALL);
+  Marker.addOperand(MCOperand::createExpr(PendingTLSDescCall));
+  PendingTLSDescCall = nullptr;
+  emitInst(Marker, Out, STI);
+}
+
 void AArch64MCLFIRewriter::emitMov(MCRegister Dest, MCRegister Src,
                                    MCStreamer &Out,
                                    const MCSubtargetInfo &STI) {
@@ -127,6 +138,9 @@ void AArch64MCLFIRewriter::rewriteIndirectBranch(const MCInst &Inst,
 
   // Guard the branch target through X28.
   emitAddMask(LFIAddrReg, BranchReg, Out, STI);
+
+  emitPendingTLSDescCall(Out, STI);
+
   emitBranch(Inst.getOpcode(), LFIAddrReg, Out, STI);
 }
 
@@ -218,6 +232,11 @@ void AArch64MCLFIRewriter::rewriteTPWrite(const MCInst &Inst, MCStreamer &Out,
 // AArch64InstrInfo::getLFIInstSizeInBytes must be updated to match.
 void AArch64MCLFIRewriter::doRewriteInst(const MCInst &Inst, MCStreamer &Out,
                                          const MCSubtargetInfo &STI) {
+  if (Inst.getOpcode() == AArch64::TLSDESCCALL) {
+    PendingTLSDescCall = Inst.getOperand(0).getExpr();
+    return;
+  }
+
   // Reserved register modification is an error.
   if (MCRegister Reg = mayModifyReserved(Inst)) {
     error(Inst, Twine("illegal modification of reserved LFI register ") +

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.h
index 8af6e1b00a791..e4ed767aa21d9 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.h
@@ -20,6 +20,7 @@
 
 namespace llvm {
 class MCContext;
+class MCExpr;
 class MCInst;
 class MCStreamer;
 class MCSubtargetInfo;
@@ -50,6 +51,12 @@ class AArch64MCLFIRewriter : public MCLFIRewriter {
   /// Recursion guard to prevent infinite loops when emitting instructions.
   bool Guard = false;
 
+  /// Deferred `.tlsdesccall` symbol. The directive attaches a
+  /// R_AARCH64_TLSDESC_CALL relocation to the following BLR. Since LFI inserts
+  /// a guard before that BLR, the marker is deferred and re-emitted between
+  /// the guard and the branch so the relocation stays on the BLR.
+  const MCExpr *PendingTLSDescCall = nullptr;
+
   // Instruction classification. Returns the reserved register that may be
   // modified, or an invalid register if no reserved register is touched.
   MCRegister mayModifyReserved(const MCInst &Inst) const;
@@ -61,6 +68,7 @@ class AArch64MCLFIRewriter : public MCLFIRewriter {
                    const MCSubtargetInfo &STI);
   void emitBranch(unsigned Opcode, MCRegister Target, MCStreamer &Out,
                   const MCSubtargetInfo &STI);
+  void emitPendingTLSDescCall(MCStreamer &Out, const MCSubtargetInfo &STI);
   void emitMov(MCRegister Dest, MCRegister Src, MCStreamer &Out,
                const MCSubtargetInfo &STI);
 

diff  --git a/llvm/test/MC/AArch64/LFI/tlsdesccall.s b/llvm/test/MC/AArch64/LFI/tlsdesccall.s
new file mode 100644
index 0000000000000..252685cc69a72
--- /dev/null
+++ b/llvm/test/MC/AArch64/LFI/tlsdesccall.s
@@ -0,0 +1,12 @@
+// RUN: llvm-mc -triple aarch64_lfi %s | FileCheck %s
+
+adrp x0, :tlsdesc:var
+ldr x1, [x0, :tlsdesc_lo12:var]
+add x0, x0, :tlsdesc_lo12:var
+.tlsdesccall var
+blr x1
+// CHECK:      add x0, x0, :tlsdesc_lo12:var
+// CHECK-NOT:  .tlsdesccall
+// CHECK:      add x28, x27, w1, uxtw
+// CHECK-NEXT: .tlsdesccall var
+// CHECK-NEXT: blr x28


        


More information about the llvm-commits mailing list