[clang] [Clang] Access tls_guard via llvm.threadlocal.address (PR #96633)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 8 08:18:41 PDT 2024
================
@@ -1070,13 +1084,20 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
// Mark as initialized before initializing anything else. If the
// initializers use previously-initialized thread_local vars, that's
// probably supposed to be OK, but the standard doesn't say.
- Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
-
- // The guard variable can't ever change again.
+ // Get the thread-local address via intrinsic.
+ if (IsTLS)
+ GuardAddr = GuardAddr.withPointer(
+ Builder.CreateThreadLocalAddress(Guard.getPointer()),
+ NotKnownNonNull);
+ Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(), 1),
+ GuardAddr);
+
+ // Emit invariant start for TLS guard address.
EmitInvariantStart(
Guard.getPointer(),
CharUnits::fromQuantity(
- CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));
+ CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())),
+ IsTLS);
----------------
nikola-tesic-ns wrote:
Ok, thanks for your effort and detailed explanation!
Do you think the best we can do (in this case) is to get `threadlocal.address` from `__tls_guard` at the first access in `__tls_init` function and reuse it in the whole function (example below)?
```
define internal void @__tls_init() {
%tls_addr = call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @__tls_guard)
%1 = load i8, ptr %1, align 1
%2 = icmp eq i8 %1, 0
br i1 %2, label %3, label %5
3:
store i8 1, ptr %tls_addr, align 1
%4 = call ptr @llvm.invariant.start.p0(i64 1, ptr %tls_addr)
call void @__cxx_global_var_init()
br label %5
5:
ret void
}
```
https://github.com/llvm/llvm-project/pull/96633
More information about the cfe-commits
mailing list