diff --git a/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp b/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp index 58ea5b68d5488..cab22f2b08de9 100644 --- a/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp +++ b/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp @@ -236,10 +236,20 @@ bool TLSVariableHoistPass::tryReplaceTLSCandidate(Function &Fn, // Generate a bitcast (no type change) auto *CastInst = genBitCastInst(Fn, GV); + bool InstUsed = false; // to replace the uses of TLS Candidate - for (auto &User : Cand.Users) + for (auto &User : Cand.Users) { + if (IntrinsicInst *II = dyn_cast(User.Inst)) { + if (II->getIntrinsicID() == Intrinsic::threadlocal_address) + continue; + } + InstUsed = true; User.Inst->setOperand(User.OpndIdx, CastInst); + } + + if (!InstUsed) + CastInst->eraseFromParent(); return true; } diff --git a/llvm/test/CodeGen/X86/tls-no-bitcast.ll b/llvm/test/CodeGen/X86/tls-no-bitcast.ll new file mode 100644 index 0000000000000..b3763570b9ca4 --- /dev/null +++ b/llvm/test/CodeGen/X86/tls-no-bitcast.ll @@ -0,0 +1,25 @@ +; RUN: llc -tls-load-hoist=true -stop-after=tlshoist < %s | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@I58561 = external thread_local global ptr + +define i32 @I59676() { +entry: +; CHECK: @I59676 +; CHECK-NOT: bitcast +; CHECK: tail call ptr @llvm.threadlocal.address.p0(ptr @I58561) +; CHECK-NEXT; tail call ptr @llvm.threadlocal.address.p0(ptr @I58561) + %0 = tail call ptr @llvm.threadlocal.address.p0(ptr @I58561) + %1 = tail call ptr @llvm.threadlocal.address.p0(ptr @I58561) + ret i32 0 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #0 + +; uselistorder directives +uselistorder ptr @llvm.threadlocal.address.p0, { 1, 0 } + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }