Index: clang/lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -517,19 +517,24 @@
     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
   } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
              getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR) {
-    // C++ [basic.start.init]p2:
-    //   Definitions of explicitly specialized class template static data
-    //   members have ordered initialization. Other class template static data
-    //   members (i.e., implicitly or explicitly instantiated specializations)
-    //   have unordered initialization.
-    //
-    // As a consequence, we can put them into their own llvm.global_ctors entry.
-    //
-    // If the global is externally visible, put the initializer into a COMDAT
-    // group with the global being initialized.  On most platforms, this is a
-    // minor startup time optimization.  In the MS C++ ABI, there are no guard
-    // variables, so this COMDAT key is required for correctness.
-    AddGlobalCtor(Fn, 65535, COMDATKey);
+    if (getCXXABI().useSinitAndSterm())
+      CXXGlobalInits.push_back(Fn);
+    else
+      // C++ [basic.start.init]p2:
+      //   Definitions of explicitly specialized class template static data
+      //   members have ordered initialization. Other class template static
+      //   data members (i.e., implicitly or explicitly instantiated
+      //   specializations) have unordered initialization.
+      //
+      // As a consequence, we can put them into their own llvm.global_ctors
+      // entry.
+      //
+      // If the global is externally visible, put the initializer into a COMDAT
+      // group with the global being initialized.  On most platforms, this is a
+      // minor startup time optimization.  In the MS C++ ABI, there are no guard
+      // variables, so this COMDAT key is required for correctness.
+      AddGlobalCtor(Fn, 65535, COMDATKey);
+
     if (getTarget().getCXXABI().isMicrosoft() && COMDATKey) {
       // In The MS C++, MS add template static data member in the linker
       // drective.
Index: clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
@@ -0,0 +1,238 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN:     -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN:     -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+    Test1(int) {}
+    ~Test1() {}
+  };
+
+  Test1 t0 = 2;
+  template <typename T> Test1 t1 = 2;
+  inline Test1 t2 = 2;
+
+  void foo() {
+    (void) &t1<int>;
+  }
+} // namespace test1
+
+namespace test2 {
+  template <typename = void>
+  struct A {
+    A() {}
+    ~A() {}
+    static A instance;
+  };
+
+  template <typename T> A<T> A<T>::instance;
+  template A<> A<>::instance;
+
+  A<int> &bar() { 
+    A<int> *a = new A<int>;
+    return *a;
+  }
+  template<> A<int> A<int>::instance = bar();
+} // namespace test2
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit80000000_clang_32add9385a76444cd9d0fab0fb83307b, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm80000000_clang_32add9385a76444cd9d0fab0fb83307b, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t0E, i32 2)
+// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t0E, i32 signext 2)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t0E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t0E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t0E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t0E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t0E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t0E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+ //CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = load atomic i8, i8* bitcast (i64* @_ZGVN5test12t2E to i8*) acquire
+// CHECK:   %guard.uninitialized = icmp eq i8 %0, 0
+// CHECK:   br i1 %guard.uninitialized, label %init.check, label %init.end
+
+// CHECK: init.check:
+ //CHECK:   %1 = call i32 @__cxa_guard_acquire(i64* @_ZGVN5test12t2E)
+// CHECK:   %tobool = icmp ne i32 %1, 0
+// CHECK:   br i1 %tobool, label %init, label %init.end
+
+// CHECK: init:
+// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t2E, i32 2)
+// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t2E, i32 signext 2)
+// CHECK:   %2 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   call void @__cxa_guard_release(i64* @_ZGVN5test12t2E)
+// CHECK:   br label %init.end
+
+// CHECK: init.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = load i8, i8* bitcast (i64* @_ZGVN5test21AIvE8instanceE to i8*)
+// CHECK:   %guard.uninitialized = icmp eq i8 %0, 0
+// CHECK:   br i1 %guard.uninitialized, label %init.check, label %init.end
+
+// CHECK: init.check:
+// CHECK:   call void @_ZN5test21AIvEC1Ev(%"struct.test2::A"* @_ZN5test21AIvE8instanceE)
+// CHECK:   %1 = call i32 @atexit(void ()* @__dtor__ZN5test21AIvE8instanceE) #2
+// CHECK:   store i64 1, i64* @_ZGVN5test21AIvE8instanceE, align 8
+// CHECK:   br label %init.end
+
+// CHECK: init.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test21AIvE8instanceE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test21AIvED1Ev(%"struct.test2::A"* @_ZN5test21AIvE8instanceE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test21AIvE8instanceE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test21AIvE8instanceE)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test21AIvE8instanceE()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %call = call nonnull align 1 dereferenceable(1) %"struct.test2::A.0"* @_ZN5test23barEv()
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test21AIiE8instanceE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test21AIiE8instanceE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test21AIiED1Ev(%"struct.test2::A.0"* @_ZN5test21AIiE8instanceE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test21AIiE8instanceE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test21AIiE8instanceE)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test21AIiE8instanceE()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.4() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = load i8, i8* bitcast (i64* @_ZGVN5test12t1IiEE to i8*)
+// CHECK:   %guard.uninitialized = icmp eq i8 %0, 0
+// CHECK:   br i1 %guard.uninitialized, label %init.check, label %init.end
+
+// CHECK: init.check:
+// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t1IiEE, i32 2)
+// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t1IiEE, i32 signext 2)
+// CHECK:   %1 = call i32 @atexit(void ()* @__dtor__ZN5test12t1IiEE)
+// CHECK:   store i64 1, i64* @_ZGVN5test12t1IiEE
+// CHECK:   br label %init.end
+
+// CHECK: init.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1IiEE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1IiEE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t1IiEE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1IiEE)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1IiEE()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define void @__sinit80000000_clang_32add9385a76444cd9d0fab0fb83307b() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   call void @__cxx_global_var_init.1()
+// CHECK:   call void @__cxx_global_var_init.2()
+// CHECK:   call void @__cxx_global_var_init.3()
+// CHECK:   call void @__cxx_global_var_init.4()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: ; Function Attrs: nounwind
+// CHECK: define void @__sterm80000000_clang_32add9385a76444cd9d0fab0fb83307b() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__finalize__ZN5test12t1IiEE()
+// CHECK:   call void @__finalize__ZN5test21AIiE8instanceE()
+// CHECK:   call void @__finalize__ZN5test21AIvE8instanceE()
+// CHECK:   call void @__finalize__ZN5test12t2E()
+// CHECK:   call void @__finalize__ZN5test12t0E()
+// CHECK:   ret void
+// CHECK: }