================
@@ -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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to