RE: r357610 - Bug-40323: MS ABI adding template static member in the linker directive section to make sure init function can be called before main.

2019-04-11 Thread Yu, Jennifer via cfe-commits
Thank you so much.  Jennifer

From: Nico Weber [mailto:tha...@chromium.org]
Sent: Thursday, April 11, 2019 2:25 PM
To: Yu, Jennifer 
Cc: cfe-commits 
Subject: Re: r357610 - Bug-40323: MS ABI adding template static member in the 
linker directive section to make sure init function can be called before main.

Done in 358232. Thanks!

On Thu, Apr 11, 2019 at 5:19 PM Yu, Jennifer 
mailto:jennifer...@intel.com>> wrote:
Hi Nico,

Iet’s revert it now.  I will try to re-submit latter.
Thanks.
Jennifer

From: Nico Weber [mailto:tha...@chromium.org]
Sent: Thursday, April 11, 2019 2:04 PM
To: Yu, Jennifer mailto:jennifer...@intel.com>>
Cc: cfe-commits mailto:cfe-commits@lists.llvm.org>>
Subject: Re: r357610 - Bug-40323: MS ABI adding template static member in the 
linker directive section to make sure init function can be called before main.

Hi Jennifer,

this caused https://bugs.llvm.org/show_bug.cgi?id=41471

Do you think this is easy to fix, or should we revert for now?

Thanks,
Nico

On Wed, Apr 3, 2019 at 1:20 PM Jennifer Yu via cfe-commits 
mailto:cfe-commits@lists.llvm.org>> wrote:
Author: jyu2
Date: Wed Apr  3 10:21:40 2019
New Revision: 357610

URL: http://llvm.org/viewvc/llvm-project?rev=357610=rev
Log:
Bug-40323: MS ABI adding template static member in the linker directive section 
to make sure init function can be called before main.

Added:
cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDeclCXX.cpp

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=357610=357609=357610=diff
==
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed Apr  3 10:21:40 2019
@@ -481,6 +481,12 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
 // 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()) {
+  // In The MS C++, MS add template static data member in the linker
+  // drective.
+  assert(COMDATKey);
+  addUsedGlobal(COMDATKey);
+}
   } else if (D->hasAttr()) {
 // SelectAny globals will be comdat-folded. Put the initializer into a
 // COMDAT group associated with the global, so the initializers get folded

Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp?rev=357610=auto
==
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp Wed Apr  3 
10:21:40 2019
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | 
FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - 
| FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm 
-o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions 
-emit-llvm -o - | FileCheck %s
+
+struct S {
+  S();
+  ~S();
+};
+
+template  struct __declspec(dllexport) ExportedTemplate {
+  static S s;
+};
+template  S ExportedTemplate::s;
+void useExportedTemplate(ExportedTemplate x) {
+  (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+}
+
+namespace explicit_template_instantiation {
+template  struct A { static  int x; };
+template  int A::x = f();
+template struct A;
+}
+
+namespace implicit_template_instantiation {
+template  struct A { static  int x; };
+template   int A::x = f();
+int g() { return A::x; }
+}
+
+
+template 
+struct X_ {
+  static T ioo;
+  static T init();
+};
+template  T X_::ioo = X_::init();
+template struct X_;
+
+template 
+struct X {
+  static T ioo;
+  static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X::ioo = X::init();
+template struct X;
+// CHECK: @llvm.global_ctors = appending global [6 x { i32, void ()*, i8* }] 
[{ i32, void ()*, i8* } { i32 65535, void ()* @"??__Ex@selectany_init@@YAXXZ", 
i8* bitcast (i32* @"?x@selectany_init@@3HA" to i8*) }, { i32, void ()*, i8* } { 
i32 65535, void ()* 
@"??__E?x@?$A@H@explicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*, 
i8* } { i32 65535, void ()* @"??__E?ioo@?$X_@H@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?ioo@?$X_@H@@2HA" to i8*) }, { i32, void ()*, i8* } 

Re: r357610 - Bug-40323: MS ABI adding template static member in the linker directive section to make sure init function can be called before main.

2019-04-11 Thread Nico Weber via cfe-commits
Done in 358232. Thanks!

On Thu, Apr 11, 2019 at 5:19 PM Yu, Jennifer  wrote:

> Hi Nico,
>
>
>
> Iet’s revert it now.  I will try to re-submit latter.
>
> Thanks.
>
> Jennifer
>
>
>
> *From:* Nico Weber [mailto:tha...@chromium.org]
> *Sent:* Thursday, April 11, 2019 2:04 PM
> *To:* Yu, Jennifer 
> *Cc:* cfe-commits 
> *Subject:* Re: r357610 - Bug-40323: MS ABI adding template static member
> in the linker directive section to make sure init function can be called
> before main.
>
>
>
> Hi Jennifer,
>
>
>
> this caused https://bugs.llvm.org/show_bug.cgi?id=41471
>
>
> Do you think this is easy to fix, or should we revert for now?
>
>
>
> Thanks,
>
> Nico
>
>
>
> On Wed, Apr 3, 2019 at 1:20 PM Jennifer Yu via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
> Author: jyu2
> Date: Wed Apr  3 10:21:40 2019
> New Revision: 357610
>
> URL: http://llvm.org/viewvc/llvm-project?rev=357610=rev
> Log:
> Bug-40323: MS ABI adding template static member in the linker directive
> section to make sure init function can be called before main.
>
> Added:
> cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
> Modified:
> cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=357610=357609=357610=diff
>
> ==
> --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed Apr  3 10:21:40 2019
> @@ -481,6 +481,12 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
>  // 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()) {
> +  // In The MS C++, MS add template static data member in the linker
> +  // drective.
> +  assert(COMDATKey);
> +  addUsedGlobal(COMDATKey);
> +}
>} else if (D->hasAttr()) {
>  // SelectAny globals will be comdat-folded. Put the initializer into a
>  // COMDAT group associated with the global, so the initializers get
> folded
>
> Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp?rev=357610=auto
>
> ==
> --- cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
> (added)
> +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp Wed
> Apr  3 10:21:40 2019
> @@ -0,0 +1,57 @@
> +// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o
> - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm
> -o - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions
> -emit-llvm -o - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions
> -emit-llvm -o - | FileCheck %s
> +
> +struct S {
> +  S();
> +  ~S();
> +};
> +
> +template  struct __declspec(dllexport) ExportedTemplate {
> +  static S s;
> +};
> +template  S ExportedTemplate::s;
> +void useExportedTemplate(ExportedTemplate x) {
> +  (void)x.s;
> +}
> +int f();
> +namespace selectany_init {
> +// MS don't put selectany static var in the linker directive, init routine
> +// f() is not getting called if x is not referenced.
> +int __declspec(selectany) x = f();
> +}
> +
> +namespace explicit_template_instantiation {
> +template  struct A { static  int x; };
> +template  int A::x = f();
> +template struct A;
> +}
> +
> +namespace implicit_template_instantiation {
> +template  struct A { static  int x; };
> +template   int A::x = f();
> +int g() { return A::x; }
> +}
> +
> +
> +template 
> +struct X_ {
> +  static T ioo;
> +  static T init();
> +};
> +template  T X_::ioo = X_::init();
> +template struct X_;
> +
> +template 
> +struct X {
> +  static T ioo;
> +  static T init();
> +};
> +// template specialized static data don't need in llvm.used,
> +// the static init routine get call from _GLOBAL__sub_I_ routines.
> +template <> int X::ioo = X::init();
> +template struct X;
> +// CHECK: @llvm.global_ctors = appending global [6 x { i32, void ()*, i8*
> }] [{ i32, void ()*, i8* } { i32 65535, void ()* 
> @"??__Ex@selectany_init@@YAXXZ",
> i8* bitcast (i32* @"?x@selectany_init@@3HA" to i8*) }, { i32, void ()*,
> i8* } { i32 65535, void ()* @"??__E?x@?$A@H
> @explicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* @"?x@
> ?$A@H@explicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*,
> i8* } { i32 65535, void ()* @"??__E?ioo@?$X_@H@@2HA@@YAXXZ", i8* bitcast
> (i32* @"?ioo@?$X_@H@@2HA" to i8*) }, { i32, void ()*, i8* } { i32 65535,
> void ()* @"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8*
> getelementptr inbounds (%struct.S, %struct.S* 

RE: r357610 - Bug-40323: MS ABI adding template static member in the linker directive section to make sure init function can be called before main.

2019-04-11 Thread Yu, Jennifer via cfe-commits
Hi Nico,

Iet’s revert it now.  I will try to re-submit latter.
Thanks.
Jennifer

From: Nico Weber [mailto:tha...@chromium.org]
Sent: Thursday, April 11, 2019 2:04 PM
To: Yu, Jennifer 
Cc: cfe-commits 
Subject: Re: r357610 - Bug-40323: MS ABI adding template static member in the 
linker directive section to make sure init function can be called before main.

Hi Jennifer,

this caused https://bugs.llvm.org/show_bug.cgi?id=41471

Do you think this is easy to fix, or should we revert for now?

Thanks,
Nico

On Wed, Apr 3, 2019 at 1:20 PM Jennifer Yu via cfe-commits 
mailto:cfe-commits@lists.llvm.org>> wrote:
Author: jyu2
Date: Wed Apr  3 10:21:40 2019
New Revision: 357610

URL: http://llvm.org/viewvc/llvm-project?rev=357610=rev
Log:
Bug-40323: MS ABI adding template static member in the linker directive section 
to make sure init function can be called before main.

Added:
cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDeclCXX.cpp

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=357610=357609=357610=diff
==
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed Apr  3 10:21:40 2019
@@ -481,6 +481,12 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
 // 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()) {
+  // In The MS C++, MS add template static data member in the linker
+  // drective.
+  assert(COMDATKey);
+  addUsedGlobal(COMDATKey);
+}
   } else if (D->hasAttr()) {
 // SelectAny globals will be comdat-folded. Put the initializer into a
 // COMDAT group associated with the global, so the initializers get folded

Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp?rev=357610=auto
==
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp Wed Apr  3 
10:21:40 2019
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | 
FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - 
| FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm 
-o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions 
-emit-llvm -o - | FileCheck %s
+
+struct S {
+  S();
+  ~S();
+};
+
+template  struct __declspec(dllexport) ExportedTemplate {
+  static S s;
+};
+template  S ExportedTemplate::s;
+void useExportedTemplate(ExportedTemplate x) {
+  (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+}
+
+namespace explicit_template_instantiation {
+template  struct A { static  int x; };
+template  int A::x = f();
+template struct A;
+}
+
+namespace implicit_template_instantiation {
+template  struct A { static  int x; };
+template   int A::x = f();
+int g() { return A::x; }
+}
+
+
+template 
+struct X_ {
+  static T ioo;
+  static T init();
+};
+template  T X_::ioo = X_::init();
+template struct X_;
+
+template 
+struct X {
+  static T ioo;
+  static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X::ioo = X::init();
+template struct X;
+// CHECK: @llvm.global_ctors = appending global [6 x { i32, void ()*, i8* }] 
[{ i32, void ()*, i8* } { i32 65535, void ()* @"??__Ex@selectany_init@@YAXXZ", 
i8* bitcast (i32* @"?x@selectany_init@@3HA" to i8*) }, { i32, void ()*, i8* } { 
i32 65535, void ()* 
@"??__E?x@?$A@H@explicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*, 
i8* } { i32 65535, void ()* @"??__E?ioo@?$X_@H@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?ioo@?$X_@H@@2HA" to i8*) }, { i32, void ()*, i8* } { i32 65535, void ()* 
@"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8* getelementptr inbounds 
(%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) }, { 
i32, void ()*, i8* } { i32 65535, void ()* 
@"??__E?x@?$A@H@implicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*, 
i8* } { i32 65535, void ()* 
@_GLOBAL__sub_I_microsoft_abi_template_static_init.cpp, i8* null }]
+// CHECK: @llvm.used = appending 

Re: r357610 - Bug-40323: MS ABI adding template static member in the linker directive section to make sure init function can be called before main.

2019-04-11 Thread Nico Weber via cfe-commits
Hi Jennifer,

this caused https://bugs.llvm.org/show_bug.cgi?id=41471

Do you think this is easy to fix, or should we revert for now?

Thanks,
Nico

On Wed, Apr 3, 2019 at 1:20 PM Jennifer Yu via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: jyu2
> Date: Wed Apr  3 10:21:40 2019
> New Revision: 357610
>
> URL: http://llvm.org/viewvc/llvm-project?rev=357610=rev
> Log:
> Bug-40323: MS ABI adding template static member in the linker directive
> section to make sure init function can be called before main.
>
> Added:
> cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
> Modified:
> cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=357610=357609=357610=diff
>
> ==
> --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed Apr  3 10:21:40 2019
> @@ -481,6 +481,12 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
>  // 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()) {
> +  // In The MS C++, MS add template static data member in the linker
> +  // drective.
> +  assert(COMDATKey);
> +  addUsedGlobal(COMDATKey);
> +}
>} else if (D->hasAttr()) {
>  // SelectAny globals will be comdat-folded. Put the initializer into a
>  // COMDAT group associated with the global, so the initializers get
> folded
>
> Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp?rev=357610=auto
>
> ==
> --- cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
> (added)
> +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-template-static-init.cpp Wed
> Apr  3 10:21:40 2019
> @@ -0,0 +1,57 @@
> +// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o
> - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm
> -o - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions
> -emit-llvm -o - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions
> -emit-llvm -o - | FileCheck %s
> +
> +struct S {
> +  S();
> +  ~S();
> +};
> +
> +template  struct __declspec(dllexport) ExportedTemplate {
> +  static S s;
> +};
> +template  S ExportedTemplate::s;
> +void useExportedTemplate(ExportedTemplate x) {
> +  (void)x.s;
> +}
> +int f();
> +namespace selectany_init {
> +// MS don't put selectany static var in the linker directive, init routine
> +// f() is not getting called if x is not referenced.
> +int __declspec(selectany) x = f();
> +}
> +
> +namespace explicit_template_instantiation {
> +template  struct A { static  int x; };
> +template  int A::x = f();
> +template struct A;
> +}
> +
> +namespace implicit_template_instantiation {
> +template  struct A { static  int x; };
> +template   int A::x = f();
> +int g() { return A::x; }
> +}
> +
> +
> +template 
> +struct X_ {
> +  static T ioo;
> +  static T init();
> +};
> +template  T X_::ioo = X_::init();
> +template struct X_;
> +
> +template 
> +struct X {
> +  static T ioo;
> +  static T init();
> +};
> +// template specialized static data don't need in llvm.used,
> +// the static init routine get call from _GLOBAL__sub_I_ routines.
> +template <> int X::ioo = X::init();
> +template struct X;
> +// CHECK: @llvm.global_ctors = appending global [6 x { i32, void ()*, i8*
> }] [{ i32, void ()*, i8* } { i32 65535, void ()* 
> @"??__Ex@selectany_init@@YAXXZ",
> i8* bitcast (i32* @"?x@selectany_init@@3HA" to i8*) }, { i32, void ()*,
> i8* } { i32 65535, void ()* @"??__E?x@?$A@H
> @explicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* @"?x@
> ?$A@H@explicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*,
> i8* } { i32 65535, void ()* @"??__E?ioo@?$X_@H@@2HA@@YAXXZ", i8* bitcast
> (i32* @"?ioo@?$X_@H@@2HA" to i8*) }, { i32, void ()*, i8* } { i32 65535,
> void ()* @"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8*
> getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H
> @@2US@@A", i32 0, i32 0) }, { i32, void ()*, i8* } { i32 65535, void ()*
> @"??__E?x@?$A@H@implicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast
> (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*) }, { i32,
> void ()*, i8* } { i32 65535, void ()*
> @_GLOBAL__sub_I_microsoft_abi_template_static_init.cpp, i8* null }]
> +// CHECK: @llvm.used = appending global [4 x i8*] [i8* bitcast (i32* @"?x@
> ?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32*
> @"?ioo@?$X_@H@@2HA" to