[llvm] [RISCV] Add explicit defs in PseudoLA_TLSDESC (PR #205494)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 24 01:57:27 PDT 2026
https://github.com/LukeZhuang updated https://github.com/llvm/llvm-project/pull/205494
>From b38952b6527b591274a364b02d920dd4cb34ce69 Mon Sep 17 00:00:00 2001
From: Zhi Zhuang <zhuangzhi.zz at alibaba-inc.com>
Date: Wed, 24 Jun 2026 12:21:49 +0800
Subject: [PATCH] [RISCV] Add explicit defs in PseudoLA_TLSDESC (#205494)
Per the psABI, la.tlsdesc clobbers a0/t0. The defs are not strictly
required now because the expanding happens pre-RA, while just
in case some passes may need it or the expanding may be moved to
post-RA in the future.
Also, a test case is added as well showing the right behavior of
TLSDESC clobbering.
---
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 4 +-
llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll | 53 ++++++++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 2abd63202a4bf..7b72dfbbad91e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1956,7 +1956,9 @@ def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
"la.tls.gd", "$dst, $src">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32 in
-def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), []>;
+def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), []> {
+ let Defs = [X5, X10];
+}
def TLSDESCCallSymbol : AsmOperandClass {
let Name = "TLSDESCCallSymbol";
diff --git a/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll b/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll
new file mode 100644
index 0000000000000..132ff7d83235d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll
@@ -0,0 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV64
+; RUN: llc -mtriple=riscv32 -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV32
+
+;; Verify that the TLSDESC resolver only clobbers a0 and t0 per the psABI.
+;; Arguments in ra/a1-a3 need not be saved/restored across the TLSDESC call,
+;; unlike a normal function call.
+
+ at tls_var = external thread_local global i32
+
+;; ra/a1-a3 need not be saved to stack or moved to s-regs.
+
+define i32 @test_clobber(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
+; RV64-LABEL: test_clobber:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: .Ltlsdesc_hi0:
+; RV64-NEXT: auipc a5, %tlsdesc_hi(tls_var)
+; RV64-NEXT: ld a6, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a5)
+; RV64-NEXT: mv a4, a0
+; RV64-NEXT: addi a0, a5, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV64-NEXT: jalr t0, 0(a6), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV64-NEXT: add a1, a4, a1
+; RV64-NEXT: add a2, a2, a3
+; RV64-NEXT: add a3, a0, tp
+; RV64-NEXT: addw a0, a1, a2
+; RV64-NEXT: li a1, 1
+; RV64-NEXT: sw a1, 0(a3)
+; RV64-NEXT: ret
+;
+; RV32-LABEL: test_clobber:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: .Ltlsdesc_hi0:
+; RV32-NEXT: auipc a5, %tlsdesc_hi(tls_var)
+; RV32-NEXT: lw a6, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a5)
+; RV32-NEXT: mv a4, a0
+; RV32-NEXT: addi a0, a5, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV32-NEXT: jalr t0, 0(a6), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV32-NEXT: add a1, a4, a1
+; RV32-NEXT: add a2, a2, a3
+; RV32-NEXT: add a3, a0, tp
+; RV32-NEXT: add a0, a1, a2
+; RV32-NEXT: li a1, 1
+; RV32-NEXT: sw a1, 0(a3)
+; RV32-NEXT: ret
+entry:
+ store i32 1, ptr @tls_var
+ %sum1 = add i32 %a, %b
+ %sum2 = add i32 %sum1, %c
+ %sum3 = add i32 %sum2, %d
+ ret i32 %sum3
+}
More information about the llvm-commits
mailing list