summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/GlobalOpt
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/GlobalOpt')
-rw-r--r--llvm/test/Transforms/GlobalOpt/2004-10-10-CastStoreOnce.ll17
-rw-r--r--llvm/test/Transforms/GlobalOpt/2005-06-15-LocalizeConstExprCrash.ll10
-rw-r--r--llvm/test/Transforms/GlobalOpt/2005-09-27-Crash.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/2006-07-07-InlineAsmCrash.ll135
-rw-r--r--llvm/test/Transforms/GlobalOpt/2006-11-01-ShrinkGlobalPhiCrash.ll33
-rw-r--r--llvm/test/Transforms/GlobalOpt/2007-04-05-Crash.ll34
-rw-r--r--llvm/test/Transforms/GlobalOpt/2007-05-13-Crash.ll74
-rw-r--r--llvm/test/Transforms/GlobalOpt/2007-06-04-PackedStruct.ll36
-rw-r--r--llvm/test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll19
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-01-03-Crash.ll26
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll18
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll10
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-04-26-SROA-Global-Align.ll34
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash-2.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash.ll30
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-01-13-phi-user.ll36
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll10
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll24
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-03-05-dbg.ll80
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-03-06-Anonymous.ll23
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-03-07-PromotePtrToBool.ll19
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll122
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll26
-rw-r--r--llvm/test/Transforms/GlobalOpt/2009-11-16-MallocSingleStoreToGlobalVar.ll30
-rw-r--r--llvm/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll18
-rw-r--r--llvm/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/2010-10-19-WeakOdr.ll16
-rw-r--r--llvm/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll5
-rw-r--r--llvm/test/Transforms/GlobalOpt/2012-05-11-blockaddress.ll16
-rw-r--r--llvm/test/Transforms/GlobalOpt/GSROA-section.ll30
-rw-r--r--llvm/test/Transforms/GlobalOpt/MallocSROA-section-no-null-opt.ll34
-rw-r--r--llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/PowerPC/coldcc_coldsites.ll81
-rw-r--r--llvm/test/Transforms/GlobalOpt/PowerPC/lit.local.cfg3
-rw-r--r--llvm/test/Transforms/GlobalOpt/SROA-section.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/alias-resolve.ll46
-rw-r--r--llvm/test/Transforms/GlobalOpt/alias-used-address-space.ll26
-rw-r--r--llvm/test/Transforms/GlobalOpt/alias-used-section.ll8
-rw-r--r--llvm/test/Transforms/GlobalOpt/alias-used.ll66
-rw-r--r--llvm/test/Transforms/GlobalOpt/amdgcn-ctor-alloca.ll17
-rw-r--r--llvm/test/Transforms/GlobalOpt/array-elem-refs.ll32
-rw-r--r--llvm/test/Transforms/GlobalOpt/assume.ll21
-rw-r--r--llvm/test/Transforms/GlobalOpt/atexit.ll6
-rw-r--r--llvm/test/Transforms/GlobalOpt/atomic.ll25
-rw-r--r--llvm/test/Transforms/GlobalOpt/available_externally_global_ctors.ll22
-rw-r--r--llvm/test/Transforms/GlobalOpt/basictest.ll10
-rw-r--r--llvm/test/Transforms/GlobalOpt/blockaddress.ll23
-rw-r--r--llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll49
-rw-r--r--llvm/test/Transforms/GlobalOpt/coldcc_stress_test.ll48
-rw-r--r--llvm/test/Transforms/GlobalOpt/compiler-used.ll16
-rw-r--r--llvm/test/Transforms/GlobalOpt/constantexpr-dangle.ll12
-rw-r--r--llvm/test/Transforms/GlobalOpt/constantfold-initializers.ll103
-rw-r--r--llvm/test/Transforms/GlobalOpt/crash-2.ll19
-rw-r--r--llvm/test/Transforms/GlobalOpt/crash.ll80
-rw-r--r--llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll34
-rw-r--r--llvm/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll23
-rw-r--r--llvm/test/Transforms/GlobalOpt/ctor-list-opt.ll115
-rw-r--r--llvm/test/Transforms/GlobalOpt/cxx-dtor.ll33
-rw-r--r--llvm/test/Transforms/GlobalOpt/deaddeclaration.ll7
-rw-r--r--llvm/test/Transforms/GlobalOpt/deadfunction.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/deadglobal-2.ll11
-rw-r--r--llvm/test/Transforms/GlobalOpt/deadglobal.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/evaluate-bitcast.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/evaluate-call-errors.ll99
-rw-r--r--llvm/test/Transforms/GlobalOpt/evaluate-call.ll87
-rw-r--r--llvm/test/Transforms/GlobalOpt/evaluate-constfold-call.ll55
-rw-r--r--llvm/test/Transforms/GlobalOpt/externally-initialized-aggregate.ll50
-rw-r--r--llvm/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll35
-rw-r--r--llvm/test/Transforms/GlobalOpt/externally-initialized.ll37
-rw-r--r--llvm/test/Transforms/GlobalOpt/fastcc.ll55
-rw-r--r--llvm/test/Transforms/GlobalOpt/global-demotion.ll80
-rw-r--r--llvm/test/Transforms/GlobalOpt/globalsra-multigep.ll16
-rw-r--r--llvm/test/Transforms/GlobalOpt/globalsra-partial.ll25
-rw-r--r--llvm/test/Transforms/GlobalOpt/globalsra-unknown-index.ll54
-rw-r--r--llvm/test/Transforms/GlobalOpt/globalsra.ll45
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-1-no-null-opt.ll40
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-1.ll45
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-2-no-null-opt.ll39
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-2.ll45
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-3-no-null-opt.ll41
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-3.ll46
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-4-no-null-opt.ll44
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-4.ll47
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-phi-no-null-opt.ll54
-rw-r--r--llvm/test/Transforms/GlobalOpt/heap-sra-phi.ll52
-rw-r--r--llvm/test/Transforms/GlobalOpt/int_sideeffect.ll16
-rw-r--r--llvm/test/Transforms/GlobalOpt/integer-bool-dwarf.ll61
-rw-r--r--llvm/test/Transforms/GlobalOpt/integer-bool.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/invariant-nodatalayout.ll17
-rw-r--r--llvm/test/Transforms/GlobalOpt/invariant.group.ll79
-rw-r--r--llvm/test/Transforms/GlobalOpt/invariant.ll59
-rw-r--r--llvm/test/Transforms/GlobalOpt/invoke.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/iterate.ll11
-rw-r--r--llvm/test/Transforms/GlobalOpt/load-store-global-no-null-opt.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/load-store-global.ll38
-rw-r--r--llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll70
-rw-r--r--llvm/test/Transforms/GlobalOpt/localize-constexpr.ll28
-rw-r--r--llvm/test/Transforms/GlobalOpt/malloc-promote-1-no-null-opt.ll31
-rw-r--r--llvm/test/Transforms/GlobalOpt/malloc-promote-1.ll32
-rw-r--r--llvm/test/Transforms/GlobalOpt/malloc-promote-2-no-null-opt.ll24
-rw-r--r--llvm/test/Transforms/GlobalOpt/malloc-promote-2.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/malloc-promote-3.ll18
-rw-r--r--llvm/test/Transforms/GlobalOpt/memcpy.ll13
-rw-r--r--llvm/test/Transforms/GlobalOpt/memset-null.ll29
-rw-r--r--llvm/test/Transforms/GlobalOpt/memset.ll31
-rw-r--r--llvm/test/Transforms/GlobalOpt/metadata.ll32
-rw-r--r--llvm/test/Transforms/GlobalOpt/musttail_cc.ll34
-rw-r--r--llvm/test/Transforms/GlobalOpt/naked_functions.ll23
-rw-r--r--llvm/test/Transforms/GlobalOpt/phi-select.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/pr21191.ll19
-rw-r--r--llvm/test/Transforms/GlobalOpt/pr33686.ll17
-rw-r--r--llvm/test/Transforms/GlobalOpt/preserve-comdats.ll37
-rw-r--r--llvm/test/Transforms/GlobalOpt/shrink-address-to-bool.ll46
-rw-r--r--llvm/test/Transforms/GlobalOpt/shrink-global-to-bool-check-debug.ll22
-rw-r--r--llvm/test/Transforms/GlobalOpt/static-const-bitcast.ll62
-rw-r--r--llvm/test/Transforms/GlobalOpt/storepointer-compare-no-null-opt.ll40
-rw-r--r--llvm/test/Transforms/GlobalOpt/storepointer-compare.ll29
-rw-r--r--llvm/test/Transforms/GlobalOpt/storepointer-no-null-opt.ll27
-rw-r--r--llvm/test/Transforms/GlobalOpt/storepointer.ll19
-rw-r--r--llvm/test/Transforms/GlobalOpt/tls.ll54
-rw-r--r--llvm/test/Transforms/GlobalOpt/trivialstore.ll19
-rw-r--r--llvm/test/Transforms/GlobalOpt/undef-init.ll17
-rw-r--r--llvm/test/Transforms/GlobalOpt/unnamed-addr.ll74
-rw-r--r--llvm/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll11
125 files changed, 4516 insertions, 0 deletions
diff --git a/llvm/test/Transforms/GlobalOpt/2004-10-10-CastStoreOnce.ll b/llvm/test/Transforms/GlobalOpt/2004-10-10-CastStoreOnce.ll
new file mode 100644
index 00000000000..061b9b0670f
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2004-10-10-CastStoreOnce.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -globalopt
+
+@V = global float 1.200000e+01 ; <float*> [#uses=1]
+@G = internal global i32* null ; <i32**> [#uses=2]
+
+define i32 @user() {
+ %P = load i32*, i32** @G ; <i32*> [#uses=1]
+ %Q = load i32, i32* %P ; <i32> [#uses=1]
+ ret i32 %Q
+}
+
+define void @setter() {
+ %Vi = bitcast float* @V to i32* ; <i32*> [#uses=1]
+ store i32* %Vi, i32** @G
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/2005-06-15-LocalizeConstExprCrash.ll b/llvm/test/Transforms/GlobalOpt/2005-06-15-LocalizeConstExprCrash.ll
new file mode 100644
index 00000000000..3efbde42341
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2005-06-15-LocalizeConstExprCrash.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -globalopt -disable-output
+; PR579
+
+@g_40507551 = internal global i16 31038 ; <i16*> [#uses=1]
+
+define void @main() {
+ %tmp.4.i.1 = load i8, i8* getelementptr (i8, i8* bitcast (i16* @g_40507551 to i8*), i32 1) ; <i8> [#uses=0]
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/2005-09-27-Crash.ll b/llvm/test/Transforms/GlobalOpt/2005-09-27-Crash.ll
new file mode 100644
index 00000000000..061c88159dd
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2005-09-27-Crash.ll
@@ -0,0 +1,27 @@
+; RUN: opt < %s -globalopt -disable-output
+ %RPyString = type { i32, %arraytype.Char }
+ %arraytype.Char = type { i32, [0 x i8] }
+ %arraytype.Signed = type { i32, [0 x i32] }
+ %functiontype.1 = type { %RPyString* (i32) *}
+ %structtype.test = type { i32, %arraytype.Signed }
+@structinstance.test = internal global { i32, { i32, [2 x i32] } } { i32 41, { i32, [2 x i32] } { i32 2, [2 x i32] [ i32 100, i32 101 ] } } ; <{ i32, { i32, [2 x i32] } }*> [#uses=1]
+
+define fastcc void @pypy_array_constant() {
+block0:
+ %tmp.9 = getelementptr %structtype.test, %structtype.test* bitcast ({ i32, { i32, [2 x i32] } }* @structinstance.test to %structtype.test*), i32 0, i32 0 ; <i32*> [#uses=0]
+ ret void
+}
+
+define fastcc void @new.varsizestruct.rpy_string() {
+ unreachable
+}
+
+define void @__entrypoint__pypy_array_constant() {
+ call fastcc void @pypy_array_constant( )
+ ret void
+}
+
+define void @__entrypoint__raised_LLVMException() {
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/2006-07-07-InlineAsmCrash.ll b/llvm/test/Transforms/GlobalOpt/2006-07-07-InlineAsmCrash.ll
new file mode 100644
index 00000000000..419ae101966
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2006-07-07-InlineAsmCrash.ll
@@ -0,0 +1,135 @@
+; RUN: opt < %s -globalopt -disable-output
+; PR820
+target datalayout = "e-p:32:32"
+target triple = "i686-pc-linux-gnu"
+ %struct..0FileDescriptor = type { i32 }
+ %"struct.FlagDescription<int32>" = type { i8*, i32*, i1, i1, i32, i8* }
+ %"struct.FlagRegisterer<bool>" = type { i8 }
+ %struct.MutexLock = type { %struct..0FileDescriptor* }
+ %"struct.std::DisabledRangeMap" = type { %"struct.std::_Rb_tree<const char*,std::pair<const char* const, FlagDescription<bool> >,std::_Select1st<std::pair<const char* const, FlagDescription<bool> > >,StringCmp,std::allocator<std::pair<const char* const, FlagDescription<bool> > > >" }
+ %"struct.std::_Rb_tree<const char*,std::pair<const char* const, FlagDescription<bool> >,std::_Select1st<std::pair<const char* const, FlagDescription<bool> > >,StringCmp,std::allocator<std::pair<const char* const, FlagDescription<bool> > > >" = type { %"struct.std::_Rb_tree<const char*,std::pair<const char* const, FlagDescription<bool> >,std::_Select1st<std::pair<const char* const, FlagDescription<bool> > >,StringCmp,std::allocator<std::pair<const char* const, FlagDescription<bool> > > >::_Rb_tree_impl<StringCmp,false>" }
+ %"struct.std::_Rb_tree<const char*,std::pair<const char* const, FlagDescription<bool> >,std::_Select1st<std::pair<const char* const, FlagDescription<bool> > >,StringCmp,std::allocator<std::pair<const char* const, FlagDescription<bool> > > >::_Rb_tree_impl<StringCmp,false>" = type { %"struct.FlagRegisterer<bool>", %"struct.std::_Rb_tree_node_base", i32 }
+ %"struct.std::_Rb_tree_const_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { %"struct.std::_Rb_tree_node_base"* }
+ %"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* }
+ %"struct.std::_Vector_base<int,std::allocator<int> >" = type { %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl" }
+ %"struct.std::_Vector_base<int,std::allocator<int> >::_Vector_impl" = type { i32*, i32*, i32* }
+ %"struct.std::vector<int,std::allocator<int> >" = type { %"struct.std::_Vector_base<int,std::allocator<int> >" }
+@registry_lock = external global %struct..0FileDescriptor ; <%struct..0FileDescriptor*> [#uses=0]
+@_ZN61FLAG__foo_int32_44FLAGS_E = external global %"struct.FlagRegisterer<bool>" ; <%"struct.FlagRegisterer<bool>"*> [#uses=0]
+@llvm.global_ctors = appending global [20 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN62FLAG__foo_string_10FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN60FLAG__foo_bool_19FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZNK5Bzh4Enum13is_contiguousEv }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN62FLAG__foo_string_17FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN61FLAG__foo_int32_21FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN7ScannerC2Ev }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__Z11StripStringPSsPKcc }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZNK9__gnu_cxx4hashI11StringPieceEclERKS1_ }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN8Hasher325ResetEj }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__Z25ACLRv }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN61FLAG__foo_int64_25FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN61FLAG__foo_int32_7FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN62FLAG__foo_string_18FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN62FLAG__foo_string_17FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN61FLAG__foo_int32_25FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_eventbuf }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN61FLAG__foo_int32_26FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN62FLAG__foo_string_16FLAGS_E }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__ZN17InitializerC2EPKcS1_PFvvE }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__checker_bcad_variable } ] ; <[20 x { i32, void ()* }]*> [#uses=0]
+
+declare void @_GLOBAL__I__ZN62FLAG__foo_string_10FLAGS_E()
+
+declare void @_GLOBAL__I__ZN60FLAG__foo_bool_19FLAGS_E()
+
+declare void @_GLOBAL__I__ZNK5Bzh4Enum13is_contiguousEv()
+
+declare void @_GLOBAL__I__ZN62FLAG__foo_string_17FLAGS_E()
+
+declare void @_GLOBAL__I__ZN61FLAG__foo_int32_21FLAGS_E()
+
+define void @_ZN14FlagRegistererIiEC1EPKcRK15FlagDescriptionIiE() {
+entry:
+ call void @_Z12RegisterFlagIiEvPKcRK15FlagDescriptionIT_E( )
+ ret void
+}
+
+define void @_Z12RegisterFlagIiEvPKcRK15FlagDescriptionIT_E() {
+entry:
+ call void @_ZN9MutexLockC1EP5Mutex( )
+ ret void
+}
+
+declare void @_GLOBAL__I__ZN7ScannerC2Ev()
+
+declare void @_GLOBAL__I__Z11StripStringPSsPKcc()
+
+define void @_ZNSt6vectorIiSaIiEEC1ERKS0_() {
+entry:
+ unreachable
+}
+
+declare void @_GLOBAL__I__ZNK9__gnu_cxx4hashI11StringPieceEclERKS1_()
+
+declare void @_GLOBAL__I__ZN8Hasher325ResetEj()
+
+declare void @_GLOBAL__I__Z25ACLRv()
+
+define void @_ZN9MutexLockC1EP5Mutex() {
+entry:
+ call void @_ZN5Mutex4LockEv( )
+ ret void
+}
+
+define void @_ZN5Mutex4LockEv() {
+entry:
+ call void @_Z22Acquire_CASPViii( )
+ ret void
+}
+
+define void @_ZNSt3mapIPKc15FlagDescriptionIiE9StringCmpSaISt4pairIKS1_S3_EEE3endEv(%"struct.std::_Rb_tree_const_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >"* sret %agg.result) {
+entry:
+ unreachable
+}
+
+declare void @_GLOBAL__I__ZN61FLAG__foo_int64_25FLAGS_E()
+
+define void @_Z14CASPViii() {
+entry:
+ %tmp3 = call i32 asm sideeffect "lock; cmpxchg $1,$2", "={ax},q,m,0,~{dirflag},~{fpsr},~{flags},~{memory}"( i32 0, i32* null, i32 0 ) ; <i32> [#uses=0]
+ unreachable
+}
+
+declare void @_GLOBAL__I__ZN61FLAG__foo_int32_7FLAGS_E()
+
+declare void @_GLOBAL__I__ZN62FLAG__foo_string_18FLAGS_E()
+
+define void @_Z22Acquire_CASPViii() {
+entry:
+ call void @_Z14CASPViii( )
+ unreachable
+}
+
+declare void @_GLOBAL__I__ZN61FLAG__foo_int32_25FLAGS_E()
+
+declare void @_GLOBAL__I_eventbuf()
+
+define void @_GLOBAL__I__ZN61FLAG__foo_int32_26FLAGS_E() {
+entry:
+ call void @_Z41__static_initialization_and_destruction_0ii1662( i32 1, i32 65535 )
+ ret void
+}
+
+define void @_Z41__static_initialization_and_destruction_0ii1662(i32 %__initialize_p, i32 %__priority) {
+entry:
+ %__initialize_p_addr = alloca i32 ; <i32*> [#uses=2]
+ %__priority_addr = alloca i32 ; <i32*> [#uses=2]
+ store i32 %__initialize_p, i32* %__initialize_p_addr
+ store i32 %__priority, i32* %__priority_addr
+ %tmp = load i32, i32* %__priority_addr ; <i32> [#uses=1]
+ %tmp.upgrd.1 = icmp eq i32 %tmp, 65535 ; <i1> [#uses=1]
+ br i1 %tmp.upgrd.1, label %cond_true, label %cond_next14
+
+cond_true: ; preds = %entry
+ %tmp8 = load i32, i32* %__initialize_p_addr ; <i32> [#uses=1]
+ %tmp9 = icmp eq i32 %tmp8, 1 ; <i1> [#uses=1]
+ br i1 %tmp9, label %cond_true10, label %cond_next14
+
+cond_true10: ; preds = %cond_true
+ call void @_ZN14FlagRegistererIiEC1EPKcRK15FlagDescriptionIiE( )
+ ret void
+
+cond_next14: ; preds = %cond_true, %entry
+ ret void
+}
+
+declare void @_GLOBAL__I__ZN62FLAG__foo_string_16FLAGS_E()
+
+define void @_ZN9__gnu_cxx13new_allocatorIPNS_15_Hashtable_nodeIjEEEC2Ev() {
+entry:
+ unreachable
+}
+
+declare void @_GLOBAL__I__ZN17InitializerC2EPKcS1_PFvvE()
+
+declare void @_GLOBAL__I__checker_bcad_variable()
diff --git a/llvm/test/Transforms/GlobalOpt/2006-11-01-ShrinkGlobalPhiCrash.ll b/llvm/test/Transforms/GlobalOpt/2006-11-01-ShrinkGlobalPhiCrash.ll
new file mode 100644
index 00000000000..7b62cf08a4b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2006-11-01-ShrinkGlobalPhiCrash.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -globalopt -disable-output
+
+ %struct._list = type { i32*, %struct._list* }
+ %struct._play = type { i32, i32*, %struct._list*, %struct._play* }
+@nrow = internal global i32 0 ; <i32*> [#uses=2]
+
+define void @make_play() {
+entry:
+ br label %cond_true16.i
+
+cond_true16.i: ; preds = %cond_true16.i, %entry
+ %low.0.in.i.0 = phi i32* [ @nrow, %entry ], [ null, %cond_true16.i ] ; <i32*> [#uses=1]
+ %low.0.i = load i32, i32* %low.0.in.i.0 ; <i32> [#uses=0]
+ br label %cond_true16.i
+}
+
+define void @make_wanted() {
+entry:
+ unreachable
+}
+
+define void @get_good_move() {
+entry:
+ ret void
+}
+
+define void @main() {
+entry:
+ store i32 8, i32* @nrow
+ tail call void @make_play( )
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/2007-04-05-Crash.ll b/llvm/test/Transforms/GlobalOpt/2007-04-05-Crash.ll
new file mode 100644
index 00000000000..f312fbbc9f9
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2007-04-05-Crash.ll
@@ -0,0 +1,34 @@
+; RUN: opt < %s -globalopt -disable-output
+
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32"
+target triple = "thumb-apple-darwin8"
+@replacementUnichar = internal global i16 -3 ; <i16*> [#uses=2]
+@"L_OBJC_IMAGE_INFO" = internal global [2 x i32] zeroinitializer ; <[2 x i32]*> [#uses=1]
+@llvm.used = appending global [1 x i8*] [ i8* bitcast ([2 x i32]* @"L_OBJC_IMAGE_INFO" to i8*) ] ; <[1 x i8*]*> [#uses=0]
+
+define zeroext i16 @__NSCharToUnicharCFWrapper(i8 zeroext %ch) {
+entry:
+ %iftmp.0.0.in.in = select i1 false, i16* @replacementUnichar, i16* null ; <i16*> [#uses=1]
+ %iftmp.0.0.in = load i16, i16* %iftmp.0.0.in.in ; <i16> [#uses=1]
+ ret i16 %iftmp.0.0.in
+}
+
+define void @__NSASCIICharToUnichar() {
+entry:
+ ret void
+}
+
+define void @_NSDefaultCStringEncoding() {
+entry:
+ call void @__NSSetCStringCharToUnichar( )
+ br i1 false, label %cond_true6, label %cond_next8
+
+cond_true6: ; preds = %entry
+ store i16 -2, i16* @replacementUnichar
+ ret void
+
+cond_next8: ; preds = %entry
+ ret void
+}
+
+declare void @__NSSetCStringCharToUnichar()
diff --git a/llvm/test/Transforms/GlobalOpt/2007-05-13-Crash.ll b/llvm/test/Transforms/GlobalOpt/2007-05-13-Crash.ll
new file mode 100644
index 00000000000..bed4fec981e
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2007-05-13-Crash.ll
@@ -0,0 +1,74 @@
+; RUN: opt < %s -globalopt -disable-output
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
+target triple = "i686-apple-darwin8"
+ %struct.SFLMutableListItem = type { i16 }
+ %struct.__CFDictionary = type opaque
+ %struct.__CFString = type opaque
+ %struct.__builtin_CFString = type { i32*, i32, i8*, i32 }
+@_ZZ19SFLGetVisibilityKeyvE19_kSFLLVisibilityKey = internal global %struct.__CFString* null ; <%struct.__CFString**> [#uses=2]
+@_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey = internal global %struct.__CFString* null ; <%struct.__CFString**> [#uses=7]
+@0 = internal constant %struct.__builtin_CFString {
+ i32* getelementptr ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0),
+ i32 1992,
+ i8* getelementptr ([14 x i8], [14 x i8]* @.str, i32 0, i32 0),
+ i32 13 }, section "__DATA,__cfstring" ; <%struct.__builtin_CFString*>:0 [#uses=1]
+@__CFConstantStringClassReference = external global [0 x i32] ; <[0 x i32]*> [#uses=1]
+@.str = internal constant [14 x i8] c"AlwaysVisible\00" ; <[14 x i8]*> [#uses=1]
+@_ZZ21SFLGetNeverVisibleKeyvE21_kSFLLNeverVisibleKey = internal global %struct.__CFString* null ; <%struct.__CFString**> [#uses=2]
+
+define %struct.__CFString* @_Z19SFLGetVisibilityKeyv() {
+entry:
+ %tmp1 = load %struct.__CFString*, %struct.__CFString** @_ZZ19SFLGetVisibilityKeyvE19_kSFLLVisibilityKey ; <%struct.__CFString*> [#uses=1]
+ ret %struct.__CFString* %tmp1
+}
+
+define %struct.__CFString* @_Z22SFLGetAlwaysVisibleKeyv() {
+entry:
+ %tmp1 = load %struct.__CFString*, %struct.__CFString** @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey ; <%struct.__CFString*> [#uses=1]
+ %tmp2 = icmp eq %struct.__CFString* %tmp1, null ; <i1> [#uses=1]
+ br i1 %tmp2, label %cond_true, label %cond_next
+
+cond_true: ; preds = %entry
+ store %struct.__CFString* bitcast (%struct.__builtin_CFString* @0 to %struct.__CFString*), %struct.__CFString** @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey
+ br label %cond_next
+
+cond_next: ; preds = %entry, %cond_true
+ %tmp4 = load %struct.__CFString*, %struct.__CFString** @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey ; <%struct.__CFString*> [#uses=1]
+ ret %struct.__CFString* %tmp4
+}
+
+define %struct.__CFString* @_Z21SFLGetNeverVisibleKeyv() {
+entry:
+ %tmp1 = load %struct.__CFString*, %struct.__CFString** @_ZZ21SFLGetNeverVisibleKeyvE21_kSFLLNeverVisibleKey ; <%struct.__CFString*> [#uses=1]
+ ret %struct.__CFString* %tmp1
+}
+
+define %struct.__CFDictionary* @_ZN18SFLMutableListItem18GetPrefsDictionaryEv(%struct.SFLMutableListItem* %this) {
+entry:
+ %tmp4 = getelementptr %struct.SFLMutableListItem, %struct.SFLMutableListItem* %this, i32 0, i32 0 ; <i16*> [#uses=1]
+ %tmp5 = load i16, i16* %tmp4 ; <i16> [#uses=1]
+ %tmp6 = icmp eq i16 %tmp5, 0 ; <i1> [#uses=1]
+ br i1 %tmp6, label %cond_next22, label %cond_true
+
+cond_true: ; preds = %entry
+ %tmp9 = load %struct.__CFString*, %struct.__CFString** @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey ; <%struct.__CFString*> [#uses=1]
+ %tmp10 = icmp eq %struct.__CFString* %tmp9, null ; <i1> [#uses=1]
+ br i1 %tmp10, label %cond_true13, label %cond_next22
+
+cond_true13: ; preds = %cond_true
+ store %struct.__CFString* bitcast (%struct.__builtin_CFString* @0 to %struct.__CFString*), %struct.__CFString** @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey
+ br label %cond_next22
+
+cond_next22: ; preds = %entry, %cond_true13, %cond_true
+ %iftmp.1.0.in = phi %struct.__CFString** [ @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey, %cond_true ], [ @_ZZ22SFLGetAlwaysVisibleKeyvE22_kSFLLAlwaysVisibleKey, %cond_true13 ], [ @_ZZ21SFLGetNeverVisibleKeyvE21_kSFLLNeverVisibleKey, %entry ] ; <%struct.__CFString**> [#uses=1]
+ %iftmp.1.0 = load %struct.__CFString*, %struct.__CFString** %iftmp.1.0.in ; <%struct.__CFString*> [#uses=1]
+ %tmp24 = load %struct.__CFString*, %struct.__CFString** @_ZZ19SFLGetVisibilityKeyvE19_kSFLLVisibilityKey ; <%struct.__CFString*> [#uses=1]
+ %tmp2728 = bitcast %struct.__CFString* %tmp24 to i8* ; <i8*> [#uses=1]
+ %tmp2930 = bitcast %struct.__CFString* %iftmp.1.0 to i8* ; <i8*> [#uses=1]
+ call void @_Z20CFDictionaryAddValuePKvS0_( i8* %tmp2728, i8* %tmp2930 )
+ ret %struct.__CFDictionary* undef
+}
+
+declare void @_Z20CFDictionaryAddValuePKvS0_(i8*, i8*)
+
diff --git a/llvm/test/Transforms/GlobalOpt/2007-06-04-PackedStruct.ll b/llvm/test/Transforms/GlobalOpt/2007-06-04-PackedStruct.ll
new file mode 100644
index 00000000000..f6e0bb70d63
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2007-06-04-PackedStruct.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -globalopt -disable-output
+; PR1491
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
+target triple = "i686-pc-linux-gnu"
+ %"struct.__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<const int, int> > >" = type <{ i8 }>
+ %"struct.std::_Rb_tree<int,std::pair<const int, int>,std::_Select1st<std::pair<const int, int> >,std::less<int>,std::allocator<std::pair<const int, int> > >" = type { %"struct.std::_Rb_tree<int,std::pair<const int, int>,std::_Select1st<std::pair<const int, int> >,std::less<int>,std::allocator<std::pair<const int, int> > >::_Rb_tree_impl<std::less<int>,false>" }
+ %"struct.std::_Rb_tree<int,std::pair<const int, int>,std::_Select1st<std::pair<const int, int> >,std::less<int>,std::allocator<std::pair<const int, int> > >::_Rb_tree_impl<std::less<int>,false>" = type { %"struct.__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<const int, int> > >", %"struct.std::_Rb_tree_node_base", i32 }
+ %"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* }
+ %"struct.std::map<int,int,std::less<int>,std::allocator<std::pair<const int, int> > >" = type { %"struct.std::_Rb_tree<int,std::pair<const int, int>,std::_Select1st<std::pair<const int, int> >,std::less<int>,std::allocator<std::pair<const int, int> > >" }
+@someMap = global %"struct.std::map<int,int,std::less<int>,std::allocator<std::pair<const int, int> > >" zeroinitializer ; <%"struct.std::map<int,int,std::less<int>,std::allocator<std::pair<const int, int> > >"*> [#uses=1]
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_someMap } ] ; <[1 x { i32, void ()* }]*> [#uses=0]
+@llvm.global_dtors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @_GLOBAL__D_someMap } ] ; <[1 x { i32, void ()* }]*> [#uses=0]
+
+define void @_GLOBAL__I_someMap() {
+entry:
+ call void @_Z41__static_initialization_and_destruction_0ii( i32 1, i32 65535 )
+ ret void
+}
+
+declare void @_GLOBAL__D_someMap()
+
+define void @_Z41__static_initialization_and_destruction_0ii(i32 %__initialize_p, i32 %__priority) {
+entry:
+ %tmp1 = icmp eq i32 %__priority, 65535 ; <i1> [#uses=1]
+ %tmp4 = icmp eq i32 %__initialize_p, 1 ; <i1> [#uses=1]
+ %tmp7 = and i1 %tmp1, %tmp4 ; <i1> [#uses=1]
+ br i1 %tmp7, label %cond_true, label %cond_next
+
+cond_true: ; preds = %entry
+ store i8 0, i8* getelementptr (%"struct.std::map<int,int,std::less<int>,std::allocator<std::pair<const int, int> > >", %"struct.std::map<int,int,std::less<int>,std::allocator<std::pair<const int, int> > >"* @someMap, i32 0, i32 0, i32 0, i32 0, i32 0)
+ ret void
+
+cond_next: ; preds = %entry
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll b/llvm/test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll
new file mode 100644
index 00000000000..f6225cd3ad0
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -globalopt -disable-output
+target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128"
+target triple = "powerpc-unknown-linux-gnu"
+ %struct.empty0 = type { }
+ %struct.es = type { %struct.empty0 }
+ %struct.es1 = type { %struct.empty0 }
+@aaui1 = internal global [6 x [2 x i32]] [ [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ] ] ; <[6 x [2 x i32]]*> [#uses=1]
+@aaui0 = internal global [0 x [2 x i32]] zeroinitializer ; <[0 x [2 x i32]]*> [#uses=1]
+
+define i8 @func() {
+entry:
+ %tmp10 = getelementptr [2 x i32], [2 x i32]* getelementptr ([6 x [2 x i32]], [6 x [2 x i32]]* @aaui1, i32 0, i32 0), i32 5, i32 1 ; <i32*> [#uses=1]
+ %tmp11 = load i32, i32* %tmp10, align 4 ; <i32> [#uses=1]
+ %tmp12 = call i32 (...) @func3( i32* null, i32 0, i32 %tmp11 ) ; <i32> [#uses=0]
+ ret i8 undef
+}
+
+declare i32 @func3(...)
+
diff --git a/llvm/test/Transforms/GlobalOpt/2008-01-03-Crash.ll b/llvm/test/Transforms/GlobalOpt/2008-01-03-Crash.ll
new file mode 100644
index 00000000000..dc41fdb8de4
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-01-03-Crash.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -globalopt | llvm-dis
+; PR1896
+
+@indirect1 = internal global void (i32)* null ; <void (i32)**> [#uses=2]
+
+declare void @indirectmarked(i32)
+
+define i32 @main() {
+entry:
+ br i1 false, label %cond_next20.i, label %cond_true.i9
+
+cond_true.i9: ; preds = %entry
+ ret i32 0
+
+cond_next20.i: ; preds = %entry
+ store void (i32)* @indirectmarked, void (i32)** @indirect1, align 4
+ br i1 false, label %cond_next21.i.i23.i, label %stack_restore
+
+stack_restore: ; preds = %cond_next20.i
+ ret i32 0
+
+cond_next21.i.i23.i: ; preds = %cond_next20.i
+ %tmp6.i4.i = load i32, i32* bitcast (void (i32)** @indirect1 to i32*), align 4 ; <i32> [#uses=0]
+ ret i32 0
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll b/llvm/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll
new file mode 100644
index 00000000000..4adc9607c75
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-01-13-OutOfRangeSROA.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; The 'X' indices could be larger than 31. Do not SROA the outer
+; indices of this array.
+; CHECK: @mm = {{.*}} [16 x [31 x double]] zeroinitializer
+@mm = internal global [16 x [31 x double]] zeroinitializer, align 32
+
+define void @test(i32 %X) {
+ %P = getelementptr [16 x [31 x double]], [16 x [31 x double]]* @mm, i32 0, i32 0, i32 %X
+ store double 1.0, double* %P
+ ret void
+}
+
+define double @get(i32 %X) {
+ %P = getelementptr [16 x [31 x double]], [16 x [31 x double]]* @mm, i32 0, i32 0, i32 %X
+ %V = load double, double* %P
+ ret double %V
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll b/llvm/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
new file mode 100644
index 00000000000..7818e5d642c
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: load volatile
+@t0.1441 = internal global double 0x3FD5555555555555, align 8 ; <double*> [#uses=1]
+
+define double @foo() nounwind {
+entry:
+ %tmp1 = load volatile double, double* @t0.1441, align 8 ; <double> [#uses=2]
+ %tmp4 = fmul double %tmp1, %tmp1 ; <double> [#uses=1]
+ ret double %tmp4
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2008-04-26-SROA-Global-Align.ll b/llvm/test/Transforms/GlobalOpt/2008-04-26-SROA-Global-Align.ll
new file mode 100644
index 00000000000..c3a6d7b5716
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-04-26-SROA-Global-Align.ll
@@ -0,0 +1,34 @@
+; Verify that when @G is SROA'd that the new globals have correct
+; alignments. Elements 0 and 2 must be 16-byte aligned, and element
+; 1 must be at least 8 byte aligned (but could be more).
+
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: @G.0 = internal unnamed_addr global {{.*}}align 16
+; CHECK: @G.1 = internal unnamed_addr global {{.*}}align 8
+; CHECK: @G.2 = internal unnamed_addr global {{.*}}align 16
+
+; rdar://5891920
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin8"
+
+%T = type { double, double, double }
+
+@G = internal global %T zeroinitializer, align 16
+
+
+define void @test() {
+ store double 1.0, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
+ store double 2.0, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
+ store double 3.0, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
+ ret void
+}
+
+define double @test2() {
+ %V1 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
+ %V2 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
+ %V3 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
+ %R = fadd double %V1, %V2
+ %R2 = fadd double %R, %V3
+ ret double %R2
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll b/llvm/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll
new file mode 100644
index 00000000000..b9d2d993240
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll
@@ -0,0 +1,28 @@
+; This test lets globalopt split the global struct and array into different
+; values. This used to crash, because globalopt forgot to put the new var in the
+; same address space as the old one.
+
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; Check that the new global values still have their address space
+; CHECK: addrspace(1) global
+; CHECK: addrspace(1) global
+
+@struct = internal addrspace(1) global { i32, i32 } zeroinitializer
+@array = internal addrspace(1) global [ 2 x i32 ] zeroinitializer
+
+define i32 @foo() {
+ %A = load i32, i32 addrspace(1) * getelementptr ({ i32, i32 }, { i32, i32 } addrspace(1) * @struct, i32 0, i32 0)
+ %B = load i32, i32 addrspace(1) * getelementptr ([ 2 x i32 ], [ 2 x i32 ] addrspace(1) * @array, i32 0, i32 0)
+ ; Use the loaded values, so they won't get removed completely
+ %R = add i32 %A, %B
+ ret i32 %R
+}
+
+; We put stores in a different function, so that the global variables won't get
+; optimized away completely.
+define void @bar(i32 %R) {
+ store i32 %R, i32 addrspace(1) * getelementptr ([ 2 x i32 ], [ 2 x i32 ] addrspace(1) * @array, i32 0, i32 0)
+ store i32 %R, i32 addrspace(1) * getelementptr ({ i32, i32 }, { i32, i32 } addrspace(1) * @struct, i32 0, i32 0)
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash-2.ll b/llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash-2.ll
new file mode 100644
index 00000000000..bd32163e5f9
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash-2.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -globalopt | llvm-dis
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin7"
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+
+define void @bar(i32 %Size) nounwind noinline {
+entry:
+ %malloccall = tail call i8* @malloc(i32 trunc (i64 mul (i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64), i64 2000000) to i32))
+ %tmp = bitcast i8* %malloccall to [1000000 x %struct.foo]*
+ %.sub = getelementptr [1000000 x %struct.foo], [1000000 x %struct.foo]* %tmp, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i32)
+
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %tmpLD1 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=2]
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %tmp = phi %struct.foo* [ %tmpLD1, %bb1.thread ], [ %tmpLD1, %bb1 ] ; <%struct.foo*> [#uses=1]
+ %0 = getelementptr %struct.foo, %struct.foo* %tmp, i32 1 ; <%struct.foo*> [#uses=0]
+ br label %bb1
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash.ll b/llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash.ll
new file mode 100644
index 00000000000..e9c16785afa
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2008-12-16-HeapSRACrash.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -globalopt | llvm-dis
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin7"
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+
+define void @bar(i32 %Size) nounwind noinline {
+entry:
+ %malloccall = tail call i8* @malloc(i32 trunc (i64 mul (i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64), i64 2000000) to i32))
+ %tmp = bitcast i8* %malloccall to [1000000 x %struct.foo]*
+ %.sub = getelementptr [1000000 x %struct.foo], [1000000 x %struct.foo]* %tmp, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i32)
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %tmpLD1 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=3]
+ store %struct.foo* %tmpLD1, %struct.foo** null
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %tmp = phi %struct.foo* [ %tmpLD1, %bb1.thread ], [ %tmpLD1, %bb1 ] ; <%struct.foo*> [#uses=0]
+ br i1 false, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 0
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2009-01-13-phi-user.ll b/llvm/test/Transforms/GlobalOpt/2009-01-13-phi-user.ll
new file mode 100644
index 00000000000..7ad24b92a2d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-01-13-phi-user.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: phi{{.*}}@head
+; PR3321
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+ %struct.node = type { %struct.node*, i32 }
+@head = internal global %struct.node* null ; <%struct.node**> [#uses=2]
+@node = internal global %struct.node { %struct.node* null, i32 42 }, align 16 ; <%struct.node*> [#uses=1]
+
+define i32 @f() nounwind {
+entry:
+ store %struct.node* @node, %struct.node** @head, align 8
+ br label %bb1
+
+bb: ; preds = %bb1
+ %0 = getelementptr %struct.node, %struct.node* %t.0, i64 0, i32 1 ; <i32*> [#uses=1]
+ %1 = load i32, i32* %0, align 4 ; <i32> [#uses=1]
+ %2 = getelementptr %struct.node, %struct.node* %t.0, i64 0, i32 0 ; <%struct.node**> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb, %entry
+ %value.0 = phi i32 [ undef, %entry ], [ %1, %bb ] ; <i32> [#uses=1]
+ %t.0.in = phi %struct.node** [ @head, %entry ], [ %2, %bb ] ; <%struct.node**> [#uses=1]
+ %t.0 = load %struct.node*, %struct.node** %t.0.in ; <%struct.node*> [#uses=3]
+ %3 = icmp eq %struct.node* %t.0, null ; <i1> [#uses=1]
+ br i1 %3, label %bb2, label %bb
+
+bb2: ; preds = %bb1
+ ret i32 %value.0
+}
+
+define i32 @main() nounwind {
+entry:
+ %0 = call i32 @f() nounwind ; <i32> [#uses=1]
+ ret i32 %0
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll b/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
new file mode 100644
index 00000000000..e6337adefa1
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -globalopt
+
+@g = global i32 0
+
+@a = alias i8, bitcast (i32* @g to i8*)
+
+define void @f() {
+ %tmp = load i8, i8* @a
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll b/llvm/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll
new file mode 100644
index 00000000000..42c243d9d7c
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+define internal void @f() {
+; CHECK-NOT: @f(
+; CHECK: define void @a
+ ret void
+}
+
+@a = alias void (), void ()* @f
+
+define void @g() {
+ call void() @a()
+ ret void
+}
+
+@b = internal alias void (), void ()* @g
+; CHECK-NOT: @b
+
+define void @h() {
+ call void() @b()
+; CHECK: call void @g
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/2009-03-05-dbg.ll b/llvm/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
new file mode 100644
index 00000000000..68ea4ffe639
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
@@ -0,0 +1,80 @@
+; REQUIRES: asserts
+; RUN: opt < %s -globalopt -stats -disable-output 2>&1 | FileCheck %s
+; CHECK: 1 globalopt - Number of global vars shrunk to booleans
+
+source_filename = "test/Transforms/GlobalOpt/2009-03-05-dbg.ll"
+
+@Stop = internal global i32 0, !dbg !0
+
+; Function Attrs: nounwind ssp
+define i32 @foo(i32 %i) #0 {
+entry:
+ %"alloca point" = bitcast i32 0 to i32
+ call void @llvm.dbg.value(metadata i32 %i, metadata !8, metadata !12), !dbg !13
+ %0 = icmp eq i32 %i, 1, !dbg !13
+ br i1 %0, label %bb, label %bb1, !dbg !13
+
+bb: ; preds = %entry
+ store i32 0, i32* @Stop, align 4, !dbg !15
+ %1 = mul nsw i32 %i, 42, !dbg !16
+ call void @llvm.dbg.value(metadata i32 %1, metadata !8, metadata !12), !dbg !16
+ br label %bb2, !dbg !16
+
+bb1: ; preds = %entry
+ store i32 1, i32* @Stop, align 4, !dbg !17
+ br label %bb2, !dbg !17
+
+bb2: ; preds = %bb1, %bb
+ %i_addr.0 = phi i32 [ %1, %bb ], [ %i, %bb1 ]
+ br label %return, !dbg !18
+
+return: ; preds = %bb2
+ ret i32 %i_addr.0, !dbg !18
+}
+
+; Function Attrs: nounwind readnone
+
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+; Function Attrs: nounwind ssp
+define i32 @bar() #0 {
+entry:
+ %"alloca point" = bitcast i32 0 to i32
+ %0 = load i32, i32* @Stop, align 4, !dbg !19
+ %1 = icmp eq i32 %0, 1, !dbg !19
+ br i1 %1, label %bb, label %bb1, !dbg !19
+
+bb: ; preds = %entry
+
+ br label %bb2, !dbg !24
+
+bb1: ; preds = %entry
+ br label %bb2, !dbg !25
+
+bb2: ; preds = %bb1, %bb
+ %.0 = phi i32 [ 0, %bb ], [ 1, %bb1 ]
+ br label %return, !dbg !25
+
+return: ; preds = %bb2
+ ret i32 %.0, !dbg !25
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+attributes #0 = { nounwind ssp }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!6, !7}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = !DIGlobalVariable(name: "Stop", scope: !2, file: !3, line: 2, type: !5, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C89, file: !3, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4)
+!3 = !DIFile(filename: "g.c", directory: "/tmp")
+!4 = !{!0}
+!5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!6 = !{i32 2, !"Dwarf Version", i32 2}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = !DILocalVariable(name: "i", arg: 1, scope: !9, file: !3, line: 4, type: !5)
+!9 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !2, file: !3, line: 4, type: !10, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !2)!10 = !DISubroutineType(types: !11)!11 = !{!5, !5}!12 = !DIExpression()!13 = !DILocation(line: 5, scope: !14)!14 = distinct !DILexicalBlock(scope: !9, file: !3)!15 = !DILocation(line: 6, scope: !14)!16 = !DILocation(line: 7, scope: !14)!17 = !DILocation(line: 9, scope: !14)!18 = !DILocation(line: 11, scope: !14)!19 = !DILocation(line: 14, scope: !20)!20 = distinct !DILexicalBlock(scope: !21, file: !3)!21 = distinct !DISubprogram(name: "bar", linkageName: "bar", scope: !2, file: !3, line: 13, type: !22, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !2)!22 = !DISubroutineType(types: !23)!23 = !{!5}!24 = !DILocation(line: 15, scope: !20)!25 = !DILocation(line: 16, scope: !20)
diff --git a/llvm/test/Transforms/GlobalOpt/2009-03-06-Anonymous.ll b/llvm/test/Transforms/GlobalOpt/2009-03-06-Anonymous.ll
new file mode 100644
index 00000000000..d5836ea9254
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-03-06-Anonymous.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@0 = global i32 0
+; CHECK-DAG: @0 = internal global i32 0
+
+@1 = private global i32 0
+; CHECK-DAG: @1 = private global i32 0
+
+define i32* @2() {
+ ret i32* @0
+}
+; CHECK-DAG: define internal fastcc i32* @2()
+
+define i32* @f() {
+entry:
+ call i32* @2()
+ ret i32* %0
+}
+
+define i32* @g() {
+entry:
+ ret i32* @1
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2009-03-07-PromotePtrToBool.ll b/llvm/test/Transforms/GlobalOpt/2009-03-07-PromotePtrToBool.ll
new file mode 100644
index 00000000000..bec4891a496
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-03-07-PromotePtrToBool.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin7"
+
+; CHECK: @X = internal unnamed_addr global i32
+@X = internal global i32* null ; <i32**> [#uses=2]
+@Y = internal global i32 0 ; <i32*> [#uses=1]
+
+define void @foo() nounwind {
+entry:
+ store i32* @Y, i32** @X, align 4
+ ret void
+}
+
+define i32* @get() nounwind {
+entry:
+ %0 = load i32*, i32** @X, align 4 ; <i32*> [#uses=1]
+ ret i32* %0
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll b/llvm/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
new file mode 100644
index 00000000000..30e4d422621
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
@@ -0,0 +1,122 @@
+; RUN: opt < %s -globalopt
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+ %struct.s_annealing_sched = type { i32, float, float, float, float }
+ %struct.s_bb = type { i32, i32, i32, i32 }
+ %struct.s_net = type { i8*, i32, i32*, float, float }
+ %struct.s_placer_opts = type { i32, float, i32, i32, i8*, i32, i32 }
+@net = internal global %struct.s_net* null ; <%struct.s_net**> [#uses=4]
+
+define fastcc void @alloc_and_load_placement_structs(i32 %place_cost_type, i32 %num_regions, float %place_cost_exp, float*** nocapture %old_region_occ_x, float*** nocapture %old_region_occ_y) nounwind ssp {
+entry:
+ br i1 undef, label %bb.i, label %my_malloc.exit
+
+bb.i: ; preds = %entry
+ unreachable
+
+my_malloc.exit: ; preds = %entry
+ br i1 undef, label %bb.i81, label %my_malloc.exit83
+
+bb.i81: ; preds = %my_malloc.exit
+ unreachable
+
+my_malloc.exit83: ; preds = %my_malloc.exit
+ br i1 undef, label %bb.i.i57, label %my_calloc.exit.i
+
+bb.i.i57: ; preds = %my_malloc.exit83
+ unreachable
+
+my_calloc.exit.i: ; preds = %my_malloc.exit83
+ br i1 undef, label %bb.i4.i, label %my_calloc.exit5.i
+
+bb.i4.i: ; preds = %my_calloc.exit.i
+ unreachable
+
+my_calloc.exit5.i: ; preds = %my_calloc.exit.i
+ %.pre.i58 = load %struct.s_net*, %struct.s_net** @net, align 4 ; <%struct.s_net*> [#uses=1]
+ br label %bb17.i78
+
+bb1.i61: ; preds = %bb4.preheader.i, %bb1.i61
+ br i1 undef, label %bb1.i61, label %bb5.i62
+
+bb5.i62: ; preds = %bb1.i61
+ br i1 undef, label %bb6.i64, label %bb15.preheader.i
+
+bb15.preheader.i: ; preds = %bb4.preheader.i, %bb5.i62
+ br label %bb16.i77
+
+bb6.i64: ; preds = %bb5.i62
+ br i1 undef, label %bb7.i65, label %bb8.i67
+
+bb7.i65: ; preds = %bb6.i64
+ unreachable
+
+bb8.i67: ; preds = %bb6.i64
+ br i1 undef, label %bb.i1.i68, label %my_malloc.exit.i70
+
+bb.i1.i68: ; preds = %bb8.i67
+ unreachable
+
+my_malloc.exit.i70: ; preds = %bb8.i67
+ %0 = load %struct.s_net*, %struct.s_net** @net, align 4 ; <%struct.s_net*> [#uses=1]
+ br i1 undef, label %bb9.i71, label %bb16.i77
+
+bb9.i71: ; preds = %bb9.i71, %my_malloc.exit.i70
+ %1 = load %struct.s_net*, %struct.s_net** @net, align 4 ; <%struct.s_net*> [#uses=1]
+ br i1 undef, label %bb9.i71, label %bb16.i77
+
+bb16.i77: ; preds = %bb9.i71, %my_malloc.exit.i70, %bb15.preheader.i
+ %.pre41.i.rle244 = phi %struct.s_net* [ %.pre41.i, %bb15.preheader.i ], [ %0, %my_malloc.exit.i70 ], [ %1, %bb9.i71 ] ; <%struct.s_net*> [#uses=1]
+ br label %bb17.i78
+
+bb17.i78: ; preds = %bb16.i77, %my_calloc.exit5.i
+ %.pre41.i = phi %struct.s_net* [ %.pre41.i.rle244, %bb16.i77 ], [ %.pre.i58, %my_calloc.exit5.i ] ; <%struct.s_net*> [#uses=1]
+ br i1 undef, label %bb4.preheader.i, label %alloc_and_load_unique_pin_list.exit
+
+bb4.preheader.i: ; preds = %bb17.i78
+ br i1 undef, label %bb1.i61, label %bb15.preheader.i
+
+alloc_and_load_unique_pin_list.exit: ; preds = %bb17.i78
+ ret void
+}
+
+define void @read_net(i8* %net_file) nounwind ssp {
+entry:
+ br i1 undef, label %bb3.us.us.i, label %bb6.preheader
+
+bb6.preheader: ; preds = %entry
+ br i1 undef, label %bb7, label %bb
+
+bb3.us.us.i: ; preds = %entry
+ unreachable
+
+bb: ; preds = %bb6.preheader
+ br i1 undef, label %bb.i34, label %bb1.i38
+
+bb.i34: ; preds = %bb
+ unreachable
+
+bb1.i38: ; preds = %bb
+ %mallocsize = mul i64 28, undef ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall to %struct.s_net* ; <%struct.s_net*> [#uses=1]
+ br i1 undef, label %bb.i1.i39, label %my_malloc.exit2.i
+
+bb.i1.i39: ; preds = %bb1.i38
+ unreachable
+
+my_malloc.exit2.i: ; preds = %bb1.i38
+ store %struct.s_net* %0, %struct.s_net** @net, align 4
+ br i1 undef, label %bb.i7.i40, label %my_malloc.exit8.i
+
+bb.i7.i40: ; preds = %my_malloc.exit2.i
+ unreachable
+
+my_malloc.exit8.i: ; preds = %my_malloc.exit2.i
+ unreachable
+
+bb7: ; preds = %bb6.preheader
+ unreachable
+}
+
+declare noalias i8* @malloc(i64)
diff --git a/llvm/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll b/llvm/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll
new file mode 100644
index 00000000000..461c25316e9
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10.0"
+
+%struct.hashheader = type { i16, i16, i16, i16, i16, i16, i32, i32, i32, i32, i32, i32, i32, i32, i32, [5 x i8], [13 x i8], i8, i8, i8, [228 x i16], [228 x i8], [228 x i8], [228 x i8], [228 x i8], [228 x i8], [228 x i8], [128 x i8], [100 x [11 x i8]], [100 x i32], [100 x i32], i16 }
+%struct.strchartype = type { i8*, i8*, i8* }
+
+@hashheader = internal global %struct.hashheader zeroinitializer, align 32 ; <%struct.hashheader*> [#uses=1]
+@chartypes = internal global %struct.strchartype* null ; <%struct.strchartype**> [#uses=1]
+; CHECK-NOT: @hashheader
+; CHECK-NOT: @chartypes
+
+; based on linit in office-ispell
+define void @test() nounwind ssp {
+ %1 = load i32, i32* getelementptr inbounds (%struct.hashheader, %struct.hashheader* @hashheader, i64 0, i32 13), align 8 ; <i32> [#uses=1]
+ %2 = sext i32 %1 to i64 ; <i64> [#uses=1]
+ %3 = mul i64 %2, ptrtoint (%struct.strchartype* getelementptr (%struct.strchartype, %struct.strchartype* null, i64 1) to i64) ; <i64> [#uses=1]
+ %4 = tail call i8* @malloc(i64 %3) ; <i8*> [#uses=1]
+; CHECK-NOT: call i8* @malloc(i64
+ %5 = bitcast i8* %4 to %struct.strchartype* ; <%struct.strchartype*> [#uses=1]
+ store %struct.strchartype* %5, %struct.strchartype** @chartypes, align 8
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
diff --git a/llvm/test/Transforms/GlobalOpt/2009-11-16-MallocSingleStoreToGlobalVar.ll b/llvm/test/Transforms/GlobalOpt/2009-11-16-MallocSingleStoreToGlobalVar.ll
new file mode 100644
index 00000000000..25bb9769f49
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2009-11-16-MallocSingleStoreToGlobalVar.ll
@@ -0,0 +1,30 @@
+; Test ensures that non-optimizable array mallocs are not optimized; specifically
+; GlobalOpt was treating a non-optimizable array malloc as a non-array malloc
+; and optimizing the global object that the malloc was stored to as a single
+; element global. The global object @TOP in this test should not be optimized.
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10.0"
+
+@TOP = internal global i64* null ; <i64**> [#uses=2]
+; CHECK: @TOP = internal unnamed_addr global i64* null
+@channelColumns = internal global i64 0 ; <i64*> [#uses=2]
+
+; Derived from @DescribeChannel() in yacr2
+define void @test() nounwind ssp {
+ store i64 2335, i64* @channelColumns, align 8
+ %1 = load i64, i64* @channelColumns, align 8 ; <i64> [#uses=1]
+ %2 = shl i64 %1, 3 ; <i64> [#uses=1]
+ %3 = add i64 %2, 8 ; <i64> [#uses=1]
+ %4 = call noalias i8* @malloc(i64 %3) nounwind ; <i8*> [#uses=1]
+; CHECK: call noalias i8* @malloc
+ %5 = bitcast i8* %4 to i64* ; <i64*> [#uses=1]
+ store i64* %5, i64** @TOP, align 8
+ %6 = load i64*, i64** @TOP, align 8 ; <i64*> [#uses=1]
+ %7 = getelementptr inbounds i64, i64* %6, i64 13 ; <i64*> [#uses=1]
+ store i64 0, i64* %7, align 8
+ ret void
+}
+
+declare noalias i8* @malloc(i64) nounwind
diff --git a/llvm/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll b/llvm/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
new file mode 100644
index 00000000000..9f53ce402fd
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
@@ -0,0 +1,18 @@
+; PR6422
+; RUN: opt -globalopt -S < %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@fixLRBT = internal global i32* null ; <i32**> [#uses=2]
+
+declare noalias i8* @malloc(i32)
+
+define i32 @parser() nounwind {
+bb918:
+ %malloccall.i10 = call i8* @malloc(i32 16) nounwind ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall.i10 to i32* ; <i32*> [#uses=1]
+ store i32* %0, i32** @fixLRBT, align 8
+ %1 = load i32*, i32** @fixLRBT, align 8 ; <i32*> [#uses=0]
+ %A = load i32, i32* %1
+ ret i32 %A
+}
diff --git a/llvm/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll b/llvm/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll
new file mode 100644
index 00000000000..12fa3419192
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2010-02-26-MallocSROA.ll
@@ -0,0 +1,27 @@
+; RUN: opt -globalopt -S < %s
+; PR6435
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.xyz = type { double, i32 }
+
+@Y = internal global %struct.xyz* null ; <%struct.xyz**> [#uses=2]
+@numf2s = external global i32 ; <i32*> [#uses=1]
+
+define fastcc void @init_net() nounwind {
+entry:
+ %0 = load i32, i32* @numf2s, align 4 ; <i32> [#uses=1]
+ %mallocsize2 = shl i32 %0, 4 ; <i32> [#uses=1]
+ %malloccall3 = tail call i8* @malloc(i32 %mallocsize2) nounwind ; <i8*> [#uses=1]
+ %1 = bitcast i8* %malloccall3 to %struct.xyz* ; <%struct.xyz*> [#uses=1]
+ store %struct.xyz* %1, %struct.xyz** @Y, align 8
+ ret void
+}
+
+define fastcc void @load_train(i8* %trainfile, i32 %mode, i32 %objects) nounwind {
+entry:
+ %0 = load %struct.xyz*, %struct.xyz** @Y, align 8 ; <%struct.xyz*> [#uses=0]
+ ret void
+}
+
+declare noalias i8* @malloc(i32)
diff --git a/llvm/test/Transforms/GlobalOpt/2010-10-19-WeakOdr.ll b/llvm/test/Transforms/GlobalOpt/2010-10-19-WeakOdr.ll
new file mode 100644
index 00000000000..c88dc1c2d12
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2010-10-19-WeakOdr.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; PR8389: Globals with weak_odr linkage type must not be modified
+
+; CHECK: weak_odr local_unnamed_addr global i32 0
+
+@SomeVar = weak_odr global i32 0
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
+
+define internal void @CTOR() {
+ store i32 23, i32* @SomeVar
+ ret void
+}
+
+
diff --git a/llvm/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll b/llvm/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll
new file mode 100644
index 00000000000..321a487cc82
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll
@@ -0,0 +1,5 @@
+; RUN: opt < %s -globalopt -disable-output
+
+%0 = type { i32, void ()* }
+@llvm.global_ctors = appending global [0 x %0] zeroinitializer
+
diff --git a/llvm/test/Transforms/GlobalOpt/2012-05-11-blockaddress.ll b/llvm/test/Transforms/GlobalOpt/2012-05-11-blockaddress.ll
new file mode 100644
index 00000000000..24213af024f
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/2012-05-11-blockaddress.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; Check that the mere presence of a blockaddress doesn't prevent -globalopt
+; from promoting @f to fastcc.
+
+; CHECK-LABEL: define{{.*}}fastcc{{.*}}@f(
+define internal i8* @f() {
+ ret i8* blockaddress(@f, %L1)
+L1:
+ ret i8* null
+}
+
+define void @g() {
+ ; CHECK: call{{.*}}fastcc{{.*}}@f
+ %p = call i8* @f()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/GSROA-section.ll b/llvm/test/Transforms/GlobalOpt/GSROA-section.ll
new file mode 100644
index 00000000000..a439fa0797d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/GSROA-section.ll
@@ -0,0 +1,30 @@
+; This test lets globalopt split the global struct and array into different
+; values. The pass needs to preserve section attribute.
+
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; Check that the new global values still have their section assignment.
+; CHECK: @struct
+; CHECK: section ".foo"
+; CHECK: @array
+; CHECK-NOT: section ".foo"
+
+@struct = internal global { i32, i32 } zeroinitializer, section ".foo"
+@array = internal global [ 2 x i32 ] zeroinitializer
+
+define i32 @foo() {
+ %A = load i32, i32* getelementptr ({ i32, i32 }, { i32, i32 }* @struct, i32 0, i32 0)
+ %B = load i32, i32* getelementptr ([ 2 x i32 ], [ 2 x i32 ]* @array, i32 0, i32 0)
+ ; Use the loaded values, so they won't get removed completely
+ %R = add i32 %A, %B
+ ret i32 %R
+}
+
+; We put stores in a different function, so that the global variables won't get
+; optimized away completely.
+define void @bar(i32 %R) {
+ store i32 %R, i32* getelementptr ([ 2 x i32 ], [ 2 x i32 ]* @array, i32 0, i32 0)
+ store i32 %R, i32* getelementptr ({ i32, i32 }, { i32, i32 }* @struct, i32 0, i32 0)
+ ret void
+}
+
+
diff --git a/llvm/test/Transforms/GlobalOpt/MallocSROA-section-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/MallocSROA-section-no-null-opt.ll
new file mode 100644
index 00000000000..c9b3f6fc1cd
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/MallocSROA-section-no-null-opt.ll
@@ -0,0 +1,34 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+; CHECK: @Y
+; CHECK: section ".foo"
+
+%struct.xyz = type { double, i32 }
+
+@Y = internal global %struct.xyz* null ,section ".foo" ; <%struct.xyz**> [#uses=2]
+@numf2s = external global i32 ; <i32*> [#uses=1]
+
+define void @init_net() #0 {
+; CHECK-LABEL: init_net(
+; CHECK: load i32, i32* @numf2s
+; CHECK: call i8* @malloc
+; CHECK: store %struct.xyz* {{.*}}, %struct.xyz** @Y
+entry:
+ %0 = load i32, i32* @numf2s, align 4 ; <i32> [#uses=1]
+ %mallocsize2 = shl i32 %0, 4 ; <i32> [#uses=1]
+ %malloccall3 = tail call i8* @malloc(i32 %mallocsize2) ; <i8*> [#uses=1]
+ %1 = bitcast i8* %malloccall3 to %struct.xyz* ; <%struct.xyz*> [#uses=1]
+ store %struct.xyz* %1, %struct.xyz** @Y, align 8
+ ret void
+}
+
+define %struct.xyz* @load_train() #0 {
+; CHECK-LABEL: load_train(
+; CHECK: load %struct.xyz*, %struct.xyz** @Y
+entry:
+ %0 = load %struct.xyz*, %struct.xyz** @Y, align 8 ; <%struct.xyz*> [#uses=0]
+ ret %struct.xyz* %0
+}
+
+declare noalias i8* @malloc(i32)
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll b/llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll
new file mode 100644
index 00000000000..75b3cfec137
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/MallocSROA-section.ll
@@ -0,0 +1,28 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+; CHECK: @Y.f0
+; CHECK: section ".foo"
+; CHECK: @Y.f1
+; CHECK: section ".foo"
+
+%struct.xyz = type { double, i32 }
+
+@Y = internal global %struct.xyz* null ,section ".foo" ; <%struct.xyz**> [#uses=2]
+@numf2s = external global i32 ; <i32*> [#uses=1]
+
+define void @init_net() {
+entry:
+ %0 = load i32, i32* @numf2s, align 4 ; <i32> [#uses=1]
+ %mallocsize2 = shl i32 %0, 4 ; <i32> [#uses=1]
+ %malloccall3 = tail call i8* @malloc(i32 %mallocsize2) ; <i8*> [#uses=1]
+ %1 = bitcast i8* %malloccall3 to %struct.xyz* ; <%struct.xyz*> [#uses=1]
+ store %struct.xyz* %1, %struct.xyz** @Y, align 8
+ ret void
+}
+
+define void @load_train() {
+entry:
+ %0 = load %struct.xyz*, %struct.xyz** @Y, align 8 ; <%struct.xyz*> [#uses=0]
+ ret void
+}
+
+declare noalias i8* @malloc(i32)
diff --git a/llvm/test/Transforms/GlobalOpt/PowerPC/coldcc_coldsites.ll b/llvm/test/Transforms/GlobalOpt/PowerPC/coldcc_coldsites.ll
new file mode 100644
index 00000000000..8fedf834f40
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/PowerPC/coldcc_coldsites.ll
@@ -0,0 +1,81 @@
+; RUN: opt -globalopt -mtriple=powerpc64le-unknown-linux-gnu -ppc-enable-coldcc -S < %s | FileCheck %s -check-prefix=COLDCC
+; RUN: opt -globalopt -S < %s | FileCheck %s -check-prefix=CHECK
+
+define signext i32 @caller(i32 signext %a, i32 signext %b, i32 signext %lim, i32 signext %i) local_unnamed_addr #0 !prof !30 {
+entry:
+; COLDCC: call coldcc signext i32 @callee
+; CHECK: call fastcc signext i32 @callee
+ %add = add nsw i32 %b, %a
+ %sub = add nsw i32 %lim, -1
+ %cmp = icmp eq i32 %sub, %i
+ br i1 %cmp, label %if.then, label %if.end, !prof !31
+
+if.then: ; preds = %entry
+ %call = tail call signext i32 @callee(i32 signext %a, i32 signext %b)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %f.0 = phi i32 [ %call, %if.then ], [ %add, %entry ]
+ ret i32 %f.0
+}
+
+define internal signext i32 @callee(i32 signext %a, i32 signext %b) unnamed_addr #0 {
+entry:
+ %0 = tail call i32 asm "add $0, $1, $2", "=r,r,r,~{r6},~{r7},~{r8},~{r9}"(i32 %a, i32 %b) #1, !srcloc !32
+ %mul = mul nsw i32 %a, 3
+ %mul1 = shl i32 %0, 1
+ %add = add nsw i32 %mul1, %mul
+ ret i32 %add
+}
+
+define signext i32 @main() local_unnamed_addr #0 !prof !33 {
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %for.body
+ %add.lcssa = phi i32 [ %add, %for.body ]
+ ret i32 %add.lcssa
+
+for.body: ; preds = %for.body, %entry
+ %i.011 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %ret.010 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %call = tail call signext i32 @caller(i32 signext 4, i32 signext 5, i32 signext 10000000, i32 signext %i.011)
+ %add = add nsw i32 %call, %ret.010
+ %inc = add nuw nsw i32 %i.011, 1
+ %exitcond = icmp eq i32 %inc, 10000000
+ br i1 %exitcond, label %for.cond.cleanup, label %for.body, !prof !34
+}
+attributes #0 = { noinline }
+
+!0 = !{i32 1, !"ProfileSummary", !1}
+!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
+!2 = !{!"ProfileFormat", !"InstrProf"}
+!3 = !{!"TotalCount", i64 20000003}
+!4 = !{!"MaxCount", i64 10000000}
+!5 = !{!"MaxInternalCount", i64 10000000}
+!6 = !{!"MaxFunctionCount", i64 10000000}
+!7 = !{!"NumCounts", i64 5}
+!8 = !{!"NumFunctions", i64 3}
+!9 = !{!"DetailedSummary", !10}
+!10 = !{!11, !12, !13, !14, !15, !16, !16, !17, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26}
+!11 = !{i32 10000, i64 10000000, i32 2}
+!12 = !{i32 100000, i64 10000000, i32 2}
+!13 = !{i32 200000, i64 10000000, i32 2}
+!14 = !{i32 300000, i64 10000000, i32 2}
+!15 = !{i32 400000, i64 10000000, i32 2}
+!16 = !{i32 500000, i64 10000000, i32 2}
+!17 = !{i32 600000, i64 10000000, i32 2}
+!18 = !{i32 700000, i64 10000000, i32 2}
+!19 = !{i32 800000, i64 10000000, i32 2}
+!20 = !{i32 900000, i64 10000000, i32 2}
+!21 = !{i32 950000, i64 10000000, i32 2}
+!22 = !{i32 990000, i64 10000000, i32 2}
+!23 = !{i32 999000, i64 10000000, i32 2}
+!24 = !{i32 999900, i64 10000000, i32 2}
+!25 = !{i32 999990, i64 10000000, i32 2}
+!26 = !{i32 999999, i64 10000000, i32 2}
+!30 = !{!"function_entry_count", i64 10000000}
+!31 = !{!"branch_weights", i32 2, i32 10000000}
+!32 = !{i32 59}
+!33 = !{!"function_entry_count", i64 1}
+!34 = !{!"branch_weights", i32 2, i32 10000001}
diff --git a/llvm/test/Transforms/GlobalOpt/PowerPC/lit.local.cfg b/llvm/test/Transforms/GlobalOpt/PowerPC/lit.local.cfg
new file mode 100644
index 00000000000..5d33887ff0a
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/PowerPC/lit.local.cfg
@@ -0,0 +1,3 @@
+if not 'PowerPC' in config.root.targets:
+ config.unsupported = True
+
diff --git a/llvm/test/Transforms/GlobalOpt/SROA-section.ll b/llvm/test/Transforms/GlobalOpt/SROA-section.ll
new file mode 100644
index 00000000000..1589608a67a
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/SROA-section.ll
@@ -0,0 +1,27 @@
+; Verify that section assignment is copied during SROA
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: @G.0
+; CHECK: section ".foo"
+; CHECK: @G.1
+; CHECK: section ".foo"
+; CHECK: @G.2
+; CHECK: section ".foo"
+
+%T = type { double, double, double }
+@G = internal global %T zeroinitializer, align 16, section ".foo"
+
+define void @test() {
+ store double 1.0, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
+ store double 2.0, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
+ store double 3.0, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
+ ret void
+}
+
+define double @test2() {
+ %V1 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 0), align 16
+ %V2 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 1), align 8
+ %V3 = load double, double* getelementptr (%T, %T* @G, i32 0, i32 2), align 16
+ %R = fadd double %V1, %V2
+ %R2 = fadd double %R, %V3
+ ret double %R2
+}
diff --git a/llvm/test/Transforms/GlobalOpt/alias-resolve.ll b/llvm/test/Transforms/GlobalOpt/alias-resolve.ll
new file mode 100644
index 00000000000..46b90ec29b9
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/alias-resolve.ll
@@ -0,0 +1,46 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@foo1 = alias void (), void ()* @foo2
+; CHECK: @foo1 = alias void (), void ()* @bar2
+
+@foo2 = alias void(), void()* @bar1
+; CHECK: @foo2 = alias void (), void ()* @bar2
+
+@bar1 = alias void (), void ()* @bar2
+; CHECK: @bar1 = alias void (), void ()* @bar2
+
+@weak1 = weak alias void (), void ()* @bar2
+; CHECK: @weak1 = weak alias void (), void ()* @bar2
+
+@bar4 = private unnamed_addr constant [2 x i8*] zeroinitializer
+@foo4 = weak_odr unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @bar4, i32 0, i32 1)
+; CHECK: @foo4 = weak_odr unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @bar4, i32 0, i32 1)
+
+define void @bar2() {
+ ret void
+}
+; CHECK: define void @bar2()
+
+define void @baz() {
+entry:
+ call void @foo1()
+; CHECK: call void @bar2()
+
+ call void @foo2()
+; CHECK: call void @bar2()
+
+ call void @bar1()
+; CHECK: call void @bar2()
+
+ call void @weak1()
+; CHECK: call void @weak1()
+ ret void
+}
+
+@foo3 = alias void (), void ()* @bar3
+; CHECK-NOT: bar3
+
+define internal void @bar3() {
+ ret void
+}
+;CHECK: define void @foo3
diff --git a/llvm/test/Transforms/GlobalOpt/alias-used-address-space.ll b/llvm/test/Transforms/GlobalOpt/alias-used-address-space.ll
new file mode 100644
index 00000000000..08081b89ac6
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/alias-used-address-space.ll
@@ -0,0 +1,26 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+target datalayout = "p:32:32:32-p1:16:16:16"
+
+@c = addrspace(1) global i8 42
+
+@i = internal addrspace(1) global i8 42
+
+; CHECK: @ia = internal addrspace(1) global i8 42
+@ia = internal alias i8, i8 addrspace(1)* @i
+
+@llvm.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ca to i8*)], section "llvm.metadata"
+; CHECK-DAG: @llvm.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ca to i8*)], section "llvm.metadata"
+
+@llvm.compiler.used = appending global [2 x i8*] [i8* addrspacecast(i8 addrspace(1)* @ia to i8*), i8* addrspacecast (i8 addrspace(1)* @i to i8*)], section "llvm.metadata"
+; CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ia to i8*)], section "llvm.metadata"
+
+@sameAsUsed = global [1 x i8*] [i8* addrspacecast(i8 addrspace(1)* @ca to i8*)]
+; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]
+
+@ca = internal alias i8, i8 addrspace(1)* @c
+; CHECK: @ca = internal alias i8, i8 addrspace(1)* @c
+
+define i8 addrspace(1)* @h() {
+ ret i8 addrspace(1)* @ca
+}
diff --git a/llvm/test/Transforms/GlobalOpt/alias-used-section.ll b/llvm/test/Transforms/GlobalOpt/alias-used-section.ll
new file mode 100644
index 00000000000..a3657dfd16b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/alias-used-section.ll
@@ -0,0 +1,8 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+@_Z17in_custom_section = internal global i8 42, section "CUSTOM"
+@in_custom_section = internal dllexport alias i8, i8* @_Z17in_custom_section
+
+; CHECK: @in_custom_section = internal dllexport global i8 42, section "CUSTOM"
+
+@llvm.used = appending global [1 x i8*] [i8* @in_custom_section], section "llvm.metadata"
diff --git a/llvm/test/Transforms/GlobalOpt/alias-used.ll b/llvm/test/Transforms/GlobalOpt/alias-used.ll
new file mode 100644
index 00000000000..91601fb9927
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/alias-used.ll
@@ -0,0 +1,66 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@c = global i8 42
+
+@i = internal global i8 42
+; CHECK: @ia = internal global i8 42
+@ia = internal alias i8, i8* @i
+
+@llvm.used = appending global [3 x i8*] [i8* bitcast (void ()* @fa to i8*), i8* bitcast (void ()* @f to i8*), i8* @ca], section "llvm.metadata"
+; CHECK-DAG: @llvm.used = appending global [3 x i8*] [i8* @ca, i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @fa to i8*)], section "llvm.metadata"
+
+@llvm.compiler.used = appending global [4 x i8*] [i8* bitcast (void ()* @fa3 to i8*), i8* bitcast (void ()* @fa to i8*), i8* @ia, i8* @i], section "llvm.metadata"
+; CHECK-DAG: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @fa3 to i8*), i8* @ia], section "llvm.metadata"
+
+@sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @fa to i8*), i8* bitcast (void ()* @f to i8*), i8* @ca]
+; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]
+
+@other = global i32* bitcast (void ()* @fa to i32*)
+; CHECK-DAG: @other = local_unnamed_addr global i32* bitcast (void ()* @f to i32*)
+
+@fa = internal alias void (), void ()* @f
+; CHECK: @fa = internal alias void (), void ()* @f
+
+@fa2 = internal alias void (), void ()* @f
+; CHECK-NOT: @fa2
+
+@fa3 = internal alias void (), void ()* @f
+; CHECK: @fa3
+
+@ca = internal alias i8, i8* @c
+; CHECK: @ca = internal alias i8, i8* @c
+
+define void @f() {
+ ret void
+}
+
+define i8* @g() {
+ ret i8* bitcast (void ()* @fa to i8*);
+}
+
+define i8* @g2() {
+ ret i8* bitcast (void ()* @fa2 to i8*);
+}
+
+define i8* @h() {
+ ret i8* @ca
+}
+
+; Check that GlobalOpt doesn't try to resolve aliases with GEP operands.
+
+%struct.S = type { i32, i32, i32 }
+@s = global %struct.S { i32 1, i32 2, i32 3 }, align 4
+
+@alias1 = alias i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i64 0, i32 1)
+@alias2 = alias i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i64 0, i32 2)
+
+; CHECK: load i32, i32* @alias1, align 4
+; CHECK: load i32, i32* @alias2, align 4
+
+define i32 @foo1() {
+entry:
+ %0 = load i32, i32* @alias1, align 4
+ %1 = load i32, i32* @alias2, align 4
+ %add = add nsw i32 %1, %0
+ ret i32 %add
+}
diff --git a/llvm/test/Transforms/GlobalOpt/amdgcn-ctor-alloca.ll b/llvm/test/Transforms/GlobalOpt/amdgcn-ctor-alloca.ll
new file mode 100644
index 00000000000..6bdcf49e95e
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/amdgcn-ctor-alloca.ll
@@ -0,0 +1,17 @@
+; RUN: opt -data-layout=A5 -globalopt %s -S -o - | FileCheck %s
+
+; CHECK-NOT: @g
+@g = internal addrspace(1) global i32* zeroinitializer
+
+; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
+ [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
+
+; CHECK-NOT: @ctor
+define internal void @ctor() {
+ %addr = alloca i32, align 8, addrspace(5)
+ %tmp = addrspacecast i32 addrspace(5)* %addr to i32*
+ store i32* %tmp, i32* addrspace(1)* @g
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/array-elem-refs.ll b/llvm/test/Transforms/GlobalOpt/array-elem-refs.ll
new file mode 100644
index 00000000000..c31965b656d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/array-elem-refs.ll
@@ -0,0 +1,32 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.S = type { i8, i8 }
+
+@c = internal global i8** bitcast (i8* getelementptr (i8, i8* bitcast ([8 x i8*]* @b to i8*), i64 48) to i8**), align 8
+@b = internal global [8 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* getelementptr inbounds (%struct.S, %struct.S* @a, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S, %struct.S* @a, i32 0, i32 0), i64 1)], align 16
+@a = internal global %struct.S zeroinitializer, align 1
+
+; Function Attrs: nounwind uwtable
+define signext i8 @foo() #0 {
+entry:
+ %0 = load i8**, i8*** @c, align 8
+ %1 = load i8*, i8** %0, align 8
+ %2 = load i8, i8* %1, align 1
+ ret i8 %2
+
+; CHECK-LABEL: @foo
+; CHECK: ret i8 0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, i32* %retval
+ ret i32 0
+}
+
+attributes #0 = { nounwind uwtable }
+
diff --git a/llvm/test/Transforms/GlobalOpt/assume.ll b/llvm/test/Transforms/GlobalOpt/assume.ll
new file mode 100644
index 00000000000..b15106bc83a
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/assume.ll
@@ -0,0 +1,21 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; CHECK: @tmp = local_unnamed_addr global i32 42
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+@tmp = global i32 0
+
+define i32 @TheAnswerToLifeTheUniverseAndEverything() {
+ ret i32 42
+}
+
+define void @_GLOBAL__I_a() {
+enter:
+ %tmp1 = call i32 @TheAnswerToLifeTheUniverseAndEverything()
+ store i32 %tmp1, i32* @tmp
+ %cmp = icmp eq i32 %tmp1, 42
+ call void @llvm.assume(i1 %cmp)
+ ret void
+}
+
+declare void @llvm.assume(i1)
diff --git a/llvm/test/Transforms/GlobalOpt/atexit.ll b/llvm/test/Transforms/GlobalOpt/atexit.ll
new file mode 100644
index 00000000000..55c2dab1c1d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/atexit.ll
@@ -0,0 +1,6 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; CHECK: ModuleID
+define internal i32 @__cxa_atexit(void (i8*)* nocapture %func, i8* nocapture %arg, i8* nocapture %dso_handle) nounwind readnone optsize noimplicitfloat {
+ unreachable
+}
diff --git a/llvm/test/Transforms/GlobalOpt/atomic.ll b/llvm/test/Transforms/GlobalOpt/atomic.ll
new file mode 100644
index 00000000000..563c1fec7d2
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/atomic.ll
@@ -0,0 +1,25 @@
+; RUN: opt -globalopt < %s -S -o - | FileCheck %s
+
+@GV1 = internal global i64 1
+@GV2 = internal global i32 0
+
+; CHECK: @GV1 = internal unnamed_addr constant i64 1
+; CHECK: @GV2 = internal unnamed_addr global i32 0
+
+define void @test1() {
+entry:
+ %0 = load atomic i8, i8* bitcast (i64* @GV1 to i8*) acquire, align 8
+ ret void
+}
+
+; PR17163
+define void @test2a() {
+entry:
+ store atomic i32 10, i32* @GV2 seq_cst, align 4
+ ret void
+}
+define i32 @test2b() {
+entry:
+ %atomic-load = load atomic i32, i32* @GV2 seq_cst, align 4
+ ret i32 %atomic-load
+}
diff --git a/llvm/test/Transforms/GlobalOpt/available_externally_global_ctors.ll b/llvm/test/Transforms/GlobalOpt/available_externally_global_ctors.ll
new file mode 100644
index 00000000000..7092a5ae222
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/available_externally_global_ctors.ll
@@ -0,0 +1,22 @@
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; Verify that the initialization of the available_externally global is not eliminated
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo_static_init, i8* null }]
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo_static_init, i8* null }]
+@foo_external = available_externally global void ()* null
+
+define internal void @foo_static_init() {
+entry:
+ store void ()* @foo_impl, void ()** @foo_external
+ ret void
+}
+
+define internal void @foo_impl() {
+entry:
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/basictest.ll b/llvm/test/Transforms/GlobalOpt/basictest.ll
new file mode 100644
index 00000000000..d5294820abe
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/basictest.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; RUN: opt < %s -passes=globalopt -S | FileCheck %s
+
+; CHECK-NOT: global
+@X = internal global i32 4 ; <i32*> [#uses=1]
+
+define i32 @foo() {
+ %V = load i32, i32* @X ; <i32> [#uses=1]
+ ret i32 %V
+}
diff --git a/llvm/test/Transforms/GlobalOpt/blockaddress.ll b/llvm/test/Transforms/GlobalOpt/blockaddress.ll
new file mode 100644
index 00000000000..12e09fcd481
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/blockaddress.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@x = internal global i8* zeroinitializer
+
+define void @f() {
+; CHECK-LABEL: @f(
+
+; Check that we don't hit an assert in Constant::IsThreadDependent()
+; when storing this blockaddress into a global.
+
+ store i8* blockaddress(@g, %here), i8** @x, align 8
+ ret void
+}
+
+define void @g() {
+entry:
+ br label %here
+
+; CHECK-LABEL: @g(
+
+here:
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll
new file mode 100644
index 00000000000..16da5315db0
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll
@@ -0,0 +1,49 @@
+; RUN: opt -globalopt -S -o - < %s | FileCheck %s
+
+@glbl = internal global i8* null
+
+define void @test1a() {
+; CHECK-LABEL: @test1a(
+; CHECK-NOT: store
+; CHECK-NEXT: ret void
+ store i8* null, i8** @glbl
+ ret void
+}
+
+define void @test1b(i8* %p) {
+; CHECK-LABEL: @test1b(
+; CHECK-NEXT: store
+; CHECK-NEXT: ret void
+ store i8* %p, i8** @glbl
+ ret void
+}
+
+define void @test2() {
+; CHECK-LABEL: @test2(
+; CHECK: alloca i8
+ %txt = alloca i8
+ call void @foo2(i8* %txt)
+ %call2 = call i8* @strdup(i8* %txt)
+ store i8* %call2, i8** @glbl
+ ret void
+}
+declare i8* @strdup(i8*)
+declare void @foo2(i8*)
+
+define void @test3() uwtable personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 {
+; CHECK-LABEL: @test3(
+; CHECK-NOT: bb1:
+; CHECK-NOT: bb2:
+; CHECK: invoke
+ %ptr = invoke i8* @_Znwm(i64 1)
+ to label %bb1 unwind label %bb2
+bb1:
+ store i8* %ptr, i8** @glbl
+ unreachable
+bb2:
+ %tmp1 = landingpad { i8*, i32 }
+ cleanup
+ resume { i8*, i32 } %tmp1
+}
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+declare i8* @_Znwm(i64)
diff --git a/llvm/test/Transforms/GlobalOpt/coldcc_stress_test.ll b/llvm/test/Transforms/GlobalOpt/coldcc_stress_test.ll
new file mode 100644
index 00000000000..80c9366af6f
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/coldcc_stress_test.ll
@@ -0,0 +1,48 @@
+; RUN: opt < %s -globalopt -S -enable-coldcc-stress-test -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s -check-prefix=COLDCC
+; RUN: opt < %s -globalopt -S | FileCheck %s -check-prefix=CHECK
+
+define internal i32 @callee_default(i32* %m) {
+; COLDCC-LABEL: define internal coldcc i32 @callee_default
+; CHECK-LABEL: define internal fastcc i32 @callee_default
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define internal fastcc i32 @callee_fastcc(i32* %m) {
+; COLDCC-LABEL: define internal fastcc i32 @callee_fastcc
+; CHECK-LABEL: define internal fastcc i32 @callee_fastcc
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define internal coldcc i32 @callee_coldcc(i32* %m) {
+; COLDCC-LABEL: define internal coldcc i32 @callee_coldcc
+; CHECK-LABEL: define internal coldcc i32 @callee_coldcc
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define i32 @callee(i32* %m) {
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define void @caller() {
+ %m = alloca i32
+ call i32 @callee_default(i32* %m)
+ call fastcc i32 @callee_fastcc(i32* %m)
+ call coldcc i32 @callee_coldcc(i32* %m)
+ call i32 @callee(i32* %m)
+ ret void
+}
+
+; COLDCC-LABEL: define void @caller()
+; COLDCC: call coldcc i32 @callee_default
+; COLDCC: call fastcc i32 @callee_fastcc
+; COLDCC: call coldcc i32 @callee_coldcc
+; COLDCC: call i32 @callee
+; CHECK-LABEL: define void @caller()
+; CHECK: call fastcc i32 @callee_default
+; CHECK: call fastcc i32 @callee_fastcc
+; CHECK: call coldcc i32 @callee_coldcc
+; CHECK: call i32 @callee
diff --git a/llvm/test/Transforms/GlobalOpt/compiler-used.ll b/llvm/test/Transforms/GlobalOpt/compiler-used.ll
new file mode 100644
index 00000000000..a710d272edc
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/compiler-used.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; Test that when all members of llvm.compiler.used are found to be redundant
+; we delete it instead of crashing.
+
+define void @foo() {
+ ret void
+}
+
+@llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata"
+
+@llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata"
+
+; CHECK-NOT: @llvm.compiler.used
+; CHECK: @llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata"
+; CHECK-NOT: @llvm.compiler.used
diff --git a/llvm/test/Transforms/GlobalOpt/constantexpr-dangle.ll b/llvm/test/Transforms/GlobalOpt/constantexpr-dangle.ll
new file mode 100644
index 00000000000..3917bfff411
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/constantexpr-dangle.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine -globalopt -S | FileCheck %s
+; CHECK: internal fastcc float @foo
+
+define internal float @foo() {
+ ret float 0.000000e+00
+}
+
+define float @bar() {
+ %tmp1 = call float (...) bitcast (float ()* @foo to float (...)*)( )
+ %tmp2 = fmul float %tmp1, 1.000000e+01 ; <float> [#uses=1]
+ ret float %tmp2
+}
diff --git a/llvm/test/Transforms/GlobalOpt/constantfold-initializers.ll b/llvm/test/Transforms/GlobalOpt/constantfold-initializers.ll
new file mode 100644
index 00000000000..3c20353d157
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/constantfold-initializers.ll
@@ -0,0 +1,103 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+
+@.str91250 = global [3 x i8] zeroinitializer
+
+; CHECK: @A = local_unnamed_addr global i1 false
+@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)
+
+; PR11352
+
+@xs = global [2 x i32] zeroinitializer, align 4
+; CHECK: @xs = local_unnamed_addr global [2 x i32] [i32 1, i32 1]
+
+; PR12642
+%PR12642.struct = type { i8 }
+@PR12642.s = global <{}> zeroinitializer, align 1
+@PR12642.p = constant %PR12642.struct* bitcast (i8* getelementptr (i8, i8* bitcast (<{}>* @PR12642.s to i8*), i64 1) to %PR12642.struct*), align 8
+
+define internal void @test1() {
+entry:
+ store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @xs, i64 0, i64 0)
+ %0 = load i32, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @xs, i32 0, i64 0), align 4
+ store i32 %0, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @xs, i64 0, i64 1)
+ ret void
+}
+
+; PR12060
+
+%closure = type { i32 }
+
+@f = internal global %closure zeroinitializer, align 4
+@m = global i32 0, align 4
+; CHECK-NOT: @f
+; CHECK: @m = local_unnamed_addr global i32 13
+
+define internal i32 @test2_helper(%closure* %this, i32 %b) {
+entry:
+ %0 = getelementptr inbounds %closure, %closure* %this, i32 0, i32 0
+ %1 = load i32, i32* %0, align 4
+ %add = add nsw i32 %1, %b
+ ret i32 %add
+}
+
+define internal void @test2() {
+entry:
+ store i32 4, i32* getelementptr inbounds (%closure, %closure* @f, i32 0, i32 0)
+ %call = call i32 @test2_helper(%closure* @f, i32 9)
+ store i32 %call, i32* @m, align 4
+ ret void
+}
+
+; PR19955
+
+@dllimportptr = global i32* null, align 4
+; CHECK: @dllimportptr = local_unnamed_addr global i32* null, align 4
+@dllimportvar = external dllimport global i32
+define internal void @test3() {
+entry:
+ store i32* @dllimportvar, i32** @dllimportptr, align 4
+ ret void
+}
+
+@dllexportptr = global i32* null, align 4
+; CHECK: @dllexportptr = local_unnamed_addr global i32* @dllexportvar, align 4
+@dllexportvar = dllexport global i32 0, align 4
+; CHECK: @dllexportvar = dllexport global i32 20, align 4
+define internal void @test4() {
+entry:
+ store i32 20, i32* @dllexportvar, align 4
+ store i32* @dllexportvar, i32** @dllexportptr, align 4
+ ret void
+}
+
+@threadlocalptr = global i32* null, align 4
+; CHECK: @threadlocalptr = global i32* null, align 4
+@threadlocalvar = external thread_local global i32
+define internal void @test5() {
+entry:
+ store i32* @threadlocalvar, i32** @threadlocalptr, align 4
+ ret void
+}
+
+@test6_v1 = internal global { i32, i32 } { i32 42, i32 0 }, align 8
+@test6_v2 = global i32 0, align 4
+; CHECK: @test6_v2 = local_unnamed_addr global i32 42, align 4
+define internal void @test6() {
+ %load = load { i32, i32 }, { i32, i32 }* @test6_v1, align 8
+ %xv0 = extractvalue { i32, i32 } %load, 0
+ %iv = insertvalue { i32, i32 } %load, i32 %xv0, 1
+ %xv1 = extractvalue { i32, i32 } %iv, 1
+ store i32 %xv1, i32* @test6_v2, align 4
+ ret void
+}
+
+@llvm.global_ctors = appending constant
+ [6 x { i32, void ()* }]
+ [{ i32, void ()* } { i32 65535, void ()* @test1 },
+ { i32, void ()* } { i32 65535, void ()* @test2 },
+ { i32, void ()* } { i32 65535, void ()* @test3 },
+ { i32, void ()* } { i32 65535, void ()* @test4 },
+ { i32, void ()* } { i32 65535, void ()* @test5 },
+ { i32, void ()* } { i32 65535, void ()* @test6 }]
diff --git a/llvm/test/Transforms/GlobalOpt/crash-2.ll b/llvm/test/Transforms/GlobalOpt/crash-2.ll
new file mode 100644
index 00000000000..748fb027c7d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/crash-2.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | opt -globalopt -disable-output
+; NOTE: This needs to run through 'llvm-as' first to reproduce the error!
+; PR15440
+
+%union.U5.0.6.12 = type { i32 }
+%struct.S0.1.7.13 = type { i8, i8, i8, i8, i16, [2 x i8] }
+%struct.S1.2.8.14 = type { i32, i16, i8, i8 }
+
+@.str = external unnamed_addr constant [2 x i8], align 1
+@g_25 = external global i8, align 1
+@g_71 = internal global %struct.S0.1.7.13 { i8 1, i8 -93, i8 58, i8 -1, i16 -5, [2 x i8] undef }, align 4
+@g_114 = external global i8, align 1
+@g_30 = external global { i32, i8, i32, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 }, align 4
+@g_271 = internal global [7 x [6 x [5 x i8*]]] [[6 x [5 x i8*]] [[5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* null], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114, i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* null, i8* null], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)]], [6 x [5 x i8*]] [[5 x i8*] [i8* @g_25, i8* null, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* @g_25, i8* @g_114, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25], [5 x i8*] [i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* @g_25, i8* @g_25, i8* @g_25], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)]], [6 x [5 x i8*]] [[5 x i8*] [i8* null, i8* @g_25, i8* @g_25, i8* @g_25, i8* null], [5 x i8*] [i8* @g_25, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* null, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* null, i8* @g_25], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* null], [5 x i8*] [i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)]], [6 x [5 x i8*]] [[5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* null, i8* @g_25], [5 x i8*] [i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* @g_25, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* @g_25], [5 x i8*] [i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* @g_114, i8* @g_25, i8* @g_25, i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)]], [6 x [5 x i8*]] [[5 x i8*] [i8* @g_25, i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* @g_25], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_114], [5 x i8*] [i8* @g_25, i8* null, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* null], [5 x i8*] [i8* @g_114, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114, i8* @g_25]], [6 x [5 x i8*]] [[5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* @g_114, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0)], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25]], [6 x [5 x i8*]] [[5 x i8*] [i8* @g_25, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* null], [5 x i8*] [i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114, i8* @g_25, i8* @g_25, i8* @g_114], [5 x i8*] [i8* null, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_25, i8* null, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_114, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* @g_114, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1)], [5 x i8*] [i8* @g_25, i8* @g_25, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25], [5 x i8*] [i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25, i8* @g_25, i8* getelementptr (i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), i64 1), i8* @g_25]]], align 4
+
+define i32 @func() {
+ %tmp = load i8, i8* getelementptr inbounds (%struct.S0.1.7.13, %struct.S0.1.7.13* @g_71, i32 0, i32 0), align 1
+ ret i32 0
+}
diff --git a/llvm/test/Transforms/GlobalOpt/crash.ll b/llvm/test/Transforms/GlobalOpt/crash.ll
new file mode 100644
index 00000000000..8cfe9ea0570
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/crash.ll
@@ -0,0 +1,80 @@
+; RUN: opt -globalopt -disable-output < %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
+target triple = "i386-apple-darwin9.8"
+
+%0 = type { i32, void ()* }
+%struct.btSimdScalar = type { %"union.btSimdScalar::$_14" }
+%"union.btSimdScalar::$_14" = type { <4 x float> }
+
+@_ZL6vTwist = global %struct.btSimdScalar zeroinitializer ; <%struct.btSimdScalar*> [#uses=1]
+@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev }] ; <[12 x %0]*> [#uses=0]
+
+define internal void @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
+entry:
+ store float 1.0, float* getelementptr inbounds (%struct.btSimdScalar, %struct.btSimdScalar* @_ZL6vTwist, i32 0, i32 0, i32 0, i32 3), align 4
+ ret void
+}
+
+
+; PR6760
+%T = type { [5 x i32] }
+
+@switch_inf = internal global %T* null
+
+define void @test(i8* %arch_file, i32 %route_type) {
+entry:
+ %A = sext i32 1 to i64
+ %B = mul i64 %A, 20
+ %C = call noalias i8* @malloc(i64 %B) nounwind
+ %D = bitcast i8* %C to %T*
+ store %T* %D, %T** @switch_inf, align 8
+ unreachable
+
+bb.nph.i:
+ %scevgep.i539 = getelementptr i8, i8* %C, i64 4
+ unreachable
+
+xx:
+ %E = load %T*, %T** @switch_inf, align 8
+ unreachable
+}
+
+declare noalias i8* @malloc(i64) nounwind
+
+
+; PR8063
+@permute_bitrev.bitrev = internal global i32* null, align 8
+define void @permute_bitrev() nounwind {
+entry:
+ %tmp = load i32*, i32** @permute_bitrev.bitrev, align 8
+ %conv = sext i32 0 to i64
+ %mul = mul i64 %conv, 4
+ %call = call i8* @malloc(i64 %mul)
+ %0 = bitcast i8* %call to i32*
+ store i32* %0, i32** @permute_bitrev.bitrev, align 8
+ ret void
+}
+
+
+
+
+@data8 = internal global [8000 x i8] zeroinitializer, align 16
+define void @memset_with_strange_user() ssp {
+ call void @llvm.memset.p0i8.i64(i8* align 16 getelementptr inbounds ([8000 x i8], [8000 x i8]* @data8, i64 0, i64 0), i8 undef, i64 ptrtoint (i8* getelementptr ([8000 x i8], [8000 x i8]* @data8, i64 1, i64 sub (i64 0, i64 ptrtoint ([8000 x i8]* @data8 to i64))) to i64), i1 false)
+ ret void
+}
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
+
+
+; PR9856
+@g_52 = internal global i32** null, align 8
+@g_90 = external global i32*, align 8
+
+define void @icmp_user_of_stored_once() nounwind ssp {
+entry:
+ %tmp4 = load i32**, i32*** @g_52, align 8
+ store i32** @g_90, i32*** @g_52
+ %cmp17 = icmp ne i32*** undef, @g_52
+ ret void
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll b/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
new file mode 100644
index 00000000000..0c3ff68a437
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
@@ -0,0 +1,34 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.0.0"
+
+%0 = type { i32, void ()* }
+%struct.foo = type { i32* }
+%struct.bar = type { i128 }
+
+@G = global i32 0, align 4
+@H = global i32 0, align 4
+@X = global %struct.foo zeroinitializer, align 8
+@X2 = global %struct.bar zeroinitializer, align 8
+@llvm.global_ctors = appending global [2 x %0] [%0 { i32 65535, void ()* @init1 }, %0 { i32 65535, void ()* @init2 }]
+
+; PR8710 - GlobalOpt shouldn't change the global's initializer to have this
+; arbitrary constant expression, the code generator can't handle it.
+define internal void @init1() {
+entry:
+ %tmp = getelementptr inbounds %struct.foo, %struct.foo* @X, i32 0, i32 0
+ store i32* inttoptr (i64 sdiv (i64 ptrtoint (i32* @G to i64), i64 ptrtoint (i32* @H to i64)) to i32*), i32** %tmp, align 8
+ ret void
+}
+; CHECK-LABEL: @init1(
+; CHECK: store i32*
+
+; PR11705 - ptrtoint isn't safe in general in global initializers.
+define internal void @init2() {
+entry:
+ %tmp = getelementptr inbounds %struct.bar, %struct.bar* @X2, i32 0, i32 0
+ store i128 ptrtoint (i32* @G to i128), i128* %tmp, align 16
+ ret void
+}
+; CHECK-LABEL: @init2(
+; CHECK: store i128
diff --git a/llvm/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll b/llvm/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
new file mode 100644
index 00000000000..b969345710d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; Don't get fooled by the inbounds keyword; it doesn't change
+; the computed address.
+
+; CHECK: @H = local_unnamed_addr global i32 2
+; CHECK: @I = local_unnamed_addr global i32 2
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
+@addr = external global i32
+@G = internal global [6 x [5 x i32]] zeroinitializer
+@H = global i32 80
+@I = global i32 90
+
+define internal void @CTOR() {
+ store i32 1, i32* getelementptr ([6 x [5 x i32]], [6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ store i32 2, i32* getelementptr inbounds ([6 x [5 x i32]], [6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ %t = load i32, i32* getelementptr ([6 x [5 x i32]], [6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ store i32 %t, i32* @H
+ %s = load i32, i32* getelementptr inbounds ([6 x [5 x i32]], [6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ store i32 %s, i32* @I
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/ctor-list-opt.ll b/llvm/test/Transforms/GlobalOpt/ctor-list-opt.ll
new file mode 100644
index 00000000000..95e7d4d1ab5
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/ctor-list-opt.ll
@@ -0,0 +1,115 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: CTOR
+%ini = type { i32, void()*, i8* }
+@llvm.global_ctors = appending global [11 x %ini] [
+ %ini { i32 65535, void ()* @CTOR1, i8* null },
+ %ini { i32 65535, void ()* @CTOR1, i8* null },
+ %ini { i32 65535, void ()* @CTOR2, i8* null },
+ %ini { i32 65535, void ()* @CTOR3, i8* null },
+ %ini { i32 65535, void ()* @CTOR4, i8* null },
+ %ini { i32 65535, void ()* @CTOR5, i8* null },
+ %ini { i32 65535, void ()* @CTOR6, i8* null },
+ %ini { i32 65535, void ()* @CTOR7, i8* null },
+ %ini { i32 65535, void ()* @CTOR8, i8* null },
+ %ini { i32 65535, void ()* @CTOR9, i8* null },
+ %ini { i32 2147483647, void ()* null, i8* null }
+]
+
+@G = global i32 0 ; <i32*> [#uses=1]
+@G2 = global i32 0 ; <i32*> [#uses=1]
+@G3 = global i32 -123 ; <i32*> [#uses=2]
+@X = global { i32, [2 x i32] } { i32 0, [2 x i32] [ i32 17, i32 21 ] } ; <{ i32, [2 x i32] }*> [#uses=2]
+@Y = global i32 -1 ; <i32*> [#uses=2]
+@Z = global i32 123 ; <i32*> [#uses=1]
+@D = global double 0.000000e+00 ; <double*> [#uses=1]
+@CTORGV = internal global i1 false ; <i1*> [#uses=2]
+
+define internal void @CTOR1() {
+ ret void
+}
+
+define internal void @CTOR2() {
+ %A = add i32 1, 23 ; <i32> [#uses=1]
+ store i32 %A, i32* @G
+ store i1 true, i1* @CTORGV
+ ret void
+}
+
+define internal void @CTOR3() {
+ %X = or i1 true, false ; <i1> [#uses=1]
+ br label %Cont
+
+Cont: ; preds = %0
+ br i1 %X, label %S, label %T
+
+S: ; preds = %Cont
+ store i32 24, i32* @G2
+ ret void
+
+T: ; preds = %Cont
+ ret void
+}
+
+define internal void @CTOR4() {
+ %X = load i32, i32* @G3 ; <i32> [#uses=1]
+ %Y = add i32 %X, 123 ; <i32> [#uses=1]
+ store i32 %Y, i32* @G3
+ ret void
+}
+
+define internal void @CTOR5() {
+ %X.2p = getelementptr inbounds { i32, [2 x i32] }, { i32, [2 x i32] }* @X, i32 0, i32 1, i32 0 ; <i32*> [#uses=2]
+ %X.2 = load i32, i32* %X.2p ; <i32> [#uses=1]
+ %X.1p = getelementptr inbounds { i32, [2 x i32] }, { i32, [2 x i32] }* @X, i32 0, i32 0 ; <i32*> [#uses=1]
+ store i32 %X.2, i32* %X.1p
+ store i32 42, i32* %X.2p
+ ret void
+}
+
+define internal void @CTOR6() {
+ %A = alloca i32 ; <i32*> [#uses=2]
+ %y = load i32, i32* @Y ; <i32> [#uses=1]
+ store i32 %y, i32* %A
+ %Av = load i32, i32* %A ; <i32> [#uses=1]
+ %Av1 = add i32 %Av, 1 ; <i32> [#uses=1]
+ store i32 %Av1, i32* @Y
+ ret void
+}
+
+define internal void @CTOR7() {
+ call void @setto( i32* @Z, i32 0 )
+ ret void
+}
+
+define void @setto(i32* %P, i32 %V) {
+ store i32 %V, i32* %P
+ ret void
+}
+
+declare double @cos(double)
+
+define internal void @CTOR8() {
+ %X = call double @cos( double 0.000000e+00 ) ; <double> [#uses=1]
+ store double %X, double* @D
+ ret void
+}
+
+define i1 @accessor() {
+ %V = load i1, i1* @CTORGV ; <i1> [#uses=1]
+ ret i1 %V
+}
+
+%struct.A = type { i32 }
+%struct.B = type { i32 (...)**, i8*, [4 x i8] }
+@GV1 = global %struct.B zeroinitializer, align 8
+@GV2 = constant [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* null, i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* null to i8*)]
+; CHECK-NOT: CTOR9
+define internal void @CTOR9() {
+entry:
+ %0 = bitcast %struct.B* @GV1 to i8*
+ %1 = getelementptr inbounds i8, i8* %0, i64 16
+ %2 = bitcast i8* %1 to %struct.A*
+ %3 = bitcast %struct.B* @GV1 to i8***
+ store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @GV2, i64 1, i64 0), i8*** %3
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/cxx-dtor.ll b/llvm/test/Transforms/GlobalOpt/cxx-dtor.ll
new file mode 100644
index 00000000000..c43a8e2be2e
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/cxx-dtor.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -S -passes='cgscc(inline),function(early-cse),globalopt' | FileCheck %s
+
+%0 = type { i32, void ()* }
+%struct.A = type { i8 }
+%struct.B = type { }
+
+@a = global %struct.A zeroinitializer, align 1
+@__dso_handle = external global i8*
+@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I_a }]
+
+; CHECK-NOT: call i32 @__cxa_atexit
+
+define internal void @__cxx_global_var_init() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
+ %1 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A, %struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+ ret void
+}
+
+define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 {
+ %t = bitcast %struct.A* %this to %struct.B*
+ call void @_ZN1BD1Ev(%struct.B* %t)
+ ret void
+}
+
+declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+
+define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) nounwind align 2 {
+ ret void
+}
+
+define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @__cxx_global_var_init()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/deaddeclaration.ll b/llvm/test/Transforms/GlobalOpt/deaddeclaration.ll
new file mode 100644
index 00000000000..942f2e1bf6b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/deaddeclaration.ll
@@ -0,0 +1,7 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; CHECK-NOT: aa
+; CHECK-NOT: bb
+
+declare void @aa()
+@bb = external global i8
diff --git a/llvm/test/Transforms/GlobalOpt/deadfunction.ll b/llvm/test/Transforms/GlobalOpt/deadfunction.ll
new file mode 100644
index 00000000000..5771c4ccfb7
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/deadfunction.ll
@@ -0,0 +1,27 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; CHECK-NOT: test
+
+declare void @aa()
+declare void @bb()
+
+; Test that we can erase a function which has a blockaddress referring to it
+@test.x = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@test, %a), i8* blockaddress(@test, %b), i8* blockaddress(@test, %c)], align 16
+define internal void @test(i32 %n) nounwind noinline {
+entry:
+ %idxprom = sext i32 %n to i64
+ %arrayidx = getelementptr inbounds [3 x i8*], [3 x i8*]* @test.x, i64 0, i64 %idxprom
+ %0 = load i8*, i8** %arrayidx, align 8
+ indirectbr i8* %0, [label %a, label %b, label %c]
+
+a:
+ tail call void @aa() nounwind
+ br label %b
+
+b:
+ tail call void @bb() nounwind
+ br label %c
+
+c:
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/deadglobal-2.ll b/llvm/test/Transforms/GlobalOpt/deadglobal-2.ll
new file mode 100644
index 00000000000..92c0f994f36
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/deadglobal-2.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; This is a harder case to delete as the GEP has a variable index.
+
+; CHECK-NOT: internal
+@G = internal global [4 x i32] zeroinitializer
+
+define void @foo(i32 %X) {
+ %Ptr = getelementptr [4 x i32], [4 x i32]* @G, i32 0, i32 %X
+ store i32 1, i32* %Ptr
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/deadglobal.ll b/llvm/test/Transforms/GlobalOpt/deadglobal.ll
new file mode 100644
index 00000000000..f5eed44cbb6
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/deadglobal.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@G1 = internal global i32 123 ; <i32*> [#uses=1]
+@A1 = internal alias i32, i32* @G1
+
+; CHECK-NOT: @G1
+; CHECK: @G2
+; CHECK-NOT: @G3
+
+; CHECK-NOT: @A1
+
+define void @foo1() {
+; CHECK: define void @foo
+; CHECK-NEXT: ret
+ store i32 1, i32* @G1
+ ret void
+}
+
+@G2 = linkonce_odr constant i32 42
+
+define void @foo2() {
+; CHECK-LABEL: define void @foo2(
+; CHECK-NEXT: store
+ store i32 1, i32* @G2
+ ret void
+}
+
+@G3 = linkonce_odr constant i32 42
diff --git a/llvm/test/Transforms/GlobalOpt/evaluate-bitcast.ll b/llvm/test/Transforms/GlobalOpt/evaluate-bitcast.ll
new file mode 100644
index 00000000000..740dba2be66
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/evaluate-bitcast.ll
@@ -0,0 +1,28 @@
+; RUN: opt -globalopt -instcombine %s -S -o - | FileCheck %s
+
+; Static constructor should have been optimized out
+; CHECK: i32 @main
+; CHECK-NEXT: ret i32 69905
+; CHECK-NOT: _GLOBAL__sub_I_main.cpp
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+%struct.S = type { %struct.A* }
+%struct.A = type { i64, i64 }
+
+@s = internal local_unnamed_addr global %struct.S zeroinitializer, align 8
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_main.cpp, i8* null }]
+@gA = available_externally dso_local local_unnamed_addr global %struct.A* inttoptr (i64 69905 to %struct.A*), align 8
+
+define dso_local i32 @main() local_unnamed_addr {
+ %1 = load i64, i64* bitcast (%struct.S* @s to i64*), align 8
+ %2 = trunc i64 %1 to i32
+ ret i32 %2
+}
+
+define internal void @_GLOBAL__sub_I_main.cpp() section ".text.startup" {
+ %1 = load i64, i64* bitcast (%struct.A** @gA to i64*), align 8
+ store i64 %1, i64* bitcast (%struct.S* @s to i64*), align 8
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/evaluate-call-errors.ll b/llvm/test/Transforms/GlobalOpt/evaluate-call-errors.ll
new file mode 100644
index 00000000000..88f7cbd8df1
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/evaluate-call-errors.ll
@@ -0,0 +1,99 @@
+; Checks for few bitcasted call evaluation errors
+
+; REQUIRES: asserts
+; RUN: opt -globalopt -instcombine -S -debug-only=evaluator %s -o %t 2>&1 | FileCheck %s
+
+; CHECK: Failed to fold bitcast call expr
+; CHECK: Can not convert function argument
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+%struct.S = type { i32 }
+%struct.Q = type { i32 }
+%struct.Foo = type { i32 }
+
+@_s = global %struct.S zeroinitializer, align 4
+@_q = global %struct.Q zeroinitializer, align 4
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_main2.cpp, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_main3.cpp, i8* null }]
+
+define internal void @__cxx_global_var_init() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @_ZN1SC1Ev(%struct.S* @_s)
+ ret void
+}
+
+define linkonce_odr void @_ZN1SC1Ev(%struct.S*) unnamed_addr align 2 {
+ %2 = alloca %struct.S*, align 8
+ store %struct.S* %0, %struct.S** %2, align 8
+ %3 = load %struct.S*, %struct.S** %2, align 8
+ call void @_ZN1SC2Ev(%struct.S* %3)
+ ret void
+}
+
+define internal void @__cxx_global_var_init.1() #0 section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @_ZN1QC1Ev(%struct.Q* @_q)
+ ret void
+}
+
+define linkonce_odr void @_ZN1QC1Ev(%struct.Q*) unnamed_addr align 2 {
+ %2 = alloca %struct.Q*, align 8
+ store %struct.Q* %0, %struct.Q** %2, align 8
+ %3 = load %struct.Q*, %struct.Q** %2, align 8
+ call void @_ZN1QC2Ev(%struct.Q* %3)
+ ret void
+}
+
+define i32 @main() {
+ %1 = alloca i32, align 4
+ store i32 0, i32* %1, align 4
+ ret i32 0
+}
+
+define linkonce_odr void @_ZN1SC2Ev(%struct.S*) unnamed_addr align 2 {
+ %2 = alloca %struct.S*, align 8
+ %3 = alloca %struct.Foo, align 4
+ store %struct.S* %0, %struct.S** %2, align 8
+ %4 = load %struct.S*, %struct.S** %2, align 8
+ %5 = getelementptr inbounds %struct.S, %struct.S* %4, i32 0, i32 0
+ %6 = call i32 bitcast (%struct.Foo* ()* @_ZL3foov to i32 ()*)()
+ %7 = getelementptr inbounds %struct.Foo, %struct.Foo* %3, i32 0, i32 0
+ store i32 %6, i32* %7, align 4
+ %8 = getelementptr inbounds %struct.Foo, %struct.Foo* %3, i32 0, i32 0
+ %9 = load i32, i32* %8, align 4
+ store i32 %9, i32* %5, align 4
+ ret void
+}
+
+define internal %struct.Foo* @_ZL3foov() {
+ ret %struct.Foo* null
+}
+
+define linkonce_odr void @_ZN1QC2Ev(%struct.Q*) unnamed_addr align 2 {
+ %2 = alloca %struct.Q*, align 8
+ store %struct.Q* %0, %struct.Q** %2, align 8
+ %3 = load %struct.Q*, %struct.Q** %2, align 8
+ %4 = getelementptr inbounds %struct.Q, %struct.Q* %3, i32 0, i32 0
+ %5 = call i32 bitcast (i32 (i32)* @_ZL3baz3Foo to i32 (%struct.Foo*)*)(%struct.Foo* null)
+ store i32 %5, i32* %4, align 4
+ ret void
+}
+
+define internal i32 @_ZL3baz3Foo(i32) {
+ %2 = alloca %struct.Foo, align 4
+ %3 = getelementptr inbounds %struct.Foo, %struct.Foo* %2, i32 0, i32 0
+ store i32 %0, i32* %3, align 4
+ %4 = getelementptr inbounds %struct.Foo, %struct.Foo* %2, i32 0, i32 0
+ %5 = load i32, i32* %4, align 4
+ ret i32 %5
+}
+
+; Function Attrs: noinline ssp uwtable
+define internal void @_GLOBAL__sub_I_main2.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @__cxx_global_var_init()
+ ret void
+}
+
+define internal void @_GLOBAL__sub_I_main3.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @__cxx_global_var_init.1()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/evaluate-call.ll b/llvm/test/Transforms/GlobalOpt/evaluate-call.ll
new file mode 100644
index 00000000000..c0456740da4
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/evaluate-call.ll
@@ -0,0 +1,87 @@
+; Checks if bitcasted call expression can be evaluated
+; Given call expresion:
+; %struct.Bar* bitcast (%struct.Foo* (%struct.Foo*)* @_ZL3fooP3Foo to %struct.Bar* (%struct.Bar*)*)(%struct.Bar* @gBar)
+; We evaluate call to function @_ZL3fooP3Foo casting both parameter and return value
+; Given call expression:
+; void bitcast (void (%struct.Foo*)* @_ZL3bazP3Foo to void (%struct.Bar*)*)(%struct.Bar* @gBar)
+; We evaluate call to function _ZL3bazP3Foo casting its parameter and check that evaluated value (nullptr)
+; is handled correctly
+
+; RUN: opt -globalopt -instcombine -S %s -o - | FileCheck %s
+
+; CHECK: @gBar = local_unnamed_addr global %struct.Bar { i32 2 }
+; CHECK-NEXT: @_s = local_unnamed_addr global %struct.S { i32 1 }, align 4
+; CHECK-NEXT: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
+
+; CHECK: define i32 @main()
+; CHECK-NEXT: ret i32 0
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+%struct.Bar = type { i32 }
+%struct.S = type { i32 }
+%struct.Foo = type { i32 }
+
+@gBar = global %struct.Bar zeroinitializer, align 4
+@_s = global %struct.S zeroinitializer, align 4
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_main.cpp, i8* null }]
+
+define internal void @__cxx_global_var_init() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @_ZN1SC1Ev_alias(%struct.S* @_s)
+ ret void
+}
+
+@_ZN1SC1Ev_alias = linkonce_odr unnamed_addr alias void (%struct.S*), void (%struct.S*)* @_ZN1SC1Ev
+
+define linkonce_odr void @_ZN1SC1Ev(%struct.S*) unnamed_addr align 2 {
+ %2 = alloca %struct.S*, align 8
+ store %struct.S* %0, %struct.S** %2, align 8
+ %3 = load %struct.S*, %struct.S** %2, align 8
+ call void @_ZN1SC2Ev(%struct.S* %3)
+ ret void
+}
+
+define i32 @main() {
+ %1 = alloca i32, align 4
+ store i32 0, i32* %1, align 4
+ ret i32 0
+}
+
+define linkonce_odr void @_ZN1SC2Ev(%struct.S*) unnamed_addr align 2 {
+ %2 = alloca %struct.S*, align 8
+ store %struct.S* %0, %struct.S** %2, align 8
+ %3 = load %struct.S*, %struct.S** %2, align 8
+ %4 = getelementptr inbounds %struct.S, %struct.S* %3, i32 0, i32 0
+ %5 = call %struct.Bar* bitcast (%struct.Foo* (%struct.Foo*)* @_ZL3fooP3Foo to %struct.Bar* (%struct.Bar*)*)(%struct.Bar* @gBar)
+ %6 = getelementptr inbounds %struct.Bar, %struct.Bar* %5, i32 0, i32 0
+ %7 = load i32, i32* %6, align 4
+ store i32 %7, i32* %4, align 4
+ call void bitcast (void (%struct.Foo*)* @_ZL3bazP3Foo to void (%struct.Bar*)*)(%struct.Bar* @gBar)
+ ret void
+}
+
+define internal %struct.Foo* @_ZL3fooP3Foo(%struct.Foo*) {
+ %2 = alloca %struct.Foo*, align 8
+ store %struct.Foo* %0, %struct.Foo** %2, align 8
+ %3 = load %struct.Foo*, %struct.Foo** %2, align 8
+ %4 = getelementptr inbounds %struct.Foo, %struct.Foo* %3, i32 0, i32 0
+ store i32 1, i32* %4, align 4
+ %5 = load %struct.Foo*, %struct.Foo** %2, align 8
+ ret %struct.Foo* %5
+}
+
+define internal void @_ZL3bazP3Foo(%struct.Foo*) {
+ %2 = alloca %struct.Foo*, align 8
+ store %struct.Foo* %0, %struct.Foo** %2, align 8
+ %3 = load %struct.Foo*, %struct.Foo** %2, align 8
+ %4 = getelementptr inbounds %struct.Foo, %struct.Foo* %3, i32 0, i32 0
+ store i32 2, i32* %4, align 4
+ ret void
+}
+
+; Function Attrs: noinline ssp uwtable
+define internal void @_GLOBAL__sub_I_main.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @__cxx_global_var_init()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/evaluate-constfold-call.ll b/llvm/test/Transforms/GlobalOpt/evaluate-constfold-call.ll
new file mode 100644
index 00000000000..aeaa5e800c7
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/evaluate-constfold-call.ll
@@ -0,0 +1,55 @@
+; Check if we can evaluate a bitcasted call to a function which is constant folded.
+; Evaluator folds call to fmodf, replacing it with constant value in case both operands
+; are known at compile time.
+; RUN: opt -globalopt -instcombine %s -S -o - | FileCheck %s
+
+; CHECK: @_q = dso_local local_unnamed_addr global %struct.Q { i32 1066527622 }
+; CHECK: define dso_local i32 @main
+; CHECK-NEXT: %[[V:.+]] = load i32, i32* getelementptr inbounds (%struct.Q, %struct.Q* @_q, i64 0, i32 0)
+; CHECK-NEXT: ret i32 %[[V]]
+
+source_filename = "main.cpp"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-none-linux-gnu"
+
+%struct.Q = type { i32 }
+
+$_ZN1QC2Ev = comdat any
+
+@_q = dso_local global %struct.Q zeroinitializer, align 4
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_main.cpp, i8* null }]
+
+define internal void @__cxx_global_var_init() section ".text.startup" {
+ call void @_ZN1QC2Ev(%struct.Q* @_q)
+ ret void
+}
+
+define linkonce_odr dso_local void @_ZN1QC2Ev(%struct.Q*) unnamed_addr #1 comdat align 2 {
+ %2 = alloca %struct.Q*, align 8
+ store %struct.Q* %0, %struct.Q** %2, align 8
+ %3 = load %struct.Q*, %struct.Q** %2, align 8
+ %4 = getelementptr inbounds %struct.Q, %struct.Q* %3, i32 0, i32 0
+ %5 = call i32 bitcast (float (float, float)* @fmodf to i32 (float, float)*)(float 0x40091EB860000000, float 2.000000e+00)
+ store i32 %5, i32* %4, align 4
+ ret void
+}
+
+define dso_local i32 @main(i32, i8**) {
+ %3 = alloca i32, align 4
+ %4 = alloca i32, align 4
+ %5 = alloca i8**, align 8
+ store i32 0, i32* %3, align 4
+ store i32 %0, i32* %4, align 4
+ store i8** %1, i8*** %5, align 8
+ %6 = load i32, i32* getelementptr inbounds (%struct.Q, %struct.Q* @_q, i32 0, i32 0), align 4
+ ret i32 %6
+}
+
+; Function Attrs: nounwind
+declare dso_local float @fmodf(float, float)
+
+; Function Attrs: noinline uwtable
+define internal void @_GLOBAL__sub_I_main.cpp() section ".text.startup" {
+ call void @__cxx_global_var_init()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/externally-initialized-aggregate.ll b/llvm/test/Transforms/GlobalOpt/externally-initialized-aggregate.ll
new file mode 100644
index 00000000000..2434f20e92b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/externally-initialized-aggregate.ll
@@ -0,0 +1,50 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+
+; This global is externally_initialized, so if we split it into scalars we
+; should keep that flag set on all of the new globals. This will prevent the
+; store to @a[0] from being constant propagated to the load in @foo, but will not
+; prevent @a[1] from being removed since it is dead.
+; CHECK: @a.0 = internal unnamed_addr externally_initialized global i32 undef
+; CHECK-NOT: @a.1
+@a = internal externally_initialized global [2 x i32] undef, align 4
+; This is the same, but a struct rather than an array.
+; CHECK: @b.0 = internal unnamed_addr externally_initialized global i32 undef
+; CHECK-NOT: @b.1
+@b = internal externally_initialized global {i32, i32} undef, align 4
+
+define i32 @foo() {
+; CHECK-LABEL: define i32 @foo
+entry:
+; This load uses the split global, but cannot be constant-propagated away.
+; CHECK: %0 = load i32, i32* @a.0
+ %0 = load i32, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 0), align 4
+ ret i32 %0
+}
+
+define i32 @bar() {
+; CHECK-LABEL: define i32 @bar
+entry:
+; This load uses the split global, but cannot be constant-propagated away.
+; CHECK: %0 = load i32, i32* @b.0
+ %0 = load i32, i32* getelementptr inbounds ({i32, i32}, {i32, i32}* @b, i32 0, i32 0), align 4
+ ret i32 %0
+}
+
+define void @init() {
+; CHECK-LABEL: define void @init
+entry:
+; This store uses the split global, but cannot be constant-propagated away.
+; CHECK: store i32 1, i32* @a.0
+ store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 0), align 4
+; This store can be removed, because the second element of @a is never read.
+; CHECK-NOT: store i32 2, i32* @a.1
+ store i32 2, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 1), align 4
+
+; This store uses the split global, but cannot be constant-propagated away.
+; CHECK: store i32 3, i32* @b.0
+ store i32 3, i32* getelementptr inbounds ({i32, i32}, {i32, i32}* @b, i32 0, i32 0), align 4
+; This store can be removed, because the second element of @b is never read.
+; CHECK-NOT: store i32 4, i32* @b.1
+ store i32 4, i32* getelementptr inbounds ({i32, i32}, {i32, i32}* @b, i32 0, i32 1), align 4
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll b/llvm/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll
new file mode 100644
index 00000000000..2e22ff06444
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; rdar://12580965.
+; ObjC++ test case.
+
+%struct.ButtonInitData = type { i8* }
+
+@_ZL14buttonInitData = internal global [1 x %struct.ButtonInitData] zeroinitializer, align 4
+
+@"\01L_OBJC_METH_VAR_NAME_40" = internal global [7 x i8] c"print:\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+@"\01L_OBJC_SELECTOR_REFERENCES_41" = internal externally_initialized global i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_OBJC_METH_VAR_NAME_40", i32 0, i32 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+@llvm.used = appending global [2 x i8*] [i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_OBJC_METH_VAR_NAME_40", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_41" to i8*)]
+
+define internal void @__cxx_global_var_init() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ %1 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_41", !invariant.load !2009
+ store i8* %1, i8** getelementptr inbounds ([1 x %struct.ButtonInitData], [1 x %struct.ButtonInitData]* @_ZL14buttonInitData, i32 0, i32 0, i32 0), align 4
+ ret void
+}
+
+define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
+ call void @__cxx_global_var_init()
+ ret void
+}
+
+declare void @test(i8*)
+
+define void @print() {
+; CHECK: %1 = load i8*, i8** @_ZL14buttonInitData.0.0, align 4
+ %1 = load i8*, i8** getelementptr inbounds ([1 x %struct.ButtonInitData], [1 x %struct.ButtonInitData]* @_ZL14buttonInitData, i32 0, i32 0, i32 0), align 4
+ call void @test(i8* %1)
+ ret void
+}
+
+!2009 = !{}
diff --git a/llvm/test/Transforms/GlobalOpt/externally-initialized.ll b/llvm/test/Transforms/GlobalOpt/externally-initialized.ll
new file mode 100644
index 00000000000..c01ba10f49c
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/externally-initialized.ll
@@ -0,0 +1,37 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+
+; This global is externally_initialized, which may modify the value between
+; it's static initializer and any code in this module being run, so the only
+; write to it cannot be merged into the static initialiser.
+; CHECK: @a = internal unnamed_addr externally_initialized global i32 undef
+@a = internal externally_initialized global i32 undef
+
+; This global is stored to by the external initialization, so cannot be
+; constant-propagated and removed, despite the fact that there are no writes
+; to it.
+; CHECK: @b = internal unnamed_addr externally_initialized global i32 undef
+@b = internal externally_initialized global i32 undef
+
+
+define void @foo() {
+; CHECK-LABEL: foo
+entry:
+; CHECK: store i32 42, i32* @a
+ store i32 42, i32* @a
+ ret void
+}
+define i32 @bar() {
+; CHECK-LABEL: bar
+entry:
+; CHECK: %val = load i32, i32* @a
+ %val = load i32, i32* @a
+ ret i32 %val
+}
+
+define i32 @baz() {
+; CHECK-LABEL: baz
+entry:
+; CHECK: %val = load i32, i32* @b
+ %val = load i32, i32* @b
+ ret i32 %val
+}
diff --git a/llvm/test/Transforms/GlobalOpt/fastcc.ll b/llvm/test/Transforms/GlobalOpt/fastcc.ll
new file mode 100644
index 00000000000..64c4a268ff3
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/fastcc.ll
@@ -0,0 +1,55 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+define internal i32 @f(i32* %m) {
+; CHECK-LABEL: define internal fastcc i32 @f
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define internal x86_thiscallcc i32 @g(i32* %m) {
+; CHECK-LABEL: define internal fastcc i32 @g
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+; Leave this one alone, because the user went out of their way to request this
+; convention.
+define internal coldcc i32 @h(i32* %m) {
+; CHECK-LABEL: define internal coldcc i32 @h
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define internal i32 @j(i32* %m) {
+; CHECK-LABEL: define internal i32 @j
+ %v = load i32, i32* %m
+ ret i32 %v
+}
+
+define internal i32 @inalloca(i32* inalloca %p) {
+; CHECK-LABEL: define internal i32 @inalloca(i32* inalloca %p)
+ %rv = load i32, i32* %p
+ ret i32 %rv
+}
+
+define void @call_things() {
+ %m = alloca i32
+ call i32 @f(i32* %m)
+ call x86_thiscallcc i32 @g(i32* %m)
+ call coldcc i32 @h(i32* %m)
+ call i32 @j(i32* %m)
+ %args = alloca inalloca i32
+ call i32 @inalloca(i32* inalloca %args)
+ ret void
+}
+
+@llvm.used = appending global [1 x i8*] [
+ i8* bitcast (i32(i32*)* @j to i8*)
+], section "llvm.metadata"
+
+; CHECK-LABEL: define void @call_things()
+; CHECK: call fastcc i32 @f
+; CHECK: call fastcc i32 @g
+; CHECK: call coldcc i32 @h
+; CHECK: call i32 @j
+; CHECK: call i32 @inalloca(i32* inalloca %args)
diff --git a/llvm/test/Transforms/GlobalOpt/global-demotion.ll b/llvm/test/Transforms/GlobalOpt/global-demotion.ll
new file mode 100644
index 00000000000..7965cb89620
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/global-demotion.ll
@@ -0,0 +1,80 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+
+@G1 = internal global i32 5
+@G2 = internal global i32 5
+@G3 = internal global i32 5
+@G4 = internal global i32 5
+@G5 = internal global i32 5
+
+; CHECK-LABEL: @test1
+define internal i32 @test1() norecurse {
+; CHECK-NOT: @G1
+ store i32 4, i32* @G1
+ %a = load i32, i32* @G1
+; CHECK: ret
+ ret i32 %a
+}
+
+; The load comes before the store which makes @G2 live before the call.
+; CHECK-LABEL: @test2
+define internal i32 @test2() norecurse {
+; CHECK-NOT: %G2
+ %a = load i32, i32* @G2
+ store i32 4, i32* @G2
+; CHECK: ret
+ ret i32 %a
+}
+
+; This global is indexed by a GEP - this makes it partial alias and we bail out.
+; FIXME: We don't actually have to bail out in this case.
+
+; CHECK-LABEL: @test3
+define internal i32 @test3() norecurse {
+; CHECK-NOT: %G3
+ %x = getelementptr i32,i32* @G3, i32 0
+ %a = load i32, i32* %x
+ store i32 4, i32* @G3
+; CHECK: ret
+ ret i32 %a
+}
+
+; The global is casted away to a larger type then loaded. The store only partially
+; covers the load, so we must not demote.
+
+; CHECK-LABEL: @test4
+define internal i32 @test4() norecurse {
+; CHECK-NOT: %G4
+ store i32 4, i32* @G4
+ %x = bitcast i32* @G4 to i64*
+ %a = load i64, i64* %x
+ %b = trunc i64 %a to i32
+; CHECK: ret
+ ret i32 %b
+}
+
+; The global is casted away to a smaller type then loaded. This one is fine.
+
+; CHECK-LABEL: @test5
+define internal i32 @test5() norecurse {
+; CHECK-NOT: @G5
+ store i32 4, i32* @G5
+ %x = bitcast i32* @G5 to i16*
+ %a = load i16, i16* %x
+ %b = zext i16 %a to i32
+; CHECK: ret
+ ret i32 %b
+}
+
+define i32 @main() norecurse {
+ %a = call i32 @test1()
+ %b = call i32 @test2()
+ %c = call i32 @test3()
+ %d = call i32 @test4()
+ %e = call i32 @test5()
+
+ %x = or i32 %a, %b
+ %y = or i32 %x, %c
+ %z = or i32 %y, %d
+ %w = or i32 %z, %e
+ ret i32 %w
+}
diff --git a/llvm/test/Transforms/GlobalOpt/globalsra-multigep.ll b/llvm/test/Transforms/GlobalOpt/globalsra-multigep.ll
new file mode 100644
index 00000000000..87a8486d881
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/globalsra-multigep.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@g_data = internal unnamed_addr global <{ [8 x i16], [8 x i16] }> <{ [8 x i16] [i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16], [8 x i16] zeroinitializer }>, align 16
+; We cannot SRA here due to the second gep meaning the access to g_data may be to either element
+; CHECK: @g_data = internal unnamed_addr constant <{ [8 x i16], [8 x i16] }>
+
+define i16 @test(i64 %a1) {
+entry:
+ %g1 = getelementptr inbounds <{ [8 x i16], [8 x i16] }>, <{ [8 x i16], [8 x i16] }>* @g_data, i64 0, i32 0
+ %arrayidx.i = getelementptr inbounds [8 x i16], [8 x i16]* %g1, i64 0, i64 %a1
+ %r = load i16, i16* %arrayidx.i, align 2
+ ret i16 %r
+}
diff --git a/llvm/test/Transforms/GlobalOpt/globalsra-partial.ll b/llvm/test/Transforms/GlobalOpt/globalsra-partial.ll
new file mode 100644
index 00000000000..141ee1bb5a8
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/globalsra-partial.ll
@@ -0,0 +1,25 @@
+; In this case, the global cannot be merged as i may be out of range
+
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global { i32, [4 x float] } zeroinitializer ; <{ i32, [4 x float] }*> [#uses=3]
+
+; CHECK: @G = internal unnamed_addr global { i32, [4 x float] }
+; CHECK: 12345
+define void @onlystore() {
+ store i32 12345, i32* getelementptr ({ i32, [4 x float] }, { i32, [4 x float] }* @G, i32 0, i32 0)
+ ret void
+}
+
+define void @storeinit(i32 %i) {
+ %Ptr = getelementptr { i32, [4 x float] }, { i32, [4 x float] }* @G, i32 0, i32 1, i32 %i ; <float*> [#uses=1]
+ store float 1.000000e+00, float* %Ptr
+ ret void
+}
+
+define float @readval(i32 %i) {
+ %Ptr = getelementptr { i32, [4 x float] }, { i32, [4 x float] }* @G, i32 0, i32 1, i32 %i ; <float*> [#uses=1]
+ %V = load float, float* %Ptr ; <float> [#uses=1]
+ ret float %V
+}
diff --git a/llvm/test/Transforms/GlobalOpt/globalsra-unknown-index.ll b/llvm/test/Transforms/GlobalOpt/globalsra-unknown-index.ll
new file mode 100644
index 00000000000..4607373ab2c
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/globalsra-unknown-index.ll
@@ -0,0 +1,54 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; globalopt should not sra the global, because it can't see the index.
+
+%struct.X = type { [3 x i32], [3 x i32] }
+
+; CHECK: @Y = internal unnamed_addr global [3 x %struct.X] zeroinitializer
+@Y = internal global [3 x %struct.X] zeroinitializer
+
+@addr = external global i8
+
+define void @frob() {
+ store i32 1, i32* getelementptr inbounds ([3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 ptrtoint (i8* @addr to i64)), align 4
+ ret void
+}
+
+; CHECK-LABEL: @borf
+; CHECK: %a = load
+; CHECK: %b = load
+; CHECK: add i32 %a, %b
+define i32 @borf(i64 %i, i64 %j) {
+ %p = getelementptr inbounds [3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0
+ %a = load i32, i32* %p
+ %q = getelementptr inbounds [3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 0, i32 1, i64 0
+ %b = load i32, i32* %q
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+; CHECK-LABEL: @borg
+; CHECK: %a = load
+; CHECK: %b = load
+; CHECK: add i32 %a, %b
+define i32 @borg(i64 %i, i64 %j) {
+ %p = getelementptr inbounds [3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 1, i32 0, i64 1
+ %a = load i32, i32* %p
+ %q = getelementptr inbounds [3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 1, i32 1, i64 1
+ %b = load i32, i32* %q
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+; CHECK-LABEL: @borh
+; CHECK: %a = load
+; CHECK: %b = load
+; CHECK: add i32 %a, %b
+define i32 @borh(i64 %i, i64 %j) {
+ %p = getelementptr inbounds [3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 2
+ %a = load i32, i32* %p
+ %q = getelementptr inbounds [3 x %struct.X], [3 x %struct.X]* @Y, i64 0, i64 2, i32 1, i64 2
+ %b = load i32, i32* %q
+ %c = add i32 %a, %b
+ ret i32 %c
+}
diff --git a/llvm/test/Transforms/GlobalOpt/globalsra.ll b/llvm/test/Transforms/GlobalOpt/globalsra.ll
new file mode 100644
index 00000000000..8098ec84b2e
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/globalsra.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: global
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global { i32, float, { double } } {
+ i32 1,
+ float 1.000000e+00,
+ { double } { double 1.727000e+01 } } ; <{ i32, float, { double } }*> [#uses=3]
+
+define void @onlystore() {
+ store i32 123, i32* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G, i32 0, i32 0)
+ ret void
+}
+
+define float @storeinit() {
+ store float 1.000000e+00, float* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G, i32 0, i32 1)
+ %X = load float, float* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G, i32 0, i32 1) ; <float> [#uses=1]
+ ret float %X
+}
+
+define double @constantize() {
+ %X = load double, double* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G, i32 0, i32 2, i32 0) ; <double> [#uses=1]
+ ret double %X
+}
+
+@G2 = internal constant { i32, float, { double } } {
+ i32 1,
+ float 1.000000e+00,
+ { double } { double 1.727000e+01 } } ; <{ i32, float, { double } }*> [#uses=3]
+
+define void @onlystore2() {
+ store i32 123, i32* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G2, i32 0, i32 0)
+ ret void
+}
+
+define float @storeinit2() {
+ store float 1.000000e+00, float* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G2, i32 0, i32 1)
+ %X = load float, float* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G2, i32 0, i32 1) ; <float> [#uses=1]
+ ret float %X
+}
+
+define double @constantize2() {
+ %X = load double, double* getelementptr ({ i32, float, { double } }, { i32, float, { double } }* @G2, i32 0, i32 2, i32 0) ; <double> [#uses=1]
+ ret double %X
+}
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-1-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-1-no-null-opt.ll
new file mode 100644
index 00000000000..c826e7f7a04
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-1-no-null-opt.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+%struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null
+; CHECK: @X
+; CHECK-NOT: @X.f0
+
+define void @bar(i64 %Size) nounwind noinline #0 {
+entry:
+ %mallocsize = mul i64 %Size, 8 ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline #0 {
+bb1.thread:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0
+ %2 = load i32, i32* %1, align 4
+ %3 = add i32 %2, %sum.0.reg2mem.0
+ %indvar.next = add i32 %i.0.reg2mem.0, 1
+ %exitcond = icmp eq i32 %indvar.next, 1200
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
+
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-1.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-1.ll
new file mode 100644
index 00000000000..28a20ada03f
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-1.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null
+; CHECK: @X.f0
+; CHECK: @X.f1
+
+define void @bar(i64 %Size) nounwind noinline {
+entry:
+ %mallocsize = mul i64 %Size, 8 ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0
+ %2 = load i32, i32* %1, align 4
+ %3 = add i32 %2, %sum.0.reg2mem.0
+ %indvar.next = add i32 %i.0.reg2mem.0, 1
+ %exitcond = icmp eq i32 %indvar.next, 1200
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+define void @bam(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-2-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-2-no-null-opt.ll
new file mode 100644
index 00000000000..c33bcba9921
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-2-no-null-opt.ll
@@ -0,0 +1,39 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+%struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+; CHECK: @X
+; CHECK-NOT: @X.f0
+
+define void @bar(i32 %Size) nounwind noinline #0 {
+entry:
+ %malloccall = tail call i8* @malloc(i64 8000000) ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1]
+ %.sub = getelementptr [1000000 x %struct.foo], [1000000 x %struct.foo]* %0, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline #0 {
+bb1.thread:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ] ; <i32> [#uses=2]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ] ; <i32> [#uses=1]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0 ; <i32*> [#uses=1]
+ %2 = load i32, i32* %1, align 4 ; <i32> [#uses=1]
+ %3 = add i32 %2, %sum.0.reg2mem.0 ; <i32> [#uses=2]
+ %indvar.next = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, 1200 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-2.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-2.ll
new file mode 100644
index 00000000000..ec05b22b33b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-2.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+; CHECK: @X.f0
+; CHECK: @X.f1
+
+define void @bar(i32 %Size) nounwind noinline {
+entry:
+ %malloccall = tail call i8* @malloc(i64 8000000) ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1]
+ %.sub = getelementptr [1000000 x %struct.foo], [1000000 x %struct.foo]* %0, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ] ; <i32> [#uses=2]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ] ; <i32> [#uses=1]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0 ; <i32*> [#uses=1]
+ %2 = load i32, i32* %1, align 4 ; <i32> [#uses=1]
+ %3 = add i32 %2, %sum.0.reg2mem.0 ; <i32> [#uses=2]
+ %indvar.next = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %indvar.next, 1200 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+define void @bam(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-3-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-3-no-null-opt.ll
new file mode 100644
index 00000000000..ba3b0a418a1
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-3-no-null-opt.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+%struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null
+; CHECK: @X
+; CHECK-NOT: @X.f0
+
+define void @bar(i64 %Size) nounwind noinline #0 {
+entry:
+ %mallocsize = mul i64 8, %Size ; <i64> [#uses=1]
+; CHECK: mul i64 8, %Size
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline #0 {
+bb1.thread:
+; CHECK: load %struct.foo*, %struct.foo** @X, align 4
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0
+ %2 = load i32, i32* %1, align 4
+ %3 = add i32 %2, %sum.0.reg2mem.0
+ %indvar.next = add i32 %i.0.reg2mem.0, 1
+ %exitcond = icmp eq i32 %indvar.next, 1200
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-3.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-3.ll
new file mode 100644
index 00000000000..67058c8aba2
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-3.ll
@@ -0,0 +1,46 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null
+; CHECK: @X.f0
+; CHECK: @X.f1
+
+define void @bar(i64 %Size) nounwind noinline {
+entry:
+ %mallocsize = mul i64 8, %Size ; <i64> [#uses=1]
+; CHECK: mul i64 %Size, 4
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0
+ %2 = load i32, i32* %1, align 4
+ %3 = add i32 %2, %sum.0.reg2mem.0
+ %indvar.next = add i32 %i.0.reg2mem.0, 1
+ %exitcond = icmp eq i32 %indvar.next, 1200
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+define void @bam(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-4-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-4-no-null-opt.ll
new file mode 100644
index 00000000000..607c93d1e8a
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-4-no-null-opt.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+%struct.foo = type { i32, i32 }
+
+@X = internal global %struct.foo* null
+; CHECK: @X
+; CHECK-NOT: @X.f0
+
+define void @bar(i64 %Size) nounwind noinline #0 {
+entry:
+ %mallocsize = shl i64 %Size, 3 ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+; CHECK: shl i64 %Size, 3
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline #0 {
+; CHECK-LABEL: @baz(
+bb1.thread:
+; CHECK: load %struct.foo*, %struct.foo** @X, align 4
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0
+ %2 = load i32, i32* %1, align 4
+; CHECK: load i32, i32* %1, align 4
+ %3 = add i32 %2, %sum.0.reg2mem.0
+ %indvar.next = add i32 %i.0.reg2mem.0, 1
+ %exitcond = icmp eq i32 %indvar.next, 1200
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-4.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-4.ll
new file mode 100644
index 00000000000..71832f34923
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-4.ll
@@ -0,0 +1,47 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null
+; CHECK: @X.f0
+; CHECK: @X.f1
+
+define void @bar(i64 %Size) nounwind noinline {
+entry:
+ %mallocsize = shl i64 %Size, 3 ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+; CHECK: mul i64 %Size, 4
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %3, %bb1 ]
+ %1 = getelementptr %struct.foo, %struct.foo* %0, i32 %i.0.reg2mem.0, i32 0
+ %2 = load i32, i32* %1, align 4
+ %3 = add i32 %2, %sum.0.reg2mem.0
+ %indvar.next = add i32 %i.0.reg2mem.0, 1
+ %exitcond = icmp eq i32 %indvar.next, 1200
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %3
+}
+
+define void @bam(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
+
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-phi-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-phi-no-null-opt.ll
new file mode 100644
index 00000000000..06c74e5bfc4
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-phi-no-null-opt.ll
@@ -0,0 +1,54 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+%struct.foo = type { i32, i32 }
+
+@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+; CHECK: @X
+; CHECK-NOT: @X.f0
+
+define void @bar(i32 %Size) nounwind noinline #0 {
+; CHECK-LABEL: @bar(
+entry:
+ %malloccall = tail call i8* @malloc(i64 8000000) ; <i8*> [#uses=1]
+ %tmp = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1]
+ %.sub = getelementptr [1000000 x %struct.foo], [1000000 x %struct.foo]* %tmp, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline #0 {
+; CHECK-LABEL: @baz(
+bb1.thread:
+ %tmpLD1 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
+; CHECK: load %struct.foo*, %struct.foo** @X, align 4
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %tmp = phi %struct.foo* [%tmpLD1, %bb1.thread ], [ %tmpLD2, %bb1 ] ; <i32> [#uses=2]
+; CHECK: %tmp = phi %struct.foo* [ %tmpLD1, %bb1.thread ], [ %tmpLD2, %bb1 ]
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ] ; <i32> [#uses=2]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %tmp3, %bb1 ] ; <i32> [#uses=1]
+ %tmp1 = getelementptr %struct.foo, %struct.foo* %tmp, i32 %i.0.reg2mem.0, i32 0 ; <i32*> [#uses=1]
+ %tmp2 = load i32, i32* %tmp1, align 4 ; <i32> [#uses=1]
+; CHECK: load i32, i32* %tmp1, align 4
+ %tmp6 = add i32 %tmp2, %sum.0.reg2mem.0 ; <i32> [#uses=2]
+ %tmp4 = getelementptr %struct.foo, %struct.foo* %tmp, i32 %i.0.reg2mem.0, i32 1 ; <i32*> [#uses=1]
+ %tmp5 = load i32 , i32 * %tmp4
+; CHECK: load i32, i32* %tmp4
+ %tmp3 = add i32 %tmp5, %tmp6
+ %indvar.next = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2]
+
+ %tmpLD2 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
+; CHECK: load %struct.foo*, %struct.foo** @X, align 4
+
+ %exitcond = icmp eq i32 %indvar.next, 1200 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %tmp3
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/heap-sra-phi.ll b/llvm/test/Transforms/GlobalOpt/heap-sra-phi.ll
new file mode 100644
index 00000000000..770220dd07b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/heap-sra-phi.ll
@@ -0,0 +1,52 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: tmp.f1 = phi i32*
+; CHECK: tmp.f0 = phi i32*
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+ %struct.foo = type { i32, i32 }
+@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+
+define void @bar(i32 %Size) nounwind noinline {
+entry:
+ %malloccall = tail call i8* @malloc(i64 8000000) ; <i8*> [#uses=1]
+ %tmp = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1]
+ %.sub = getelementptr [1000000 x %struct.foo], [1000000 x %struct.foo]* %tmp, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
+ store %struct.foo* %.sub, %struct.foo** @X, align 4
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @baz() nounwind readonly noinline {
+bb1.thread:
+ %tmpLD1 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb1.thread
+ %tmp = phi %struct.foo* [%tmpLD1, %bb1.thread ], [ %tmpLD2, %bb1 ] ; <i32> [#uses=2]
+ %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ] ; <i32> [#uses=2]
+ %sum.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %tmp3, %bb1 ] ; <i32> [#uses=1]
+ %tmp1 = getelementptr %struct.foo, %struct.foo* %tmp, i32 %i.0.reg2mem.0, i32 0 ; <i32*> [#uses=1]
+ %tmp2 = load i32, i32* %tmp1, align 4 ; <i32> [#uses=1]
+ %tmp6 = add i32 %tmp2, %sum.0.reg2mem.0 ; <i32> [#uses=2]
+ %tmp4 = getelementptr %struct.foo, %struct.foo* %tmp, i32 %i.0.reg2mem.0, i32 1 ; <i32*> [#uses=1]
+ %tmp5 = load i32 , i32 * %tmp4
+ %tmp3 = add i32 %tmp5, %tmp6
+ %indvar.next = add i32 %i.0.reg2mem.0, 1 ; <i32> [#uses=2]
+
+ %tmpLD2 = load %struct.foo*, %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
+
+ %exitcond = icmp eq i32 %indvar.next, 1200 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb1
+
+bb2: ; preds = %bb1
+ ret i32 %tmp3
+}
+
+define void @bam(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load %struct.foo*, %struct.foo** @X, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/int_sideeffect.ll b/llvm/test/Transforms/GlobalOpt/int_sideeffect.ll
new file mode 100644
index 00000000000..59c3a8aa4ba
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/int_sideeffect.ll
@@ -0,0 +1,16 @@
+; RUN: opt -S < %s -globalopt | FileCheck %s
+
+; Static evaluation across a @llvm.sideeffect.
+
+; CHECK-NOT: store
+
+declare void @llvm.sideeffect()
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @ctor } ]
+@G = global i32 0
+
+define internal void @ctor() {
+ store i32 1, i32* @G
+ call void @llvm.sideeffect()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/integer-bool-dwarf.ll b/llvm/test/Transforms/GlobalOpt/integer-bool-dwarf.ll
new file mode 100644
index 00000000000..6aa35be21d8
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/integer-bool-dwarf.ll
@@ -0,0 +1,61 @@
+;RUN: opt -S -globalopt -f %s | FileCheck %s
+
+;CHECK: @foo = internal unnamed_addr global i1 false, align 4, !dbg ![[VAR:.*]]
+;CHECK: ![[VAR]] = !DIGlobalVariableExpression(var: !1, expr:
+;CHECK-SAME: !DIExpression(DW_OP_deref, DW_OP_constu, 111, DW_OP_mul,
+;CHECK-SAME: DW_OP_constu, 0, DW_OP_plus, DW_OP_stack_value,
+;CHECK-SAME: DW_OP_LLVM_fragment, 0, 1))
+
+@foo = internal global i32 0, align 4, !dbg !0
+
+; Function Attrs: noinline nounwind optnone uwtable
+define void @set1() #0 !dbg !11 {
+entry:
+ store i32 111, i32* @foo, align 4, !dbg !14
+ ret void, !dbg !15
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define void @set2() #0 !dbg !16 {
+entry:
+ store i32 0, i32* @foo, align 4, !dbg !17
+ ret void, !dbg !18
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define i32 @get() #0 !dbg !19 {
+entry:
+ %0 = load i32, i32* @foo, align 4, !dbg !22
+ ret i32 %0, !dbg !23
+}
+
+attributes #0 = { noinline nounwind optnone uwtable }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 0, 1))
+!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 1, type: !6, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "integer-bool-dwarf.c", directory: "/")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{!"clang version 6.0.0 "}
+!11 = distinct !DISubprogram(name: "set1", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized: false, unit: !2, retainedNodes: !4)
+!12 = !DISubroutineType(types: !13)
+!13 = !{null}
+!14 = !DILocation(line: 5, column: 7, scope: !11)
+!15 = !DILocation(line: 6, column: 1, scope: !11)
+!16 = distinct !DISubprogram(name: "set2", scope: !3, file: !3, line: 8, type: !12, isLocal: false, isDefinition: true, scopeLine: 9, isOptimized: false, unit: !2, retainedNodes: !4)
+!17 = !DILocation(line: 10, column: 7, scope: !16)
+!18 = !DILocation(line: 11, column: 1, scope: !16)
+!19 = distinct !DISubprogram(name: "get", scope: !3, file: !3, line: 13, type: !20, isLocal: false, isDefinition: true, scopeLine: 14, isOptimized: false, unit: !2, retainedNodes: !4)
+!20 = !DISubroutineType(types: !21)
+!21 = !{!6}
+!22 = !DILocation(line: 15, column: 10, scope: !19)
+!23 = !DILocation(line: 15, column: 3, scope: !19)
diff --git a/llvm/test/Transforms/GlobalOpt/integer-bool.ll b/llvm/test/Transforms/GlobalOpt/integer-bool.ll
new file mode 100644
index 00000000000..617febdc016
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/integer-bool.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -S -globalopt -instcombine | FileCheck %s
+;; check that global opt turns integers that only hold 0 or 1 into bools.
+
+@G = internal addrspace(1) global i32 0
+; CHECK: @G
+; CHECK: addrspace(1)
+; CHECK: global i1 false
+
+define void @set1() {
+ store i32 0, i32 addrspace(1)* @G
+; CHECK: store i1 false
+ ret void
+}
+
+define void @set2() {
+ store i32 1, i32 addrspace(1)* @G
+; CHECK: store i1 true
+ ret void
+}
+
+define i1 @get() {
+; CHECK-LABEL: @get(
+ %A = load i32, i32 addrspace(1) * @G
+ %C = icmp slt i32 %A, 2
+ ret i1 %C
+; CHECK: ret i1 true
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/invariant-nodatalayout.ll b/llvm/test/Transforms/GlobalOpt/invariant-nodatalayout.ll
new file mode 100644
index 00000000000..d1fbe46257d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/invariant-nodatalayout.ll
@@ -0,0 +1,17 @@
+; RUN: opt -globalopt -S -o - < %s | FileCheck %s
+; The check here is that it doesn't crash.
+
+declare {}* @llvm.invariant.start.p0i8(i64 %size, i8* nocapture %ptr)
+
+@object1 = global { i32, i32 } zeroinitializer
+; CHECK: @object1 = global { i32, i32 } zeroinitializer
+
+define void @ctor1() {
+ %ptr = bitcast {i32, i32}* @object1 to i8*
+ call {}* @llvm.invariant.start.p0i8(i64 4, i8* %ptr)
+ ret void
+}
+
+@llvm.global_ctors = appending constant
+ [1 x { i32, void ()* }]
+ [ { i32, void ()* } { i32 65535, void ()* @ctor1 } ]
diff --git a/llvm/test/Transforms/GlobalOpt/invariant.group.ll b/llvm/test/Transforms/GlobalOpt/invariant.group.ll
new file mode 100644
index 00000000000..8a090cbd0d3
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/invariant.group.ll
@@ -0,0 +1,79 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; This test is hint, what could globalOpt optimize and what it can't
+; FIXME: @tmp and @tmp2 can be safely set to 42
+; CHECK: @tmp = local_unnamed_addr global i32 0
+; CHECK: @tmp2 = local_unnamed_addr global i32 0
+; CHECK: @tmp3 = global i32 0
+
+@tmp = global i32 0
+@tmp2 = global i32 0
+@tmp3 = global i32 0
+@ptrToTmp3 = global i32* null
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+
+define i32 @TheAnswerToLifeTheUniverseAndEverything() {
+ ret i32 42
+}
+
+define void @_GLOBAL__I_a() {
+enter:
+ call void @_optimizable()
+ call void @_not_optimizable()
+ ret void
+}
+
+define void @_optimizable() {
+enter:
+ %valptr = alloca i32
+
+ %val = call i32 @TheAnswerToLifeTheUniverseAndEverything()
+ store i32 %val, i32* @tmp
+ store i32 %val, i32* %valptr
+
+ %0 = bitcast i32* %valptr to i8*
+ %barr = call i8* @llvm.launder.invariant.group(i8* %0)
+ %1 = bitcast i8* %barr to i32*
+
+ %val2 = load i32, i32* %1
+ store i32 %val2, i32* @tmp2
+ ret void
+}
+
+; We can't step through launder.invariant.group here, because that would change
+; this load in @usage_of_globals()
+; val = load i32, i32* %ptrVal, !invariant.group !0
+; into
+; %val = load i32, i32* @tmp3, !invariant.group !0
+; and then we could assume that %val and %val2 to be the same, which coud be
+; false, because @changeTmp3ValAndCallBarrierInside() may change the value
+; of @tmp3.
+define void @_not_optimizable() {
+enter:
+ store i32 13, i32* @tmp3, !invariant.group !0
+
+ %0 = bitcast i32* @tmp3 to i8*
+ %barr = call i8* @llvm.launder.invariant.group(i8* %0)
+ %1 = bitcast i8* %barr to i32*
+
+ store i32* %1, i32** @ptrToTmp3
+ store i32 42, i32* %1, !invariant.group !0
+
+ ret void
+}
+define void @usage_of_globals() {
+entry:
+ %ptrVal = load i32*, i32** @ptrToTmp3
+ %val = load i32, i32* %ptrVal, !invariant.group !0
+
+ call void @changeTmp3ValAndCallBarrierInside()
+ %val2 = load i32, i32* @tmp3, !invariant.group !0
+ ret void;
+}
+
+declare void @changeTmp3ValAndCallBarrierInside()
+
+declare i8* @llvm.launder.invariant.group(i8*)
+
+!0 = !{}
diff --git a/llvm/test/Transforms/GlobalOpt/invariant.ll b/llvm/test/Transforms/GlobalOpt/invariant.ll
new file mode 100644
index 00000000000..02ffe2bc424
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/invariant.ll
@@ -0,0 +1,59 @@
+; RUN: opt -globalopt -S -o - < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare {}* @llvm.invariant.start.p0i8(i64 %size, i8* nocapture %ptr)
+
+define void @test1(i8* %ptr) {
+ call {}* @llvm.invariant.start.p0i8(i64 4, i8* %ptr)
+ ret void
+}
+
+@object1 = global i32 0
+; CHECK: @object1 = constant i32 -1
+define void @ctor1() {
+ store i32 -1, i32* @object1
+ %A = bitcast i32* @object1 to i8*
+ call void @test1(i8* %A)
+ ret void
+}
+
+
+@object2 = global i32 0
+; CHECK: @object2 = global i32 0
+define void @ctor2() {
+ store i32 -1, i32* @object2
+ %A = bitcast i32* @object2 to i8*
+ %B = call {}* @llvm.invariant.start.p0i8(i64 4, i8* %A)
+ %C = bitcast {}* %B to i8*
+ ret void
+}
+
+
+@object3 = global i32 0
+; CHECK: @object3 = global i32 -1
+define void @ctor3() {
+ store i32 -1, i32* @object3
+ %A = bitcast i32* @object3 to i8*
+ call {}* @llvm.invariant.start.p0i8(i64 3, i8* %A)
+ ret void
+}
+
+
+@object4 = global i32 0
+; CHECK: @object4 = global i32 -1
+define void @ctor4() {
+ store i32 -1, i32* @object4
+ %A = bitcast i32* @object4 to i8*
+ call {}* @llvm.invariant.start.p0i8(i64 -1, i8* %A)
+ ret void
+}
+
+
+@llvm.global_ctors = appending constant
+ [4 x { i32, void ()* }]
+ [ { i32, void ()* } { i32 65535, void ()* @ctor1 },
+ { i32, void ()* } { i32 65535, void ()* @ctor2 },
+ { i32, void ()* } { i32 65535, void ()* @ctor3 },
+ { i32, void ()* } { i32 65535, void ()* @ctor4 } ]
diff --git a/llvm/test/Transforms/GlobalOpt/invoke.ll b/llvm/test/Transforms/GlobalOpt/invoke.ll
new file mode 100644
index 00000000000..a3019939735
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/invoke.ll
@@ -0,0 +1,27 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+; rdar://11022897
+
+; Globalopt should be able to evaluate an invoke.
+; CHECK: @tmp = local_unnamed_addr global i32 1
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+@tmp = global i32 0
+
+define i32 @one() {
+ ret i32 1
+}
+
+define void @_GLOBAL__I_a() personality i8* undef {
+bb:
+ %tmp1 = invoke i32 @one()
+ to label %bb2 unwind label %bb4
+
+bb2: ; preds = %bb
+ store i32 %tmp1, i32* @tmp
+ ret void
+
+bb4: ; preds = %bb
+ %tmp5 = landingpad { i8*, i32 }
+ filter [0 x i8*] zeroinitializer
+ unreachable
+}
diff --git a/llvm/test/Transforms/GlobalOpt/iterate.ll b/llvm/test/Transforms/GlobalOpt/iterate.ll
new file mode 100644
index 00000000000..8c6543b685d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/iterate.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: %G
+
+@G = internal global i32 0 ; <i32*> [#uses=1]
+@H = internal global { i32* } { i32* @G } ; <{ i32* }*> [#uses=1]
+
+define i32 @loadg() {
+ %G = load i32*, i32** getelementptr ({ i32* }, { i32* }* @H, i32 0, i32 0) ; <i32*> [#uses=1]
+ %GV = load i32, i32* %G ; <i32> [#uses=1]
+ ret i32 %GV
+}
diff --git a/llvm/test/Transforms/GlobalOpt/load-store-global-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/load-store-global-no-null-opt.ll
new file mode 100644
index 00000000000..d319d162ff4
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/load-store-global-no-null-opt.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@a = internal global i64* null, align 8
+; CHECK: @a
+
+; PR13968
+define void @qux_no_null_opt() nounwind #0 {
+; CHECK-LABEL: @qux_no_null_opt(
+; CHECK: getelementptr i64*, i64** @a, i32 1
+; CHECK: store i64* inttoptr (i64 1 to i64*), i64** @a
+ %b = bitcast i64** @a to i8*
+ %g = getelementptr i64*, i64** @a, i32 1
+ %cmp = icmp ne i8* null, %b
+ %cmp2 = icmp eq i8* null, %b
+ %cmp3 = icmp eq i64** null, %g
+ store i64* inttoptr (i64 1 to i64*), i64** @a, align 8
+ %l = load i64*, i64** @a, align 8
+ ret void
+}
+
+define i64* @bar() {
+ %X = load i64*, i64** @a, align 8
+ ret i64* %X
+; CHECK-LABEL: @bar(
+; CHECK: load
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/load-store-global.ll b/llvm/test/Transforms/GlobalOpt/load-store-global.ll
new file mode 100644
index 00000000000..e01358e8ed3
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/load-store-global.ll
@@ -0,0 +1,38 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@G = internal global i32 17 ; <i32*> [#uses=3]
+; CHECK-NOT: @G
+
+define void @foo() {
+ %V = load i32, i32* @G ; <i32> [#uses=1]
+ store i32 %V, i32* @G
+ ret void
+; CHECK-LABEL: @foo(
+; CHECK-NEXT: ret void
+}
+
+define i32 @bar() {
+ %X = load i32, i32* @G ; <i32> [#uses=1]
+ ret i32 %X
+; CHECK-LABEL: @bar(
+; CHECK-NEXT: ret i32 17
+}
+
+@a = internal global i64* null, align 8
+; CHECK-NOT: @a
+
+; PR13968
+define void @qux() nounwind {
+ %b = bitcast i64** @a to i8*
+ %g = getelementptr i64*, i64** @a, i32 1
+ %cmp = icmp ne i8* null, %b
+ %cmp2 = icmp eq i8* null, %b
+ %cmp3 = icmp eq i64** null, %g
+ store i64* inttoptr (i64 1 to i64*), i64** @a, align 8
+ %l = load i64*, i64** @a, align 8
+ ret void
+; CHECK-LABEL: @qux(
+; CHECK-NOT: store
+; CHECK-NOT: load
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll b/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll
new file mode 100644
index 00000000000..e5f0eea8013
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll
@@ -0,0 +1,70 @@
+; RUN: opt -S < %s -globalopt | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@_ZL1x = internal global [200 x i8]* null, align 8, !dbg !0
+
+define i32 @main(i32 %argc, i8** %argv) norecurse !dbg !18 {
+; CHECK: define i32 @main
+; Make sure we localized the global.
+; CHECK: alloca [200 x i8]*
+; Make sure the metadata is sane. Currently, we just drop the metadata,
+; so it points to nothing.
+; CHECK: call void @llvm.dbg.value(metadata !2,
+; CHECK: !2 = !{}
+entry:
+ call void @llvm.dbg.value(metadata i32 %argc, metadata !22, metadata !23), !dbg !24
+ call void @llvm.dbg.value(metadata i8** %argv, metadata !25, metadata !23), !dbg !26
+ %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 0, !dbg !27
+ %0 = load i8*, i8** %arrayidx, align 8, !dbg !27
+ %1 = bitcast i8* %0 to [200 x i8]*, !dbg !28
+ store [200 x i8]* %1, [200 x i8]** @_ZL1x, align 8, !dbg !29
+ call void @llvm.dbg.value(metadata i8** bitcast ([200 x i8]** @_ZL1x to i8**), metadata !30, metadata !23), !dbg !31
+ %2 = load i8*, i8** bitcast ([200 x i8]** @_ZL1x to i8**), align 8, !dbg !32
+ %3 = load i8, i8* %2, align 1, !dbg !33
+ %conv = sext i8 %3 to i32, !dbg !33
+ ret i32 %conv, !dbg !34
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!15, !16}
+!llvm.ident = !{!17}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "x", linkageName: "_ZL1x", scope: !2, file: !14, line: 1, type: !6, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !13)
+!3 = !DIFile(filename: "-", directory: "/")
+!4 = !{}
+!5 = !{!6, !11}
+!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
+!7 = !DICompositeType(tag: DW_TAG_array_type, baseType: !8, size: 1600, elements: !9)
+!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!9 = !{!10}
+!10 = !DISubrange(count: 200)
+!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
+!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
+!13 = !{!0}
+!14 = !DIFile(filename: "<stdin>", directory: "/")
+!15 = !{i32 2, !"Dwarf Version", i32 4}
+!16 = !{i32 2, !"Debug Info Version", i32 3}
+!17 = !{!"clang"}
+!18 = distinct !DISubprogram(name: "main", scope: !14, file: !14, line: 2, type: !19, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !2, retainedNodes: !4)
+!19 = !DISubroutineType(types: !20)
+!20 = !{!21, !21, !11}
+!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!22 = !DILocalVariable(name: "argc", arg: 1, scope: !18, file: !14, line: 2, type: !21)
+!23 = !DIExpression()
+!24 = !DILocation(line: 2, column: 14, scope: !18)
+!25 = !DILocalVariable(name: "argv", arg: 2, scope: !18, file: !14, line: 2, type: !11)
+!26 = !DILocation(line: 2, column: 26, scope: !18)
+!27 = !DILocation(line: 2, column: 52, scope: !18)
+!28 = !DILocation(line: 2, column: 38, scope: !18)
+!29 = !DILocation(line: 2, column: 36, scope: !18)
+!30 = !DILocalVariable(name: "y", scope: !18, file: !14, line: 2, type: !11)
+!31 = !DILocation(line: 2, column: 68, scope: !18)
+!32 = !DILocation(line: 2, column: 92, scope: !18)
+!33 = !DILocation(line: 2, column: 91, scope: !18)
+!34 = !DILocation(line: 2, column: 84, scope: !18)
diff --git a/llvm/test/Transforms/GlobalOpt/localize-constexpr.ll b/llvm/test/Transforms/GlobalOpt/localize-constexpr.ll
new file mode 100644
index 00000000000..3fa7db89b04
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/localize-constexpr.ll
@@ -0,0 +1,28 @@
+; RUN: opt -S < %s -globalopt | FileCheck %s
+
+@G = internal global i32 42
+
+define i8 @f() norecurse {
+; CHECK-LABEL: @f
+; CHECK: alloca
+; CHECK-NOT: @G
+; CHECK: }
+ store i32 42, i32* @G
+ %a = load i8, i8* bitcast (i32* @G to i8*)
+ ret i8 %a
+}
+
+@H = internal global i32 42
+@Halias = alias i32, i32* @H
+
+; @H can't be localized because @Halias uses it, and @Halias can't be converted to an instruction.
+define i8 @g() norecurse {
+; CHECK-LABEL: @g
+; CHECK-NOT: alloca
+; CHECK: @H
+; CHECK: }
+ store i32 42, i32* @H
+ %a = load i8, i8* bitcast (i32* @H to i8*)
+ ret i8 %a
+}
+
diff --git a/llvm/test/Transforms/GlobalOpt/malloc-promote-1-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/malloc-promote-1-no-null-opt.ll
new file mode 100644
index 00000000000..fc6dab31640
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/malloc-promote-1-no-null-opt.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global i32* null ; <i32**> [#uses=3]
+; CHECK: global
+
+define void @init() #0 {
+; CHECK-LABEL: @init(
+; CHECK: store
+; CHECK: load
+ %malloccall = tail call i8* @malloc(i64 4) ; <i8*> [#uses=1]
+ %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1]
+ store i32* %P, i32** @G
+ %GV = load i32*, i32** @G ; <i32*> [#uses=1]
+ store i32 0, i32* %GV
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @get() #0 {
+; CHECK-LABEL: @get(
+; CHECK: load i32*, i32** @G
+; CHECK-NEXT: load i32, i32* %GV
+ %GV = load i32*, i32** @G ; <i32*> [#uses=1]
+ %V = load i32, i32* %GV ; <i32> [#uses=1]
+ ret i32 %V
+; CHECK: ret i32 %V
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/malloc-promote-1.ll b/llvm/test/Transforms/GlobalOpt/malloc-promote-1.ll
new file mode 100644
index 00000000000..a8f127474e3
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/malloc-promote-1.ll
@@ -0,0 +1,32 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global i32* null ; <i32**> [#uses=4]
+; CHECK-NOT: global
+
+define void @init() {
+ %malloccall = tail call i8* @malloc(i64 4) ; <i8*> [#uses=1]
+ %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1]
+ store i32* %P, i32** @G
+ %GV = load i32*, i32** @G ; <i32*> [#uses=1]
+ store i32 0, i32* %GV
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define i32 @get() {
+ %GV = load i32*, i32** @G ; <i32*> [#uses=1]
+ %V = load i32, i32* %GV ; <i32> [#uses=1]
+ ret i32 %V
+; CHECK: ret i32 0
+}
+
+define void @foo(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load i32*, i32** @G, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
+
diff --git a/llvm/test/Transforms/GlobalOpt/malloc-promote-2-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/malloc-promote-2-no-null-opt.ll
new file mode 100644
index 00000000000..009a33435fd
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/malloc-promote-2-no-null-opt.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global i32* null
+
+define void @t() #0 {
+; CHECK: @t()
+; CHECK: call i8* @malloc
+; CHECK: bitcast
+; CHECK: store
+; CHECK: load
+; CHECK: getelementptr
+; CHECK: store
+ %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4))
+ %P = bitcast i8* %malloccall to i32*
+ store i32* %P, i32** @G
+ %GV = load i32*, i32** @G
+ %GVe = getelementptr i32, i32* %GV, i32 40
+ store i32 20, i32* %GVe
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/malloc-promote-2.ll b/llvm/test/Transforms/GlobalOpt/malloc-promote-2.ll
new file mode 100644
index 00000000000..64f379365c7
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/malloc-promote-2.ll
@@ -0,0 +1,27 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global i32* null
+
+define void @t() {
+; CHECK: @t()
+; CHECK-NOT: call i8* @malloc
+; CHECK-NEXT: ret void
+ %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4))
+ %P = bitcast i8* %malloccall to i32*
+ store i32* %P, i32** @G
+ %GV = load i32*, i32** @G
+ %GVe = getelementptr i32, i32* %GV, i32 40
+ store i32 20, i32* %GVe
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
+
+define void @foo(i64 %Size) nounwind noinline #0 {
+entry:
+ %0 = load i32*, i32** @G, align 4
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/malloc-promote-3.ll b/llvm/test/Transforms/GlobalOpt/malloc-promote-3.ll
new file mode 100644
index 00000000000..1e42c3b89a6
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/malloc-promote-3.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+@G = internal global i32* null
+
+define void @t() {
+; CHECK: @t()
+; CHECK: call i8* @malloc
+ %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) nobuiltin
+ %P = bitcast i8* %malloccall to i32*
+ store i32* %P, i32** @G
+ %GV = load i32*, i32** @G
+ %GVe = getelementptr i32, i32* %GV, i32 40
+ store i32 20, i32* %GVe
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
diff --git a/llvm/test/Transforms/GlobalOpt/memcpy.ll b/llvm/test/Transforms/GlobalOpt/memcpy.ll
new file mode 100644
index 00000000000..0e65f381c1c
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/memcpy.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: G1 = internal unnamed_addr constant
+
+@G1 = internal global [58 x i8] c"asdlfkajsdlfkajsd;lfkajds;lfkjasd;flkajsd;lkfja;sdlkfjasd\00" ; <[58 x i8]*> [#uses=1]
+
+define void @foo() {
+ %Blah = alloca [58 x i8]
+ %tmp.0 = getelementptr [58 x i8], [58 x i8]* %Blah, i32 0, i32 0
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %tmp.0, i8* align 1 getelementptr inbounds ([58 x i8], [58 x i8]* @G1, i32 0, i32 0), i32 58, i1 false)
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
diff --git a/llvm/test/Transforms/GlobalOpt/memset-null.ll b/llvm/test/Transforms/GlobalOpt/memset-null.ll
new file mode 100644
index 00000000000..32bd21cfc58
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/memset-null.ll
@@ -0,0 +1,29 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+; PR10047
+
+%0 = type { i32, void ()* }
+%struct.A = type { [100 x i32] }
+
+; CHECK: @a
+@a = global %struct.A zeroinitializer, align 4
+@llvm.global_ctors = appending global [2 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I_a }, %0 { i32 65535, void ()* @_GLOBAL__I_b }]
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
+
+; CHECK-NOT: GLOBAL__I_a
+define internal void @_GLOBAL__I_a() nounwind {
+entry:
+ tail call void @llvm.memset.p0i8.i64(i8* align 4 bitcast (%struct.A* @a to i8*), i8 0, i64 400, i1 false) nounwind
+ ret void
+}
+
+%struct.X = type { i8 }
+@y = global i8* null, align 8
+@x = global %struct.X zeroinitializer, align 1
+
+define internal void @_GLOBAL__I_b() nounwind {
+entry:
+ %tmp.i.i.i = load i8*, i8** @y, align 8
+ tail call void @llvm.memset.p0i8.i64(i8* %tmp.i.i.i, i8 0, i64 10, i1 false) nounwind
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/memset.ll b/llvm/test/Transforms/GlobalOpt/memset.ll
new file mode 100644
index 00000000000..90a3db8cb7b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/memset.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; CHECK-NOT: internal
+
+; Both globals are write only, delete them.
+
+@G0 = internal global [58 x i8] c"asdlfkajsdlfkajsd;lfkajds;lfkjasd;flkajsd;lkfja;sdlkfjasd\00" ; <[58 x i8]*> [#uses=1]
+@G1 = internal global [4 x i32] [ i32 1, i32 2, i32 3, i32 4 ] ; <[4 x i32]*> [#uses=1]
+
+define void @foo() {
+ %Blah = alloca [58 x i8]
+ %tmp3 = bitcast [58 x i8]* %Blah to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([4 x i32]* @G1 to i8*), i8* %tmp3, i32 16, i1 false)
+ call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([58 x i8], [58 x i8]* @G0, i32 0, i32 0), i8 17, i32 58, i1 false)
+ ret void
+}
+
+@G0_as1 = internal addrspace(1) global [58 x i8] c"asdlfkajsdlfkajsd;lfkajds;lfkjasd;flkajsd;lkfja;sdlkfjasd\00" ; <[58 x i8]*> [#uses=1]
+@G1_as1 = internal addrspace(1) global [4 x i32] [ i32 1, i32 2, i32 3, i32 4 ] ; <[4 x i32]*> [#uses=1]
+
+define void @foo_as1() {
+ %Blah = alloca [58 x i8]
+ %tmp3 = bitcast [58 x i8]* %Blah to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* addrspacecast ([4 x i32] addrspace(1)* @G1_as1 to i8*), i8* %tmp3, i32 16, i1 false)
+ call void @llvm.memset.p1i8.i32(i8 addrspace(1)* getelementptr inbounds ([58 x i8], [58 x i8] addrspace(1)* @G0_as1, i32 0, i32 0), i8 17, i32 58, i1 false)
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
+declare void @llvm.memset.p1i8.i32(i8 addrspace(1)* nocapture, i8, i32, i1) nounwind
diff --git a/llvm/test/Transforms/GlobalOpt/metadata.ll b/llvm/test/Transforms/GlobalOpt/metadata.ll
new file mode 100644
index 00000000000..b766349d506
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/metadata.ll
@@ -0,0 +1,32 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; PR6112 - When globalopt does RAUW(@G, %G), the metadata reference should drop
+; to null. Function local metadata that references @G from a different function
+; to that containing %G should likewise drop to null.
+@G = internal global i8** null
+
+define i32 @main(i32 %argc, i8** %argv) norecurse {
+; CHECK-LABEL: @main(
+; CHECK: %G = alloca
+ store i8** %argv, i8*** @G
+ ret i32 0
+}
+
+define void @foo(i32 %x) {
+; Note: these arguments look like MDNodes, but they're really syntactic sugar
+; for 'MetadataAsValue::get(ValueAsMetadata::get(Value*))'. When @G drops to
+; null, the ValueAsMetadata instance gets replaced by metadata !{}, or
+; MDNode::get({}).
+ call void @llvm.foo(metadata i8*** @G, metadata i32 %x)
+; CHECK: call void @llvm.foo(metadata ![[EMPTY:[0-9]+]], metadata i32 %x)
+ ret void
+}
+
+declare void @llvm.foo(metadata, metadata) nounwind readnone
+
+!named = !{!0}
+; CHECK: !named = !{![[NULL:[0-9]+]]}
+
+!0 = !{i8*** @G}
+; CHECK-DAG: ![[NULL]] = distinct !{null}
+; CHECK-DAG: ![[EMPTY]] = !{}
diff --git a/llvm/test/Transforms/GlobalOpt/musttail_cc.ll b/llvm/test/Transforms/GlobalOpt/musttail_cc.ll
new file mode 100644
index 00000000000..fc927ea91dd
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/musttail_cc.ll
@@ -0,0 +1,34 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; PR36546
+
+; Check that musttail callee preserves its calling convention
+
+define i32 @test(i32 %a) {
+ ; CHECK: %ca = musttail call i32 @foo(i32 %a)
+ %ca = musttail call i32 @foo(i32 %a)
+ ret i32 %ca
+}
+
+; CHECK-LABEL: define internal i32 @foo(i32 %a)
+define internal i32 @foo(i32 %a) {
+ ret i32 %a
+}
+
+; Check that musttail caller preserves its calling convention
+
+define i32 @test2(i32 %a) {
+ %ca = call i32 @foo1(i32 %a)
+ ret i32 %ca
+}
+
+; CHECK-LABEL: define internal i32 @foo1(i32 %a)
+define internal i32 @foo1(i32 %a) {
+ ; CHECK: %ca = musttail call i32 @foo2(i32 %a)
+ %ca = musttail call i32 @foo2(i32 %a)
+ ret i32 %ca
+}
+
+; CHECK-LABEL: define internal i32 @foo2(i32 %a)
+define internal i32 @foo2(i32 %a) {
+ ret i32 %a
+}
diff --git a/llvm/test/Transforms/GlobalOpt/naked_functions.ll b/llvm/test/Transforms/GlobalOpt/naked_functions.ll
new file mode 100644
index 00000000000..80c3aa8c3b2
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/naked_functions.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; Check that naked functions don't get marked with fast calling conventions
+
+@g = common global i32 0, align 4
+
+define i32 @bar() {
+entry:
+ %call = call i32 @foo(i32* @g)
+; CHECK: %call = call i32 @foo(i32* @g)
+ ret i32 %call
+}
+
+define internal i32 @foo(i32*) #0 {
+entry:
+ %retval = alloca i32, align 4
+ call void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
+ unreachable
+}
+
+; CHECK: define internal i32 @foo(i32*)
+
+attributes #0 = { naked }
diff --git a/llvm/test/Transforms/GlobalOpt/phi-select.ll b/llvm/test/Transforms/GlobalOpt/phi-select.ll
new file mode 100644
index 00000000000..86b017c9cb3
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/phi-select.ll
@@ -0,0 +1,27 @@
+; Test that PHI nodes and select instructions do not necessarily make stuff
+; non-constant.
+
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: global
+
+@X = internal global i32 4 ; <i32*> [#uses=2]
+@Y = internal global i32 5 ; <i32*> [#uses=2]
+
+define i32 @test1(i1 %C) {
+ %P = select i1 %C, i32* @X, i32* @Y ; <i32*> [#uses=1]
+ %V = load i32, i32* %P ; <i32> [#uses=1]
+ ret i32 %V
+}
+
+define i32 @test2(i1 %C) {
+; <label>:0
+ br i1 %C, label %T, label %Cont
+
+T: ; preds = %0
+ br label %Cont
+
+Cont: ; preds = %T, %0
+ %P = phi i32* [ @X, %0 ], [ @Y, %T ] ; <i32*> [#uses=1]
+ %V = load i32, i32* %P ; <i32> [#uses=1]
+ ret i32 %V
+}
diff --git a/llvm/test/Transforms/GlobalOpt/pr21191.ll b/llvm/test/Transforms/GlobalOpt/pr21191.ll
new file mode 100644
index 00000000000..9e201b888be
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/pr21191.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+$c = comdat any
+; CHECK: $c = comdat any
+
+define linkonce_odr void @foo() comdat($c) {
+ ret void
+}
+; CHECK: define linkonce_odr void @foo() local_unnamed_addr comdat($c)
+
+define linkonce_odr void @bar() comdat($c) {
+ ret void
+}
+; CHECK: define linkonce_odr void @bar() local_unnamed_addr comdat($c)
+
+define void @zed() {
+ call void @foo()
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/pr33686.ll b/llvm/test/Transforms/GlobalOpt/pr33686.ll
new file mode 100644
index 00000000000..d6bb98735f4
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/pr33686.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -globalopt %s | FileCheck %s
+
+@glob = external global i16, align 1
+
+define void @beth() {
+; CHECK-LABEL: @beth(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret void
+;
+entry:
+ ret void
+
+notreachable:
+ %patatino = select i1 undef, i16* @glob, i16* %patatino
+ br label %notreachable
+}
diff --git a/llvm/test/Transforms/GlobalOpt/preserve-comdats.ll b/llvm/test/Transforms/GlobalOpt/preserve-comdats.ll
new file mode 100644
index 00000000000..0148f0024b9
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/preserve-comdats.ll
@@ -0,0 +1,37 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+
+$comdat_global = comdat any
+
+@comdat_global = weak_odr global i8 0, comdat($comdat_global)
+@simple_global = internal global i8 0
+; CHECK: @comdat_global = weak_odr global i8 0, comdat{{$}}
+; CHECK: @simple_global = internal global i8 42
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [
+ { i32, void ()*, i8* } { i32 65535, void ()* @init_comdat_global, i8* @comdat_global },
+ { i32, void ()*, i8* } { i32 65535, void ()* @init_simple_global, i8* null }
+]
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
+; CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @init_comdat_global, i8* @comdat_global }]
+
+define void @init_comdat_global() {
+ store i8 42, i8* @comdat_global
+ ret void
+}
+; CHECK: define void @init_comdat_global()
+
+define internal void @init_simple_global() comdat($comdat_global) {
+ store i8 42, i8* @simple_global
+ ret void
+}
+; CHECK-NOT: @init_simple_global()
+
+define i8* @use_simple() {
+ ret i8* @simple_global
+}
+; CHECK: define i8* @use_simple()
+
+define i8* @use_comdat() {
+ ret i8* @comdat_global
+}
+; CHECK: define i8* @use_comdat()
diff --git a/llvm/test/Transforms/GlobalOpt/shrink-address-to-bool.ll b/llvm/test/Transforms/GlobalOpt/shrink-address-to-bool.ll
new file mode 100644
index 00000000000..1a298b04e9b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/shrink-address-to-bool.ll
@@ -0,0 +1,46 @@
+;RUN: opt -S -globalopt -f %s | FileCheck %s
+
+;CHECK: @foo = {{.*}}, !dbg !0
+@foo = global i64 ptrtoint ([1 x i64]* @baa to i64), align 8, !dbg !0
+@baa = common global [1 x i64] zeroinitializer, align 8, !dbg !6
+
+; Function Attrs: noinline nounwind optnone uwtable
+define void @fun() #0 !dbg !16 {
+entry:
+ %0 = load i64, i64* @foo, align 8, !dbg !19
+ %1 = inttoptr i64 %0 to i64*, !dbg !19
+ %cmp = icmp ugt i64* getelementptr inbounds ([1 x i64], [1 x i64]* @baa, i32 0, i32 0), %1, !dbg !20
+ %conv = zext i1 %cmp to i32, !dbg !20
+ store i64 0, i64* @foo, align 8, !dbg !21
+ ret void, !dbg !22
+}
+
+attributes #0 = { noinline nounwind optnone uwtable }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "shrink-address-to-bool.c", directory: "/")
+!4 = !{}
+!5 = !{!0, !6}
+!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
+!7 = distinct !DIGlobalVariable(name: "baa", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
+!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 64, elements: !10)
+!9 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
+!10 = !{!11}
+!11 = !DISubrange(count: 1)
+!12 = !{i32 2, !"Dwarf Version", i32 4}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"wchar_size", i32 4}
+!15 = !{!"clang version 6.0.0 "}
+!16 = distinct !DISubprogram(name: "fun", scope: !3, file: !3, line: 4, type: !17, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized: false, unit: !2, retainedNodes: !4)
+!17 = !DISubroutineType(types: !18)
+!18 = !{null}
+!19 = !DILocation(line: 5, column: 9, scope: !16)
+!20 = !DILocation(line: 5, column: 7, scope: !16)
+!21 = !DILocation(line: 6, column: 7, scope: !16)
+!22 = !DILocation(line: 7, column: 1, scope: !16)
diff --git a/llvm/test/Transforms/GlobalOpt/shrink-global-to-bool-check-debug.ll b/llvm/test/Transforms/GlobalOpt/shrink-global-to-bool-check-debug.ll
new file mode 100644
index 00000000000..71019128bb1
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/shrink-global-to-bool-check-debug.ll
@@ -0,0 +1,22 @@
+;RUN: opt -S -debugify -globalopt -f %s | FileCheck %s
+
+@foo = internal global i32 0, align 4
+
+define dso_local i32 @bar() {
+entry:
+ store i32 5, i32* @foo, align 4
+ %0 = load i32, i32* @foo, align 4
+ ret i32 %0
+}
+
+;CHECK: @bar
+;CHECK-NEXT: entry:
+;CHECK-NEXT: store i1 true, i1* @foo, !dbg ![[DbgLocStore:[0-9]+]]
+;CHECK-NEXT: %.b = load i1, i1* @foo, !dbg ![[DbgLocLoadSel:[0-9]+]]
+;CHECK-NEXT: %0 = select i1 %.b, i32 5, i32 0, !dbg ![[DbgLocLoadSel]]
+;CHECK-NEXT: call void @llvm.dbg.value({{.*}}), !dbg ![[DbgLocLoadSel]]
+;CHECK-NEXT: ret i32 %0, !dbg ![[DbgLocRet:[0-9]+]]
+
+;CHECK: ![[DbgLocStore]] = !DILocation(line: 1,
+;CHECK: ![[DbgLocLoadSel]] = !DILocation(line: 2,
+;CHECK: ![[DbgLocRet]] = !DILocation(line: 3,
diff --git a/llvm/test/Transforms/GlobalOpt/static-const-bitcast.ll b/llvm/test/Transforms/GlobalOpt/static-const-bitcast.ll
new file mode 100644
index 00000000000..52da721b55f
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/static-const-bitcast.ll
@@ -0,0 +1,62 @@
+; RUN: opt -globalopt %s -S -o - | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.A = type { %class.Wrapper }
+%class.Wrapper = type { i32 }
+
+$Wrapper = comdat any
+
+@kA = internal global %struct.A zeroinitializer, align 4
+; CHECK: @kA = internal unnamed_addr constant %struct.A { %class.Wrapper { i32 1036831949 } }, align 4
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } {
+i32 65535, void ()* @_GLOBAL__sub_I_const_static.cc, i8* null }]
+
+define dso_local i32 @AsBits(float* %x) #0 {
+entry:
+ %0 = bitcast float* %x to i32*
+ %1 = load i32, i32* %0, align 4
+ ret i32 %1
+}
+
+define internal void @__cxx_global_var_init() #1 section ".text.startup" {
+entry:
+ call void @Wrapper(%class.Wrapper* getelementptr inbounds (%struct.A, %struct.A* @kA, i32 0, i32 0), float 0x3FB99999A0000000)
+ %0 = call {}* @llvm.invariant.start.p0i8(i64 4, i8* bitcast (%struct.A* @kA to i8*))
+ ret void
+}
+
+define linkonce_odr dso_local void @Wrapper(%class.Wrapper* %this, float %x) unnamed_addr #0 comdat align 2 {
+entry:
+ %x.addr = alloca float, align 4
+ store float %x, float* %x.addr, align 4
+ %store_ = getelementptr inbounds %class.Wrapper, %class.Wrapper* %this, i32 0, i32 0
+ %call = call i32 @AsBits(float* %x.addr)
+ store i32 %call, i32* %store_, align 4
+ ret void
+}
+
+declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) #2
+
+; Function Attrs: nounwind uwtable
+define dso_local void @LoadIt(%struct.A* %c) #0 {
+entry:
+ %0 = bitcast %struct.A* %c to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast (%struct.A* @kA to i8*), i64 4, i1 false)
+ ret void
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #2
+
+; Function Attrs: uwtable
+define internal void @_GLOBAL__sub_I_const_static.cc() #1 section ".text.startup" {
+entry:
+ call void @__cxx_global_var_init()
+ ret void
+}
+
+attributes #0 = { nounwind uwtable "target-cpu"="x86-64" }
+attributes #1 = { uwtable "target-cpu"="x86-64" }
+attributes #2 = { argmemonly nounwind }
diff --git a/llvm/test/Transforms/GlobalOpt/storepointer-compare-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/storepointer-compare-no-null-opt.ll
new file mode 100644
index 00000000000..709df17e0b5
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/storepointer-compare-no-null-opt.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: global
+
+@G = internal global void ()* null ; <void ()**> [#uses=2]
+
+define internal void @Actual() {
+; CHECK-LABEL: Actual(
+ ret void
+}
+
+define void @init() {
+; CHECK-LABEL: init(
+; CHECK: store void ()* @Actual, void ()** @G
+ store void ()* @Actual, void ()** @G
+ ret void
+}
+
+define void @doit() #0 {
+; CHECK-LABEL: doit(
+ %FP = load void ()*, void ()** @G ; <void ()*> [#uses=2]
+; CHECK: %FP = load void ()*, void ()** @G
+ %CC = icmp eq void ()* %FP, null ; <i1> [#uses=1]
+; CHECK: %CC = icmp eq void ()* %FP, null
+ br i1 %CC, label %isNull, label %DoCall
+; CHECK: br i1 %CC, label %isNull, label %DoCall
+
+DoCall: ; preds = %0
+; CHECK: DoCall:
+; CHECK: call void %FP()
+; CHECK: ret void
+ call void %FP( )
+ ret void
+
+isNull: ; preds = %0
+; CHECK: isNull:
+; CHECK: ret void
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/storepointer-compare.ll b/llvm/test/Transforms/GlobalOpt/storepointer-compare.ll
new file mode 100644
index 00000000000..969443569c2
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/storepointer-compare.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK: call void @Actual
+
+; Check that a comparison does not prevent an indirect call from being made
+; direct. The global will still remain, but indirect call elim is still good.
+
+@G = internal global void ()* null ; <void ()**> [#uses=2]
+
+define internal void @Actual() {
+ ret void
+}
+
+define void @init() {
+ store void ()* @Actual, void ()** @G
+ ret void
+}
+
+define void @doit() {
+ %FP = load void ()*, void ()** @G ; <void ()*> [#uses=2]
+ %CC = icmp eq void ()* %FP, null ; <i1> [#uses=1]
+ br i1 %CC, label %isNull, label %DoCall
+
+DoCall: ; preds = %0
+ call void %FP( )
+ ret void
+
+isNull: ; preds = %0
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/storepointer-no-null-opt.ll b/llvm/test/Transforms/GlobalOpt/storepointer-no-null-opt.ll
new file mode 100644
index 00000000000..c9a63f0080d
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/storepointer-no-null-opt.ll
@@ -0,0 +1,27 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+@G = internal global void ()* null ; <void ()**> [#uses=2]
+; CHECK: global
+
+define internal void @Actual() {
+; CHECK-LABEL: Actual(
+ ret void
+}
+
+define void @init() {
+; CHECK-LABEL: init(
+; CHECK: store void ()* @Actual, void ()** @G
+ store void ()* @Actual, void ()** @G
+ ret void
+}
+
+define void @doit() #0 {
+; CHECK-LABEL: doit(
+; CHECK: %FP = load void ()*, void ()** @G
+; CHECK: call void %FP()
+ %FP = load void ()*, void ()** @G ; <void ()*> [#uses=1]
+ call void %FP( )
+ ret void
+}
+
+attributes #0 = { "null-pointer-is-valid"="true" }
diff --git a/llvm/test/Transforms/GlobalOpt/storepointer.ll b/llvm/test/Transforms/GlobalOpt/storepointer.ll
new file mode 100644
index 00000000000..8edaa64a62b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/storepointer.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: global
+
+@G = internal global void ()* null ; <void ()**> [#uses=2]
+
+define internal void @Actual() {
+ ret void
+}
+
+define void @init() {
+ store void ()* @Actual, void ()** @G
+ ret void
+}
+
+define void @doit() {
+ %FP = load void ()*, void ()** @G ; <void ()*> [#uses=1]
+ call void %FP( )
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/tls.ll b/llvm/test/Transforms/GlobalOpt/tls.ll
new file mode 100644
index 00000000000..d010b96188f
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/tls.ll
@@ -0,0 +1,54 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; RUN: opt -emulated-tls < %s -globalopt -S | FileCheck %s
+
+declare void @wait()
+declare void @signal()
+declare void @start_thread(void ()*)
+
+@x = internal thread_local global [100 x i32] zeroinitializer, align 16
+@ip = internal global i32* null, align 8
+
+; PR14309: GlobalOpt would think that the value of @ip is always the address of
+; x[1]. However, that address is different for different threads so @ip cannot
+; be replaced with a constant.
+
+define i32 @f() {
+entry:
+ ; Set @ip to point to x[1] for thread 1.
+ store i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), i32** @ip, align 8
+
+ ; Run g on a new thread.
+ tail call void @start_thread(void ()* @g) nounwind
+ tail call void @wait() nounwind
+
+ ; Reset x[1] for thread 1.
+ store i32 0, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), align 4
+
+ ; Read the value of @ip, which now points at x[1] for thread 2.
+ %0 = load i32*, i32** @ip, align 8
+
+ %1 = load i32, i32* %0, align 4
+ ret i32 %1
+
+; CHECK-LABEL: @f(
+; Make sure that the load from @ip hasn't been removed.
+; CHECK: load i32*, i32** @ip
+; CHECK: ret
+}
+
+define internal void @g() nounwind uwtable {
+entry:
+ ; Set @ip to point to x[1] for thread 2.
+ store i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), i32** @ip, align 8
+
+ ; Store 50 in x[1] for thread 2.
+ store i32 50, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), align 4
+
+ tail call void @signal() nounwind
+ ret void
+
+; CHECK-LABEL: @g(
+; Make sure that the store to @ip hasn't been removed.
+; CHECK: store {{.*}} @ip
+; CHECK: ret
+}
diff --git a/llvm/test/Transforms/GlobalOpt/trivialstore.ll b/llvm/test/Transforms/GlobalOpt/trivialstore.ll
new file mode 100644
index 00000000000..9a490879a41
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/trivialstore.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: G
+
+@G = internal global i32 17 ; <i32*> [#uses=3]
+
+define void @foo() {
+ store i32 17, i32* @G
+ ret void
+}
+
+define i32 @bar() {
+ %X = load i32, i32* @G ; <i32> [#uses=1]
+ ret i32 %X
+}
+
+define internal void @dead() {
+ store i32 123, i32* @G
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/undef-init.ll b/llvm/test/Transforms/GlobalOpt/undef-init.ll
new file mode 100644
index 00000000000..71fad343e56
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/undef-init.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; CHECK-NOT: store
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I__Z3foov } ] ; <[1 x { i32, void ()* }]*> [#uses=0]
+@X.0 = internal global i32 undef ; <i32*> [#uses=2]
+
+define i32 @_Z3foov() {
+entry:
+ %tmp.1 = load i32, i32* @X.0 ; <i32> [#uses=1]
+ ret i32 %tmp.1
+}
+
+define internal void @_GLOBAL__I__Z3foov() {
+entry:
+ store i32 1, i32* @X.0
+ ret void
+}
diff --git a/llvm/test/Transforms/GlobalOpt/unnamed-addr.ll b/llvm/test/Transforms/GlobalOpt/unnamed-addr.ll
new file mode 100644
index 00000000000..9f11f1bd92c
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/unnamed-addr.ll
@@ -0,0 +1,74 @@
+; RUN: opt -globalopt -S < %s | FileCheck %s
+
+@a = internal global i32 0, align 4
+@b = internal global i32 0, align 4
+@c = internal global i32 0, align 4
+@d = internal constant [4 x i8] c"foo\00", align 1
+@e = linkonce_odr global i32 0
+
+; CHECK: @a = internal global i32 0, align 4
+; CHECK: @b = internal global i32 0, align 4
+; CHECK: @c = internal unnamed_addr global i32 0, align 4
+; CHECK: @d = internal unnamed_addr constant [4 x i8] c"foo\00", align 1
+; CHECK: @e = linkonce_odr local_unnamed_addr global i32 0
+
+; CHECK: define internal fastcc void @used_internal() unnamed_addr {
+define internal void @used_internal() {
+ ret void
+}
+
+define i32 @get_e() {
+ call void @used_internal()
+ %t = load i32, i32* @e
+ ret i32 %t
+}
+
+define void @set_e(i32 %x) {
+ store i32 %x, i32* @e
+ ret void
+}
+
+define i1 @bah(i64 %i) nounwind readonly optsize ssp {
+entry:
+ %arrayidx4 = getelementptr inbounds [4 x i8], [4 x i8]* @d, i64 0, i64 %i
+ %tmp5 = load i8, i8* %arrayidx4, align 1
+ %array0 = bitcast [4 x i8]* @d to i8*
+ %tmp6 = load i8, i8* %array0, align 1
+ %cmp = icmp eq i8 %tmp5, %tmp6
+ ret i1 %cmp
+}
+
+define void @baz(i32 %x) {
+entry:
+ store i32 %x, i32* @a, align 4
+ store i32 %x, i32* @b, align 4
+ store i32 %x, i32* @c, align 4
+ ret void
+}
+
+define i32 @foo(i32* %x) nounwind readnone optsize ssp {
+entry:
+ %cmp = icmp eq i32* %x, @a
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @bar() {
+entry:
+ switch i64 ptrtoint (i32* @b to i64), label %sw.epilog [
+ i64 1, label %return
+ i64 0, label %return
+ ]
+
+sw.epilog:
+ ret i32 0
+
+return:
+ ret i32 1
+}
+
+define i32 @zed() {
+entry:
+ %tmp1 = load i32, i32* @c, align 4
+ ret i32 %tmp1
+}
diff --git a/llvm/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll b/llvm/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll
new file mode 100644
index 00000000000..51feb480e3b
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+
+@zero = internal global [10 x i32] zeroinitializer
+
+define i32 @test1(i64 %idx) nounwind {
+ %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* @zero, i64 0, i64 %idx
+ %l = load i32, i32* %arrayidx
+ ret i32 %l
+; CHECK-LABEL: @test1(
+; CHECK: ret i32 0
+}
OpenPOWER on IntegriCloud