Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -1802,6 +1802,8 @@ FuncAttrs.addAttribute("indirect-tls-seg-refs"); if (CodeGenOpts.NoImplicitFloat) FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat); + if (Context.getLangOpts().PICLevel > 0) + FuncAttrs.addAttribute("tls-load-hoist"); if (AttrOnCallSite) { // Attributes that should go on the call site only. Index: clang/test/CodeGen/X86/tls_loads.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/X86/tls_loads.cpp @@ -0,0 +1,44 @@ +// RUN: %clang -target x86_64-unknown-unknown -fPIC -O2 -S -o - %s -emit-llvm | FileCheck %s --check-prefix=HOIST +// RUN: %clang -target x86_64-unknown-unknown -O2 -S -o - %s -emit-llvm | FileCheck %s --check-prefix=NOHOIST + +// Use this test generate IR test for llvm/test/CodeGen/X86/intel-tls-loads-control*.ll +thread_local int thl_x; +thread_local int thl_x2; + +struct SS { + char thl_c; + int num; +}; + +int gfunc(); +int gfunc2(int); + +int f1(int c) { + int *px = &thl_x; + while (c--) + *px += gfunc2(thl_x2); + return *px; +} + +int f2(int c) { + thread_local struct SS st; + while (c--) { + thl_x += gfunc(); + st.thl_c += (char)gfunc(); + st.num += gfunc(); + } + return thl_x; +} + +int f3(int c) { + int *px = &thl_x; + gfunc2(*px); + gfunc2(*px); + return 1; +} + +// HOIST: attributes {{.*}}"tls-load-hoist" +// HOIST: attributes {{.*}}"tls-load-hoist" +// HOIST: attributes {{.*}}"tls-load-hoist" + +// NOHOIST-NOT: attributes {{.*}}"tls-load-hoist" Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -2125,7 +2125,7 @@ ``"tls-load-hoist"`` This attribute indicates that the function will try to reduce redundant - tls address caculation by hoisting tls variable. + tls address calculation by hoisting tls variable. ``uwtable[(sync|async)]`` This attribute indicates that the ABI being targeted requires that Index: llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp =================================================================== --- llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp +++ llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp @@ -40,16 +40,10 @@ #define DEBUG_TYPE "tlshoist" -// TODO: Support "strict" model if we need to strictly load TLS address, -// because "non-optimize" may also do some optimization in other passes. -static cl::opt TLSLoadHoist( - "tls-load-hoist", - cl::desc( - "hoist the TLS loads in PIC model: " - "tls-load-hoist=optimize: Eleminate redundant TLS load(s)." - "tls-load-hoist=strict: Strictly load TLS address before every use." - "tls-load-hoist=non-optimize: Generally load TLS before use(s)."), - cl::init("non-optimize"), cl::Hidden); +static cl::opt TLSLoadHoist( + "tls-load-hoist", cl::init(false), cl::Hidden, + cl::desc("hoist the TLS loads in PIC model to eleminate redundant " + "TLS address calculation.")); namespace { @@ -282,8 +276,7 @@ if (Fn.hasOptNone()) return false; - if (TLSLoadHoist != "optimize" && - !Fn.getAttributes().hasFnAttr("tls-load-hoist")) + if (!TLSLoadHoist && !Fn.getAttributes().hasFnAttr("tls-load-hoist")) return false; this->LI = &LI; Index: llvm/test/CodeGen/X86/tls-loads-control.ll =================================================================== --- llvm/test/CodeGen/X86/tls-loads-control.ll +++ llvm/test/CodeGen/X86/tls-loads-control.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --tls-load-hoist=optimize --stop-after=tlshoist -o - %s | FileCheck %s +; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --tls-load-hoist=true --stop-after=tlshoist -o - %s | FileCheck %s ; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --stop-after=tlshoist -o - %s | FileCheck %s ; This test come from compiling clang/test/CodeGen/intel/tls_loads.cpp with: Index: llvm/test/CodeGen/X86/tls-loads-control2.ll =================================================================== --- llvm/test/CodeGen/X86/tls-loads-control2.ll +++ llvm/test/CodeGen/X86/tls-loads-control2.ll @@ -1,5 +1,4 @@ -; RUN: opt -S -mtriple=x86_64-unknown-unknown -tlshoist --relocation-model=pic --tls-load-hoist=optimize -o - %s | FileCheck %s --check-prefix=HOIST0 -; RUN: opt -S -mtriple=x86_64-unknown-unknown -tlshoist --relocation-model=pic --tls-load-hoist=non-optimize -o - %s | FileCheck %s --check-prefix=HOIST2 +; RUN: opt -S -mtriple=x86_64-unknown-unknown -tlshoist --relocation-model=pic --tls-load-hoist=true -o - %s | FileCheck %s --check-prefix=HOIST0 ; RUN: opt -S -mtriple=x86_64-unknown-unknown -tlshoist --relocation-model=pic -o - %s | FileCheck %s --check-prefix=HOIST2 $_ZTW5thl_x = comdat any Index: llvm/test/CodeGen/X86/tls-loads-control3.ll =================================================================== --- llvm/test/CodeGen/X86/tls-loads-control3.ll +++ llvm/test/CodeGen/X86/tls-loads-control3.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --tls-load-hoist=optimize -o - %s | FileCheck %s --check-prefix=HOIST0 -; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --tls-load-hoist=non-optimize -o - %s | FileCheck %s --check-prefix=HOIST2 +; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic --tls-load-hoist=true -o - %s | FileCheck %s --check-prefix=HOIST0 ; RUN: llc -mtriple=x86_64-unknown-unknown -O2 --relocation-model=pic -o - %s | FileCheck %s --check-prefix=HOIST2 ; This test has no module flag {"tls-load-hoist", i32 0}, so use --tls-load-hoist=x