diff --git a/lld/test/ELF/lto/riscv-no-emutls.ll b/lld/test/ELF/lto/riscv-no-emutls.ll new file mode 100644 --- /dev/null +++ b/lld/test/ELF/lto/riscv-no-emutls.ll @@ -0,0 +1,55 @@ +; Test that on targets w/ default emulated TLS, that pass doesn't run in LTO + +; RUN: split-file %s %t + +; RUN: opt -module-summary %t/a.ll -o %t/a.bc --mtriple=riscv64-unknown-linux-android10000 +; RUN: opt -module-summary %t/b.ll -o %t/b.bc --mtriple=riscv64-unknown-linux-android10000 +; RUN: ld.lld --plugin-opt=-debug-pass=Structure %t/a.bc %t/b.bc -o /dev/null --no-undefined -shared 2>&1 | FileCheck %s --allow-empty + +; Ensure the backend pass we want to avoid doesn't run: LowerEmuTLSPass +; so we check for its output under pass structure +; CHECK-NOT: Add __emutls_ + +; Also check that we don't end up creating thread_locals that are undefined in +; the final link. +; CHECK-NOT: error: undefined hidden symbol: Mem +; CHECK-NOT: error: undefined hidden symbol: __tls_get_addr + +;--- a.ll +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" + +%struct.Memory = type { i32, i32 } + +@Mem = internal thread_local global ptr null, align 8 + +; Give a bogus definition to satisfy the linker +define ptr @__tls_get_addr(ptr nonnull) #0 { + ret ptr null +} + +define void @baz(i32 noundef signext %n) #0 { +entry: + %call = call ptr @create() + %0 = call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @Mem) + store ptr %call, ptr %0, align 8 + + ret void +} + +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1 + +declare ptr @create() #0 + +attributes #0 = { mustprogress noinline nounwind "frame-pointer"="all" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +;--- b.ll +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" + +define ptr @create() #0 { +entry: + ret ptr inttoptr (i64 66 to ptr) +} + +attributes #0 = { mustprogress noinline nounwind "frame-pointer"="all" } + diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -952,7 +952,8 @@ /// Tests whether the target uses emulated TLS as default. bool hasDefaultEmulatedTLS() const { - return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment(); + return !isRISCV64() && + (isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment()); } /// Tests whether the target uses -data-sections as default.