mstorsjo created this revision. mstorsjo added reviewers: rnk, mati865. mstorsjo requested review of this revision. Herald added a project: clang.
These actually can be automatically imported from another DLL. (This works properly as long as the actual implementation of emutls is linked dynamically from e.g. libgcc; if the implementation comes from compiler-rt or a statically linked libgcc, it doesn't work as intended.) This fixes PR50146 and https://github.com/msys2/MINGW-packages/issues/8706 (fixing calling std::call_once in a dynamically linked libstdc++); since f73183958482602c4588b0f4a1c3a096e7542947 <https://reviews.llvm.org/rGf73183958482602c4588b0f4a1c3a096e7542947> the dso_local attribute on the TLS variable affected the actual generated code for accessing the emutls variable. The dso_local attribute on the emutls variable made those accesses to use 32 bit relative addressing in code, which requires runtime pseudo relocations in the text section, and breaks entirely if the actual other variable ends up loaded too far away in the virtual address space. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D102970 Files: clang/lib/CodeGen/CodeGenModule.cpp clang/test/CodeGen/dso-local-executable.c Index: clang/test/CodeGen/dso-local-executable.c =================================================================== --- clang/test/CodeGen/dso-local-executable.c +++ clang/test/CodeGen/dso-local-executable.c @@ -9,13 +9,15 @@ // COFF-DAG: define dso_local i32* @zed() // COFF-DAG: declare dllimport void @import_func() -// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s +// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck --check-prefixes=MINGW,MINGW-NATIVE_TLS %s +// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - -femulated-tls | FileCheck --check-prefixes=MINGW,MINGW-EMUTLS %s // MINGW: @baz = dso_local global i32 42 // MINGW-NEXT: @import_var = external dllimport global i32 // MINGW-NEXT: @weak_bar = extern_weak global i32 // MINGW-NEXT: @bar = external global i32 // MINGW-NEXT: @local_thread_var = dso_local thread_local global i32 42 -// MINGW-NEXT: @thread_var = external dso_local thread_local global i32 +// MINGW-NATIVE_TLS-NEXT: @thread_var = external dso_local thread_local global i32 +// MINGW-EMUTLS-NEXT: @thread_var = external thread_local global i32 // MINGW-DAG: declare dso_local void @foo() // MINGW-DAG: define dso_local i32* @zed() // MINGW-DAG: declare dllimport void @import_func() Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -986,8 +986,12 @@ // In MinGW, variables without DLLImport can still be automatically // imported from a DLL by the linker; don't mark variables that // potentially could come from another DLL as DSO local. + + // With EmulatedTLS, TLS variables can be autoimported from other DLLs + // (and this actually happens in the public interface of libstdc++), so + // such variables can't be marked as DSO local. if (GV->isDeclarationForLinker() && isa<llvm::GlobalVariable>(GV) && - !GV->isThreadLocal()) + (!GV->isThreadLocal() || CGM.getCodeGenOpts().EmulatedTLS)) return false; }
Index: clang/test/CodeGen/dso-local-executable.c =================================================================== --- clang/test/CodeGen/dso-local-executable.c +++ clang/test/CodeGen/dso-local-executable.c @@ -9,13 +9,15 @@ // COFF-DAG: define dso_local i32* @zed() // COFF-DAG: declare dllimport void @import_func() -// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s +// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck --check-prefixes=MINGW,MINGW-NATIVE_TLS %s +// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - -femulated-tls | FileCheck --check-prefixes=MINGW,MINGW-EMUTLS %s // MINGW: @baz = dso_local global i32 42 // MINGW-NEXT: @import_var = external dllimport global i32 // MINGW-NEXT: @weak_bar = extern_weak global i32 // MINGW-NEXT: @bar = external global i32 // MINGW-NEXT: @local_thread_var = dso_local thread_local global i32 42 -// MINGW-NEXT: @thread_var = external dso_local thread_local global i32 +// MINGW-NATIVE_TLS-NEXT: @thread_var = external dso_local thread_local global i32 +// MINGW-EMUTLS-NEXT: @thread_var = external thread_local global i32 // MINGW-DAG: declare dso_local void @foo() // MINGW-DAG: define dso_local i32* @zed() // MINGW-DAG: declare dllimport void @import_func() Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -986,8 +986,12 @@ // In MinGW, variables without DLLImport can still be automatically // imported from a DLL by the linker; don't mark variables that // potentially could come from another DLL as DSO local. + + // With EmulatedTLS, TLS variables can be autoimported from other DLLs + // (and this actually happens in the public interface of libstdc++), so + // such variables can't be marked as DSO local. if (GV->isDeclarationForLinker() && isa<llvm::GlobalVariable>(GV) && - !GV->isThreadLocal()) + (!GV->isThreadLocal() || CGM.getCodeGenOpts().EmulatedTLS)) return false; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits