Index: cp/decl2.c
===================================================================
--- cp/decl2.c  (revision 221425)
+++ cp/decl2.c  (working copy)
@@ -3033,9 +3033,15 @@ get_local_tls_init_fn (void)
                                                  void_list_node));
       SET_DECL_LANGUAGE (fn, lang_c);
       TREE_PUBLIC (fn) = false;
+      TREE_STATIC (fn) = true;
       DECL_ARTIFICIAL (fn) = true;
       mark_used (fn);
       SET_IDENTIFIER_GLOBAL_VALUE (sname, fn);
+      /* In LIPO mode make sure we record the new global value so that it
+         is cleared before parsing the next aux module.  */
+      if (L_IPO_COMP_MODE && !is_parsing_done_p ())
+        add_decl_to_current_module_scope (fn,
+                                          NAMESPACE_LEVEL (global_namespace));
     }
   return fn;
 }
@@ -3100,6 +3106,11 @@ get_tls_init_fn (tree var)
       DECL_BEFRIENDING_CLASSES (fn) = var;

       SET_IDENTIFIER_GLOBAL_VALUE (sname, fn);
+      /* In LIPO mode make sure we record the new global value so that it
+         is cleared before parsing the next aux module.  */
+      if (L_IPO_COMP_MODE && !is_parsing_done_p ())
+        add_decl_to_current_module_scope (fn,
+                                          NAMESPACE_LEVEL (global_namespace));
     }
   return fn;
 }
@@ -3157,6 +3168,11 @@ get_tls_wrapper_fn (tree var)
       DECL_BEFRIENDING_CLASSES (fn) = var;

       SET_IDENTIFIER_GLOBAL_VALUE (sname, fn);
+      /* In LIPO mode make sure we record the new global value so that it
+         is cleared before parsing the next aux module.  */
+      if (L_IPO_COMP_MODE && !is_parsing_done_p ())
+        add_decl_to_current_module_scope (fn,
+                                          NAMESPACE_LEVEL (global_namespace));
     }
   return fn;
 }
@@ -4213,8 +4229,12 @@ handle_tls_init (void)
       one_static_initialization_or_destruction (var, init, true);

 #ifdef ASM_OUTPUT_DEF
-      /* Output init aliases even with -fno-extern-tls-init.  */
-      if (TREE_PUBLIC (var))
+      /* Output init aliases even with -fno-extern-tls-init.  Don't emit
+         aliases in LIPO aux modules, since the corresponding __tls_init
+         will be static promoted and deleted, so the variable's tls init
+         function will be resolved by its own primary module.  An alias
+         would prevent the promoted aux __tls_init from being deleted.  */
+      if (TREE_PUBLIC (var) && !L_IPO_IS_AUXILIARY_MODULE)
        {
           tree single_init_fn = get_tls_init_fn (var);
          if (single_init_fn == NULL_TREE)
Index: l-ipo.c
===================================================================
--- l-ipo.c     (revision 221425)
+++ l-ipo.c     (working copy)
@@ -1120,6 +1120,27 @@ cgraph_unify_type_alias_sets (void)
   htab_delete (type_hash_tab);
 }

+/* Return true if DECL is an artificial function that we do not want
+   to promote and which may not be available in the primary module.
+   The sole exception is currently __tls_init.  */
+
+static bool
+decl_artificial_nopromote (tree decl)
+{
+  if (!DECL_ARTIFICIAL (decl))
+    return false;
+
+  /* Handle the __tls_init function specially as we do want to promote it and
+     allow the aux module to be resolved to the version in the primary module.
+     We check if it is prefixed by __tls_init to catch it after promotion
+     as well from cgraph_is_aux_decl_external.  */
+  if (!strncmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "__tls_init",
+                10))
+    return false;
+
+  return true;
+}
+
 /* Return true if NODE->decl from an auxiliary module has external
    definition (and therefore is not needed for expansion).  */

@@ -1144,7 +1165,7 @@ cgraph_is_aux_decl_external (struct cgraph_node *n
      Functions marked artificial (e.g. an implicitly instantiated virtual
      destructor) are also not guaranteed to be available in the primary module,
      as they are not promoted by process_module_scope_static_func.  */
-  if (DECL_COMDAT (decl) || DECL_WEAK (decl) || DECL_ARTIFICIAL (decl))
+  if (DECL_COMDAT (decl) || DECL_WEAK (decl) ||
decl_artificial_nopromote (decl))
     return false;

   /* virtual functions won't be deleted in the primary module.  */
@@ -2022,7 +2043,7 @@ process_module_scope_static_func (struct cgraph_no
   if (TREE_PUBLIC (decl)
       || !TREE_STATIC (decl)
       || DECL_EXTERNAL (decl)
-      || DECL_ARTIFICIAL (decl))
+      || decl_artificial_nopromote (decl))
     return;

   if (flag_ripa_no_promote_always_inline
Index: testsuite/g++.dg/tree-prof/lipo/tls.h
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/tls.h       (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/tls.h       (working copy)
@@ -0,0 +1,16 @@
+extern int NextId();
+
+class TLSClass {
+ public:
+  TLSClass() {
+    id = NextId();
+    bar = 1;
+  }
+  ~TLSClass() {}
+  int id;
+  int bar;
+};
+extern TLSClass* NextTLSClass();
+extern void *SetTLSClass(TLSClass *a);
+extern TLSClass *GetTLSClass();
+extern thread_local TLSClass* current_tls_;
Index: testsuite/g++.dg/tree-prof/lipo/tls2.h
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/tls2.h      (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/tls2.h      (working copy)
@@ -0,0 +1,15 @@
+extern int NextId();
+
+class TLSClass {
+ public:
+  TLSClass() {
+    id = NextId();
+    bar = 1;
+  }
+  ~TLSClass() {}
+  int id;
+  int bar;
+};
+extern TLSClass* NextTLSClass();
+extern void *SetTLSClass(TLSClass *a);
+extern TLSClass *GetTLSClass();
Index: testsuite/g++.dg/tree-prof/lipo/tls2_0.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/tls2_0.C    (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/tls2_0.C    (working copy)
@@ -0,0 +1,10 @@
+// { dg-options "-std=c++11 -O2 --param=lipo-sampling-period=1" }
+#include "tls2.h"
+
+static thread_local TLSClass* current_tls_ = NextTLSClass();
+void *SetTLSClass(TLSClass *a) {
+  current_tls_ = a;
+}
+TLSClass *GetTLSClass() {
+  return current_tls_;
+}
Index: testsuite/g++.dg/tree-prof/lipo/tls2_1.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/tls2_1.C    (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/tls2_1.C    (working copy)
@@ -0,0 +1,31 @@
+// { dg-options "-std=c++11 -O2 --param=lipo-sampling-period=1" }
+#include <stdio.h>
+#include <stdlib.h>
+#include <new>
+#include "tls2.h"
+TLSClass* NextTLSClass() {
+  return new TLSClass();
+}
+int NextId() {
+  static int id = 0;
+  return id++;
+}
+static thread_local TLSClass* current_tls2_ = NextTLSClass();
+void *SetTLSClass2(TLSClass *a) {
+  current_tls2_ = a;
+}
+int main() {
+  int i = 0;
+  if (GetTLSClass()->id != i++)
+    abort();
+  TLSClass *A = NextTLSClass();
+  SetTLSClass(A);
+  if (GetTLSClass()->id != i++)
+    abort();
+  if (current_tls2_->id != i++)
+    abort();
+  A = NextTLSClass();
+  SetTLSClass2(A);
+  if (current_tls2_->id != i++)
+    abort();
+}
Index: testsuite/g++.dg/tree-prof/lipo/tls_0.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/tls_0.C     (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/tls_0.C     (working copy)
@@ -0,0 +1,10 @@
+// { dg-options "-std=c++11 -O2 --param=lipo-sampling-period=1" }
+#include "tls.h"
+
+thread_local TLSClass* current_tls_ = NextTLSClass();
+void *SetTLSClass(TLSClass *a) {
+  current_tls_ = a;
+}
+TLSClass *GetTLSClass() {
+  return current_tls_;
+}
Index: testsuite/g++.dg/tree-prof/lipo/tls_1.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/tls_1.C     (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/tls_1.C     (working copy)
@@ -0,0 +1,38 @@
+// { dg-options "-std=c++11 -O2 --param=lipo-sampling-period=1" }
+#include <stdio.h>
+#include <stdlib.h>
+#include <new>
+#include "tls.h"
+TLSClass* NextTLSClass() {
+  return new TLSClass();
+}
+int NextId() {
+  static int id = 0;
+  return id++;
+}
+void *SetTLSClassHere(TLSClass *a) {
+  current_tls_ = a;
+}
+thread_local TLSClass* current_tls2_ = NextTLSClass();
+void *SetTLSClass2(TLSClass *a) {
+  current_tls2_ = a;
+}
+int main() {
+  int i = 0;
+  if (GetTLSClass()->id != i++)
+    abort();
+  TLSClass *A = NextTLSClass();
+  SetTLSClass(A);
+  if (GetTLSClass()->id != i++)
+    abort();
+  A = NextTLSClass();
+  SetTLSClassHere(A);
+  if (GetTLSClass()->id != i++)
+    abort();
+  if (current_tls2_->id != i++)
+    abort();
+  A = NextTLSClass();
+  SetTLSClass2(A);
+  if (current_tls2_->id != i++)
+    abort();
+}
