[llvm] [RISCV] Declare TLSDESC clobbers for vector registers and CSRs per psABI (PR #205027)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 00:58:03 PDT 2026
https://github.com/LukeZhuang updated https://github.com/llvm/llvm-project/pull/205027
>From 7b80229f0a3e515cce41c0946f303baedce5b814 Mon Sep 17 00:00:00 2001
From: Luke Zhuang <luke.zhuang at linux.alibaba.com>
Date: Wed, 24 Jun 2026 17:33:16 +0800
Subject: [PATCH] [RISCV] Declare TLSDESC clobbers for vector registers and
CSRs per psABI (#205027)
Per the RISC-V psABI, the TLSDESC resolver clobbers a0 and t0 in the
base case. By the new ABI updates
(https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/496),
when the V extension is enabled, it now additionally clobbers
all vector registers and vector CSRs.
This patch adds V-regs/csrs clobbering to the existing
PseudoLA_TLSDESC and PseudoTLSDESCCall in RISCVInstrInfo.td,
as well as 2 additional tests covering the V-register clobber
and V-CSRs clobber cases.
---
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 8 +-
.../RISCV/tlsdesc-clobber-vector-csrs.ll | 61 ++++
.../RISCV/tlsdesc-clobber-vector-regs.ll | 338 ++++++++++++++++++
llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll | 4 +
4 files changed, 409 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-csrs.ll
create mode 100644 llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-regs.ll
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 7b72dfbbad91e..5ad3f5c9af497 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1955,9 +1955,13 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8,
def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
"la.tls.gd", "$dst, $src">;
+defvar TLSDESCVClobbers = !listconcat(
+ !foreach(i, !range(32), !cast<Register>("V"#i)),
+ [VTYPE, VL, VXSAT, VXRM]);
+
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32 in
def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), []> {
- let Defs = [X5, X10];
+ let Defs = !listconcat([X5, X10], TLSDESCVClobbers);
}
def TLSDESCCallSymbol : AsmOperandClass {
@@ -1982,7 +1986,7 @@ def PseudoTLSDESCCall : Pseudo<(outs GPR:$rd),
(ins GPR:$rs1, simm12_lo:$imm12, tlsdesc_call_symbol:$src), [],
"jalr", "$rd, ${imm12}(${rs1}), $src">,
Sched<[WriteJalr, ReadJalr]> {
- let Defs = [X10];
+ let Defs = !listconcat([X10], TLSDESCVClobbers);
let Uses = [X10];
}
diff --git a/llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-csrs.ll b/llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-csrs.ll
new file mode 100644
index 0000000000000..f6ca65650031f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-csrs.ll
@@ -0,0 +1,61 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr=+v -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV64
+; RUN: llc -mtriple=riscv32 -mattr=+v -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV32
+
+;; Verify that when the V extension is enabled, the TLSDESC resolver clobbers
+;; vector CSRs (vl, vtype, vxrm, vxsat) per the psABI. The compiler must
+;; re-emit a vsetvl after the TLSDESC call to recover the vector configuration
+
+ at tls_var = external thread_local global i32
+
+define void @test_vector_csr_clobber(ptr %in, ptr %out) nounwind {
+; RV64-LABEL: test_vector_csr_clobber:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: mv a2, a0
+; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; RV64-NEXT: vle32.v v8, (a0)
+; RV64-NEXT: .Ltlsdesc_hi0:
+; RV64-NEXT: auipc a0, %tlsdesc_hi(tls_var)
+; RV64-NEXT: vse32.v v8, (a1)
+; RV64-NEXT: ld a3, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
+; RV64-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV64-NEXT: jalr t0, 0(a3), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV64-NEXT: add a0, a0, tp
+; RV64-NEXT: li a3, 1
+; RV64-NEXT: sw a3, 0(a0)
+; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; RV64-NEXT: vle32.v v8, (a2)
+; RV64-NEXT: vse32.v v8, (a1)
+; RV64-NEXT: ret
+;
+; RV32-LABEL: test_vector_csr_clobber:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: mv a2, a0
+; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; RV32-NEXT: vle32.v v8, (a0)
+; RV32-NEXT: .Ltlsdesc_hi0:
+; RV32-NEXT: auipc a0, %tlsdesc_hi(tls_var)
+; RV32-NEXT: vse32.v v8, (a1)
+; RV32-NEXT: lw a3, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
+; RV32-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV32-NEXT: jalr t0, 0(a3), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV32-NEXT: add a0, a0, tp
+; RV32-NEXT: li a3, 1
+; RV32-NEXT: sw a3, 0(a0)
+; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; RV32-NEXT: vle32.v v8, (a2)
+; RV32-NEXT: vse32.v v8, (a1)
+; RV32-NEXT: ret
+entry:
+ %v1 = load <4 x i32>, ptr %in
+ store <4 x i32> %v1, ptr %out
+
+ store i32 1, ptr @tls_var
+
+ ;; We must re-emit vsetvli here because TLSDESC clobbered it
+ %v2 = load <4 x i32>, ptr %in
+ store <4 x i32> %v2, ptr %out
+ ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-regs.ll b/llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-regs.ll
new file mode 100644
index 0000000000000..a5e3ede958825
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/tlsdesc-clobber-vector-regs.ll
@@ -0,0 +1,338 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr=+v -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV64
+; RUN: llc -mtriple=riscv32 -mattr=+v -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV32
+
+;; Verify that when the V extension is enabled, vector registers whose live
+;; ranges span a TLSDESC call are spilled and reloaded, because the TLSDESC
+;; resolver clobbers all vector registers per the psABI.
+
+ at tls_var = external thread_local global i32
+
+define void @test_vector_reg_clobber() nounwind {
+; RV64-LABEL: test_vector_reg_clobber:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: addi sp, sp, -16
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 3
+; RV64-NEXT: sub sp, sp, a0
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v1
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a1, a0, 3
+; RV64-NEXT: sub a0, a1, a0
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v1, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v2
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 1
+; RV64-NEXT: mv a1, a0
+; RV64-NEXT: slli a0, a0, 1
+; RV64-NEXT: add a0, a0, a1
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v2, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v3
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a1, a0, 2
+; RV64-NEXT: add a0, a1, a0
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v3, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v4
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 2
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v4, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v5
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a1, a0, 1
+; RV64-NEXT: add a0, a1, a0
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v5, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v6
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 1
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v6, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v7
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vs1r.v v7, (a0) # vscale x 8-byte Folded Spill
+; RV64-NEXT: .Ltlsdesc_hi0:
+; RV64-NEXT: auipc a0, %tlsdesc_hi(tls_var)
+; RV64-NEXT: #APP
+; RV64-NEXT: # def v8
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: addi a1, sp, 16
+; RV64-NEXT: vs1r.v v8, (a1) # vscale x 8-byte Folded Spill
+; RV64-NEXT: ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
+; RV64-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV64-NEXT: jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV64-NEXT: add a0, a0, tp
+; RV64-NEXT: li a1, 1
+; RV64-NEXT: sw a1, 0(a0)
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a1, a0, 3
+; RV64-NEXT: sub a0, a1, a0
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v1, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v1
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 1
+; RV64-NEXT: mv a1, a0
+; RV64-NEXT: slli a0, a0, 1
+; RV64-NEXT: add a0, a0, a1
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v2, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v2
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a1, a0, 2
+; RV64-NEXT: add a0, a1, a0
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v3, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v3
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 2
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v4, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v4
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a1, a0, 1
+; RV64-NEXT: add a0, a1, a0
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v5, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v5
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 1
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v6, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v6
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: add a0, sp, a0
+; RV64-NEXT: addi a0, a0, 16
+; RV64-NEXT: vl1r.v v7, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v7
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: addi a0, sp, 16
+; RV64-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload
+; RV64-NEXT: #APP
+; RV64-NEXT: # use v8
+; RV64-NEXT: #NO_APP
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 3
+; RV64-NEXT: add sp, sp, a0
+; RV64-NEXT: addi sp, sp, 16
+; RV64-NEXT: ret
+;
+; RV32-LABEL: test_vector_reg_clobber:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: addi sp, sp, -16
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 3
+; RV32-NEXT: sub sp, sp, a0
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v1
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a1, a0, 3
+; RV32-NEXT: sub a0, a1, a0
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v1, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v2
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 1
+; RV32-NEXT: mv a1, a0
+; RV32-NEXT: slli a0, a0, 1
+; RV32-NEXT: add a0, a0, a1
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v2, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v3
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a1, a0, 2
+; RV32-NEXT: add a0, a1, a0
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v3, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v4
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 2
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v4, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v5
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a1, a0, 1
+; RV32-NEXT: add a0, a1, a0
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v5, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v6
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 1
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v6, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v7
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vs1r.v v7, (a0) # vscale x 8-byte Folded Spill
+; RV32-NEXT: .Ltlsdesc_hi0:
+; RV32-NEXT: auipc a0, %tlsdesc_hi(tls_var)
+; RV32-NEXT: #APP
+; RV32-NEXT: # def v8
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: addi a1, sp, 16
+; RV32-NEXT: vs1r.v v8, (a1) # vscale x 8-byte Folded Spill
+; RV32-NEXT: lw a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
+; RV32-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV32-NEXT: jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV32-NEXT: add a0, a0, tp
+; RV32-NEXT: li a1, 1
+; RV32-NEXT: sw a1, 0(a0)
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a1, a0, 3
+; RV32-NEXT: sub a0, a1, a0
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v1, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v1
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 1
+; RV32-NEXT: mv a1, a0
+; RV32-NEXT: slli a0, a0, 1
+; RV32-NEXT: add a0, a0, a1
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v2, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v2
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a1, a0, 2
+; RV32-NEXT: add a0, a1, a0
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v3, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v3
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 2
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v4, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v4
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a1, a0, 1
+; RV32-NEXT: add a0, a1, a0
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v5, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v5
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 1
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v6, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v6
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: add a0, sp, a0
+; RV32-NEXT: addi a0, a0, 16
+; RV32-NEXT: vl1r.v v7, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v7
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: addi a0, sp, 16
+; RV32-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload
+; RV32-NEXT: #APP
+; RV32-NEXT: # use v8
+; RV32-NEXT: #NO_APP
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 3
+; RV32-NEXT: add sp, sp, a0
+; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: ret
+entry:
+ %v1 = call <vscale x 2 x i32> asm sideeffect "# def v1", "={v1}"()
+ %v2 = call <vscale x 2 x i32> asm sideeffect "# def v2", "={v2}"()
+ %v3 = call <vscale x 2 x i32> asm sideeffect "# def v3", "={v3}"()
+ %v4 = call <vscale x 2 x i32> asm sideeffect "# def v4", "={v4}"()
+ %v5 = call <vscale x 2 x i32> asm sideeffect "# def v5", "={v5}"()
+ %v6 = call <vscale x 2 x i32> asm sideeffect "# def v6", "={v6}"()
+ %v7 = call <vscale x 2 x i32> asm sideeffect "# def v7", "={v7}"()
+ %v8 = call <vscale x 2 x i32> asm sideeffect "# def v8", "={v8}"()
+
+ store i32 1, ptr @tls_var
+
+ call void asm sideeffect "# use v1", "{v1}"(<vscale x 2 x i32> %v1)
+ call void asm sideeffect "# use v2", "{v2}"(<vscale x 2 x i32> %v2)
+ call void asm sideeffect "# use v3", "{v3}"(<vscale x 2 x i32> %v3)
+ call void asm sideeffect "# use v4", "{v4}"(<vscale x 2 x i32> %v4)
+ call void asm sideeffect "# use v5", "{v5}"(<vscale x 2 x i32> %v5)
+ call void asm sideeffect "# use v6", "{v6}"(<vscale x 2 x i32> %v6)
+ call void asm sideeffect "# use v7", "{v7}"(<vscale x 2 x i32> %v7)
+ call void asm sideeffect "# use v8", "{v8}"(<vscale x 2 x i32> %v8)
+ ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll b/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll
index 132ff7d83235d..6cfd90c65a6f5 100644
--- a/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll
+++ b/llvm/test/CodeGen/RISCV/tlsdesc-clobber.ll
@@ -3,6 +3,10 @@
; RUN: | FileCheck %s --check-prefix=RV64
; RUN: llc -mtriple=riscv32 -relocation-model=pic -enable-tlsdesc < %s \
; RUN: | FileCheck %s --check-prefix=RV32
+; RUN: llc -mtriple=riscv64 -mattr=+v -relocation-model=pic -enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=RV64
+; RUN: llc -mtriple=riscv32 -mattr=+v -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,
More information about the llvm-commits
mailing list