summaryrefslogtreecommitdiff
path: root/test/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll5
-rw-r--r--test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll2
-rw-r--r--test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll9
-rw-r--r--test/Transforms/ADCE/dce_pure_invoke.ll4
-rw-r--r--test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll4
-rw-r--r--test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll5
-rw-r--r--test/Transforms/ConstantMerge/merge-both.ll17
-rw-r--r--test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll6
-rw-r--r--test/Transforms/DeadArgElim/deadexternal.ll2
-rw-r--r--test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll27
-rw-r--r--test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll85
-rw-r--r--test/Transforms/DeadStoreElimination/atomic.ll107
-rw-r--r--test/Transforms/DeadStoreElimination/simple.ll8
-rw-r--r--test/Transforms/EarlyCSE/basic.ll10
-rw-r--r--test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll4
-rw-r--r--test/Transforms/FunctionAttrs/atomic.ll21
-rw-r--r--test/Transforms/GVN/2010-05-08-OneBit.ll4
-rw-r--r--test/Transforms/GVN/2011-09-07-TypeIdFor.ll81
-rw-r--r--test/Transforms/GVN/atomic.ll80
-rw-r--r--test/Transforms/GVN/condprop.ll83
-rw-r--r--test/Transforms/GVN/phi-translate.ll2
-rw-r--r--test/Transforms/GVN/pr10820.ll18
-rw-r--r--test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll2
-rw-r--r--test/Transforms/IPConstantProp/global.ll26
-rw-r--r--test/Transforms/IPConstantProp/return-argument.ll10
-rw-r--r--test/Transforms/IPConstantProp/return-constant.ll4
-rw-r--r--test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll15
-rw-r--r--test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll15
-rw-r--r--test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll8
-rw-r--r--test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll10
-rw-r--r--test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll6
-rw-r--r--test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll2
-rw-r--r--test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll2
-rw-r--r--test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll30
-rw-r--r--test/Transforms/IndVarSimplify/2011-09-19-vectoriv.ll16
-rw-r--r--test/Transforms/IndVarSimplify/2011-09-27-hoistsext.ll28
-rw-r--r--test/Transforms/IndVarSimplify/ada-loops.ll9
-rw-r--r--test/Transforms/IndVarSimplify/addrec-gep.ll12
-rw-r--r--test/Transforms/IndVarSimplify/ashr-tripcount.ll2
-rw-r--r--test/Transforms/IndVarSimplify/complex-scev.ll4
-rw-r--r--test/Transforms/IndVarSimplify/crash.ll34
-rw-r--r--test/Transforms/IndVarSimplify/elim-extend.ll2
-rw-r--r--test/Transforms/IndVarSimplify/floating-point-iv.ll8
-rw-r--r--test/Transforms/IndVarSimplify/gep-with-mul-base.ll17
-rw-r--r--test/Transforms/IndVarSimplify/interesting-invoke-use.ll4
-rw-r--r--test/Transforms/IndVarSimplify/iv-fold.ll56
-rw-r--r--test/Transforms/IndVarSimplify/iv-sext.ll2
-rw-r--r--test/Transforms/IndVarSimplify/iv-zext.ll4
-rw-r--r--test/Transforms/IndVarSimplify/lftr-reuse.ll230
-rw-r--r--test/Transforms/IndVarSimplify/max-pointer.ll39
-rw-r--r--test/Transforms/IndVarSimplify/no-iv-rewrite.ll84
-rw-r--r--test/Transforms/IndVarSimplify/pointer-indvars.ll15
-rw-r--r--test/Transforms/IndVarSimplify/pointer.ll38
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll10
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep-nested.ll23
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep-remainder.ll6
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep.ll10
-rw-r--r--test/Transforms/IndVarSimplify/preserve-signed-wrap.ll2
-rw-r--r--test/Transforms/IndVarSimplify/subtract.ll15
-rw-r--r--test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll2
-rw-r--r--test/Transforms/Inline/2003-09-14-InlineValue.ll4
-rw-r--r--test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll9
-rw-r--r--test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll20
-rw-r--r--test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll2
-rw-r--r--test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll2
-rw-r--r--test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll20
-rw-r--r--test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll12
-rw-r--r--test/Transforms/Inline/2007-04-15-InlineEH.ll6
-rw-r--r--test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll2
-rw-r--r--test/Transforms/Inline/callgraph-update.ll3
-rw-r--r--test/Transforms/Inline/crash.ll10
-rw-r--r--test/Transforms/Inline/inline_invoke.ll122
-rw-r--r--test/Transforms/Inline/invoke_test-1.ll4
-rw-r--r--test/Transforms/Inline/invoke_test-2.ll6
-rw-r--r--test/Transforms/Inline/invoke_test-3.ll8
-rw-r--r--test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll3
-rw-r--r--test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll3
-rw-r--r--test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll6
-rw-r--r--test/Transforms/InstCombine/2008-04-28-VolatileStore.ll2
-rw-r--r--test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll2
-rw-r--r--test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll2
-rw-r--r--test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll4
-rw-r--r--test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll2
-rw-r--r--test/Transforms/InstCombine/2011-09-03-Trampoline.ll87
-rw-r--r--test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll20
-rw-r--r--test/Transforms/InstCombine/LandingPadClauses.ll181
-rw-r--r--test/Transforms/InstCombine/and2.ll7
-rw-r--r--test/Transforms/InstCombine/atomic.ll24
-rw-r--r--test/Transforms/InstCombine/bitcast.ll34
-rw-r--r--test/Transforms/InstCombine/call.ll20
-rw-r--r--test/Transforms/InstCombine/canonicalize_branch.ll31
-rw-r--r--test/Transforms/InstCombine/cast.ll47
-rw-r--r--test/Transforms/InstCombine/crash.ll4
-rw-r--r--test/Transforms/InstCombine/deadcode.ll11
-rw-r--r--test/Transforms/InstCombine/devirt.ll39
-rw-r--r--test/Transforms/InstCombine/extractvalue.ll2
-rw-r--r--test/Transforms/InstCombine/fcmp.ll11
-rw-r--r--test/Transforms/InstCombine/getelementptr.ll20
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll12
-rw-r--r--test/Transforms/InstCombine/malloc-free-delete.ll25
-rw-r--r--test/Transforms/InstCombine/nsw.ll44
-rw-r--r--test/Transforms/InstCombine/ptr-int-cast.ll14
-rw-r--r--test/Transforms/InstCombine/select.ll10
-rw-r--r--test/Transforms/InstCombine/shift.ll19
-rw-r--r--test/Transforms/InstCombine/vec_demanded_elts.ll11
-rw-r--r--test/Transforms/InstCombine/vector-casts.ll2
-rw-r--r--test/Transforms/InstCombine/volatile_store.ll4
-rw-r--r--test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll29
-rw-r--r--test/Transforms/InstSimplify/compare.ll11
-rw-r--r--test/Transforms/JumpThreading/no-irreducible-loops.ll2
-rw-r--r--test/Transforms/LCSSA/invoke-dest.ll8
-rw-r--r--test/Transforms/LICM/2007-05-22-VolatileSink.ll2
-rw-r--r--test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll2
-rw-r--r--test/Transforms/LICM/atomics.ll79
-rw-r--r--test/Transforms/LICM/scalar-promote-memmodel.ll37
-rw-r--r--test/Transforms/LICM/scalar_promote.ll2
-rw-r--r--test/Transforms/LoopDeletion/2008-05-06-Phi.ll2
-rw-r--r--test/Transforms/LoopIdiom/basic.ll4
-rw-r--r--test/Transforms/LoopSimplify/2003-08-15-PreheadersFail.ll2
-rw-r--r--test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll887
-rw-r--r--test/Transforms/LoopSimplify/merge-exits.ll2
-rw-r--r--test/Transforms/LoopSimplify/preserve-scev.ll88
-rw-r--r--test/Transforms/LoopSimplify/single-backedge.ll9
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-07-19-CritEdgeBreakCrash.ll52
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-07-20-DoubleIV.ll43
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-10-03-CritEdgeMerge.ll43
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-10-06-ReusePhi.ll53
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-10-13-SCEVChain.ll111
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-10-14-IntPtr.ll27
-rw-r--r--test/Transforms/LoopStrengthReduce/invariant_value_first.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/ops_after_indvar.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll14
-rw-r--r--test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll2
-rw-r--r--test/Transforms/LoopUnroll/2011-08-08-PhiUpdate.ll103
-rw-r--r--test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll41
-rw-r--r--test/Transforms/LoopUnroll/2011-08-09-PhiUpdate.ll62
-rw-r--r--test/Transforms/LoopUnroll/2011-10-01-NoopTrunc.ll36
-rw-r--r--test/Transforms/LoopUnroll/pr10813.ll29
-rw-r--r--test/Transforms/LoopUnroll/scevunroll.ll172
-rw-r--r--test/Transforms/LoopUnroll/unloop.ll429
-rw-r--r--test/Transforms/LoopUnswitch/2011-09-26-EHCrash.ll67
-rw-r--r--test/Transforms/LowerAtomic/atomic-load.ll10
-rw-r--r--test/Transforms/LowerAtomic/atomic-swap.ll7
-rw-r--r--test/Transforms/LowerAtomic/barrier.ll4
-rw-r--r--test/Transforms/LowerSetJmp/2003-11-05-DominanceProperties.ll16
-rw-r--r--test/Transforms/LowerSetJmp/dg.exp3
-rw-r--r--test/Transforms/LowerSetJmp/simpletest.ll31
-rw-r--r--test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll2
-rw-r--r--test/Transforms/Mem2Reg/atomic.ll12
-rw-r--r--test/Transforms/Mem2Reg/crash.ll3
-rw-r--r--test/Transforms/MemCpyOpt/atomic.ll41
-rw-r--r--test/Transforms/ObjCARC/basic.ll110
-rw-r--r--test/Transforms/ObjCARC/cfg-hazards.ll329
-rw-r--r--test/Transforms/ObjCARC/contract-storestrong.ll4
-rw-r--r--test/Transforms/ObjCARC/empty-block.ll59
-rw-r--r--test/Transforms/ObjCARC/invoke.ll6
-rw-r--r--test/Transforms/ObjCARC/nested.ll620
-rw-r--r--test/Transforms/ObjCARC/retain-block-alloca.ll54
-rw-r--r--test/Transforms/ObjCARC/retain-block-side-effects.ll39
-rw-r--r--test/Transforms/ObjCARC/retain-not-declared.ll54
-rw-r--r--test/Transforms/ObjCARC/rv.ll11
-rw-r--r--test/Transforms/PhaseOrdering/2010-03-22-empty-baseclass.ll162
-rw-r--r--test/Transforms/PruneEH/2003-09-14-ExternalCall.ll3
-rw-r--r--test/Transforms/SCCP/2003-08-26-InvokeHandling.ll9
-rw-r--r--test/Transforms/SCCP/2004-11-16-DeadInvoke.ll9
-rw-r--r--test/Transforms/SCCP/2007-05-16-InvokeCrash.ll6
-rw-r--r--test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll2
-rw-r--r--test/Transforms/SCCP/atomic-load-store.ll30
-rw-r--r--test/Transforms/SCCP/ipsccp-basic.ll23
-rw-r--r--test/Transforms/SCCP/switch.ll13
-rw-r--r--test/Transforms/SCCP/undef-resolve.ll66
-rw-r--r--test/Transforms/ScalarRepl/2003-10-29-ArrayProblem.ll2
-rw-r--r--test/Transforms/ScalarRepl/2011-09-22-PHISpeculateInvoke.ll40
-rw-r--r--test/Transforms/ScalarRepl/2011-10-11-VectorMemset.ll22
-rw-r--r--test/Transforms/ScalarRepl/lifetime.ll139
-rw-r--r--test/Transforms/ScalarRepl/vector_promote.ll170
-rw-r--r--test/Transforms/ScalarRepl/vectors-with-mismatched-elements.ll27
-rw-r--r--test/Transforms/ScalarRepl/volatile.ll4
-rw-r--r--test/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll3
-rw-r--r--test/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll3
-rw-r--r--test/Transforms/SimplifyCFG/2005-10-02-InvokeSimplify.ll3
-rw-r--r--test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll14
-rw-r--r--test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll4
-rw-r--r--test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll14
-rw-r--r--test/Transforms/SimplifyCFG/2010-03-30-InvokeCrash.ll6
-rw-r--r--test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll22
-rw-r--r--test/Transforms/SimplifyCFG/BrUnwind.ll2
-rw-r--r--test/Transforms/SimplifyCFG/invoke_unwind.ll20
-rw-r--r--test/Transforms/SimplifyCFG/phi-undef-loadstore.ll87
-rw-r--r--test/Transforms/SimplifyCFG/trapping-load-unreachable.ll51
-rw-r--r--test/Transforms/SimplifyLibCalls/StrCmp.ll73
-rw-r--r--test/Transforms/SimplifyLibCalls/StrNCmp.ll95
-rw-r--r--test/Transforms/SimplifyLibCalls/memcmp.ll22
-rw-r--r--test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll12
-rw-r--r--test/Transforms/Sink/basic.ll16
-rw-r--r--test/Transforms/StripSymbols/block-address.ll23
-rw-r--r--test/Transforms/TailCallElim/dont_reorder_load.ll2
-rw-r--r--test/Transforms/TailCallElim/reorder_load.ll4
-rw-r--r--test/Transforms/TailCallElim/setjmp.ll19
-rw-r--r--test/Transforms/TailDup/2003-06-24-Simpleloop.ll15
-rw-r--r--test/Transforms/TailDup/2003-07-22-InfiniteLoop.ll11
-rw-r--r--test/Transforms/TailDup/2003-08-23-InvalidatedPointers.ll29
-rw-r--r--test/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll17
-rw-r--r--test/Transforms/TailDup/2004-04-01-DemoteRegToStack.ll20
-rw-r--r--test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll26
-rw-r--r--test/Transforms/TailDup/2009-07-31-phicrash.ll14
-rw-r--r--test/Transforms/TailDup/MergeTest.ll27
-rw-r--r--test/Transforms/TailDup/PHIUpdateTest.ll16
-rw-r--r--test/Transforms/TailDup/X86/if-tail-dup.ll49
-rw-r--r--test/Transforms/TailDup/basictest.ll20
-rw-r--r--test/Transforms/TailDup/basictest2.ll15
212 files changed, 5802 insertions, 1869 deletions
diff --git a/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll b/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll
index 444ca8ec904b9..6bbcfdb67ec58 100644
--- a/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll
+++ b/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll
@@ -8,7 +8,9 @@ then: ; preds = %0
to label %invoke_cont unwind label %invoke_catch
invoke_catch: ; preds = %then
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %exn
invoke_cont: ; preds = %then
ret void
@@ -17,3 +19,4 @@ endif: ; preds = %0
ret void
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll b/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll
index a6a41fd69effe..7ee0f468af0b9 100644
--- a/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll
+++ b/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll
@@ -11,6 +11,6 @@ invoke_catch.0: ; No predecessors!
br i1 false, label %UnifiedUnwindBlock, label %UnifiedReturnBlock
UnifiedUnwindBlock: ; preds = %invoke_catch.0
- unwind
+ unreachable
}
diff --git a/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll b/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll
index 991e876a25b77..4ddc2f180a2d3 100644
--- a/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll
+++ b/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll
@@ -15,17 +15,21 @@ tmp.3.i.noexc: ; preds = %entry
br i1 false, label %then.0, label %else.0
invoke_catch.0: ; preds = %entry
+ %exn.0 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
invoke void @q_atomic_decrement( )
to label %tmp.1.i.i183.noexc unwind label %terminate
tmp.1.i.i183.noexc: ; preds = %invoke_catch.0
- unwind
+ ret void
then.0: ; preds = %tmp.3.i.noexc
invoke void @_ZN10QByteArray6resizeEi( )
to label %invoke_cont.1 unwind label %invoke_catch.1
invoke_catch.1: ; preds = %then.0
+ %exn.1 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
invoke void @q_atomic_decrement( )
to label %tmp.1.i.i162.noexc unwind label %terminate
@@ -40,6 +44,9 @@ else.0: ; preds = %tmp.3.i.noexc
terminate: ; preds = %invoke_catch.1, %invoke_catch.0
%dbg.0.1 = phi { }* [ null, %invoke_catch.1 ], [ null, %invoke_catch.0 ] ; <{ }*> [#uses=0]
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/ADCE/dce_pure_invoke.ll b/test/Transforms/ADCE/dce_pure_invoke.ll
index c16d45cc23939..8e7851804575b 100644
--- a/test/Transforms/ADCE/dce_pure_invoke.ll
+++ b/test/Transforms/ADCE/dce_pure_invoke.ll
@@ -11,5 +11,9 @@ Cont: ; preds = %0
ret i32 0
Other: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll b/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll
index 91e9799ad9cab..ff5de6b73e210 100644
--- a/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll
+++ b/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll
@@ -190,5 +190,9 @@ return: ; preds = %entry
ret void
LongJmpBlkPre: ; preds = %endif.52, %then.40
+ %exn = landingpad { i8*, i32 } personality i32 (...)* @__gcc_personality_v0
+ catch i8* null
ret void
}
+
+declare i32 @__gcc_personality_v0(...)
diff --git a/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll b/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll
index fc58577f67abf..92603d9e634ea 100644
--- a/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll
+++ b/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll
@@ -10,6 +10,9 @@ Cont: ; preds = %EB
ret i32 %V
Unw: ; preds = %EB
- unwind
+ %exn = landingpad { i8*, i32 } personality i32 (...)* @__gcc_personality_v0
+ catch i8* null
+ resume { i8*, i32 } %exn
}
+declare i32 @__gcc_personality_v0(...)
diff --git a/test/Transforms/ConstantMerge/merge-both.ll b/test/Transforms/ConstantMerge/merge-both.ll
index 0282f464aeee9..b71eb437dbc3f 100644
--- a/test/Transforms/ConstantMerge/merge-both.ll
+++ b/test/Transforms/ConstantMerge/merge-both.ll
@@ -1,5 +1,7 @@
; RUN: opt -constmerge %s -S -o - | FileCheck %s
; Test that in one run var3 is merged into var2 and var1 into var4.
+; Test that we merge @var5 and @var6 into one with the higher alignment, and
+; don't merge var7/var8 into var5/var6.
declare void @zed(%struct.foobar*, %struct.foobar*)
@@ -14,13 +16,24 @@ declare void @zed(%struct.foobar*, %struct.foobar*)
; CHECK-NOT: @
; CHECK: @var2 = constant %struct.foobar { i32 2 }
; CHECK-NEXT: @var4 = constant %struct.foobar { i32 2 }
-; CHECK-NOT: @
-; CHECK: declare void @zed(%struct.foobar*, %struct.foobar*)
+
+declare void @helper([16 x i8]*)
+@var5 = internal constant [16 x i8] c"foo1bar2foo3bar\00", align 16
+@var6 = private unnamed_addr constant [16 x i8] c"foo1bar2foo3bar\00", align 1
+@var7 = internal constant [16 x i8] c"foo1bar2foo3bar\00"
+@var8 = private unnamed_addr constant [16 x i8] c"foo1bar2foo3bar\00"
+
+; CHECK-NEXT: @var6 = private constant [16 x i8] c"foo1bar2foo3bar\00", align 16
+; CHECK-NEXT: @var8 = private constant [16 x i8] c"foo1bar2foo3bar\00"
define i32 @main() {
entry:
call void @zed(%struct.foobar* @var1, %struct.foobar* @var2)
call void @zed(%struct.foobar* @var3, %struct.foobar* @var4)
+ call void @helper([16 x i8]* @var5)
+ call void @helper([16 x i8]* @var6)
+ call void @helper([16 x i8]* @var7)
+ call void @helper([16 x i8]* @var8)
ret i32 0
}
diff --git a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll
index 161821f3f8f79..fc25daca1c2ed 100644
--- a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll
+++ b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll
@@ -11,6 +11,8 @@ T:
%y = extractvalue {i32,i32} %x, 1
ret i32 %y
T2:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
@@ -22,5 +24,9 @@ T:
%y = extractvalue {i32,i32} %x, 1
ret i32 %y
T2:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/DeadArgElim/deadexternal.ll b/test/Transforms/DeadArgElim/deadexternal.ll
index 84092613130b7..b2d63ec772095 100644
--- a/test/Transforms/DeadArgElim/deadexternal.ll
+++ b/test/Transforms/DeadArgElim/deadexternal.ll
@@ -31,7 +31,7 @@ define void @h() {
entry:
%i = alloca i32, align 4
volatile store i32 10, i32* %i, align 4
-; CHECK: %tmp = volatile load i32* %i, align 4
+; CHECK: %tmp = load volatile i32* %i, align 4
; CHECK-next: call void @f(i32 undef)
%tmp = volatile load i32* %i, align 4
call void @f(i32 %tmp)
diff --git a/test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll b/test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll
new file mode 100644
index 0000000000000..c5cc101a5f7b3
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll
@@ -0,0 +1,27 @@
+; RUN: opt -dse -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-darwin"
+
+%"class.std::auto_ptr" = type { i32* }
+
+; CHECK: @_Z3foov
+define void @_Z3foov(%"class.std::auto_ptr"* noalias nocapture sret %agg.result) uwtable ssp {
+_ZNSt8auto_ptrIiED1Ev.exit:
+ %temp.lvalue = alloca %"class.std::auto_ptr", align 8
+ call void @_Z3barv(%"class.std::auto_ptr"* sret %temp.lvalue)
+ %_M_ptr.i.i = getelementptr inbounds %"class.std::auto_ptr"* %temp.lvalue, i64 0, i32 0
+ %tmp.i.i = load i32** %_M_ptr.i.i, align 8, !tbaa !0
+; CHECK-NOT: store i32* null
+ store i32* null, i32** %_M_ptr.i.i, align 8, !tbaa !0
+ %_M_ptr.i.i4 = getelementptr inbounds %"class.std::auto_ptr"* %agg.result, i64 0, i32 0
+ store i32* %tmp.i.i, i32** %_M_ptr.i.i4, align 8, !tbaa !0
+; CHECK: ret void
+ ret void
+}
+
+declare void @_Z3barv(%"class.std::auto_ptr"* sret)
+
+!0 = metadata !{metadata !"any pointer", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
diff --git a/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll b/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll
new file mode 100644
index 0000000000000..22b87864c0632
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll
@@ -0,0 +1,85 @@
+; RUN: opt -dse -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-f128:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.pair.162 = type { %struct.BasicBlock*, i32, [4 x i8] }
+%struct.BasicBlock = type { %struct.Value, %struct.ilist_node.24, %struct.iplist.22, %struct.Function* }
+%struct.Value = type { i32 (...)**, i8, i8, i16, %struct.Type*, %struct.Use*, %struct.StringMapEntry* }
+%struct.Type = type { %struct.LLVMContext*, i8, [3 x i8], i32, {}* }
+%struct.LLVMContext = type { %struct.LLVMContextImpl* }
+%struct.LLVMContextImpl = type opaque
+%struct.Use = type { %struct.Value*, %struct.Use*, %struct.PointerIntPair }
+%struct.PointerIntPair = type { i64 }
+%struct.StringMapEntry = type opaque
+%struct.ilist_node.24 = type { %struct.ilist_half_node.23, %struct.BasicBlock* }
+%struct.ilist_half_node.23 = type { %struct.BasicBlock* }
+%struct.iplist.22 = type { %struct.ilist_traits.21, %struct.Instruction* }
+%struct.ilist_traits.21 = type { %struct.ilist_half_node.25 }
+%struct.ilist_half_node.25 = type { %struct.Instruction* }
+%struct.Instruction = type { [52 x i8], %struct.ilist_node.26, %struct.BasicBlock*, %struct.DebugLoc }
+%struct.ilist_node.26 = type { %struct.ilist_half_node.25, %struct.Instruction* }
+%struct.DebugLoc = type { i32, i32 }
+%struct.Function = type { %struct.GlobalValue, %struct.ilist_node.14, %struct.iplist.4, %struct.iplist, %struct.ValueSymbolTable*, %struct.AttrListPtr }
+%struct.GlobalValue = type <{ [52 x i8], [4 x i8], %struct.Module*, i8, i16, [5 x i8], %struct.basic_string }>
+%struct.Module = type { %struct.LLVMContext*, %struct.iplist.20, %struct.iplist.16, %struct.iplist.12, %struct.vector.2, %struct.ilist, %struct.basic_string, %struct.ValueSymbolTable*, %struct.OwningPtr, %struct.basic_string, %struct.basic_string, %struct.basic_string, i8* }
+%struct.iplist.20 = type { %struct.ilist_traits.19, %struct.GlobalVariable* }
+%struct.ilist_traits.19 = type { %struct.ilist_node.18 }
+%struct.ilist_node.18 = type { %struct.ilist_half_node.17, %struct.GlobalVariable* }
+%struct.ilist_half_node.17 = type { %struct.GlobalVariable* }
+%struct.GlobalVariable = type { %struct.GlobalValue, %struct.ilist_node.18, i8, [7 x i8] }
+%struct.iplist.16 = type { %struct.ilist_traits.15, %struct.Function* }
+%struct.ilist_traits.15 = type { %struct.ilist_node.14 }
+%struct.ilist_node.14 = type { %struct.ilist_half_node.13, %struct.Function* }
+%struct.ilist_half_node.13 = type { %struct.Function* }
+%struct.iplist.12 = type { %struct.ilist_traits.11, %struct.GlobalAlias* }
+%struct.ilist_traits.11 = type { %struct.ilist_node.10 }
+%struct.ilist_node.10 = type { %struct.ilist_half_node.9, %struct.GlobalAlias* }
+%struct.ilist_half_node.9 = type { %struct.GlobalAlias* }
+%struct.GlobalAlias = type { %struct.GlobalValue, %struct.ilist_node.10 }
+%struct.vector.2 = type { %struct._Vector_base.1 }
+%struct._Vector_base.1 = type { %struct._Vector_impl.0 }
+%struct._Vector_impl.0 = type { %struct.basic_string*, %struct.basic_string*, %struct.basic_string* }
+%struct.basic_string = type { %struct._Alloc_hider }
+%struct._Alloc_hider = type { i8* }
+%struct.ilist = type { %struct.iplist.8 }
+%struct.iplist.8 = type { %struct.ilist_traits.7, %struct.NamedMDNode* }
+%struct.ilist_traits.7 = type { %struct.ilist_node.6 }
+%struct.ilist_node.6 = type { %struct.ilist_half_node.5, %struct.NamedMDNode* }
+%struct.ilist_half_node.5 = type { %struct.NamedMDNode* }
+%struct.NamedMDNode = type { %struct.ilist_node.6, %struct.basic_string, %struct.Module*, i8* }
+%struct.ValueSymbolTable = type opaque
+%struct.OwningPtr = type { %struct.GVMaterializer* }
+%struct.GVMaterializer = type opaque
+%struct.iplist.4 = type { %struct.ilist_traits.3, %struct.BasicBlock* }
+%struct.ilist_traits.3 = type { %struct.ilist_half_node.23 }
+%struct.iplist = type { %struct.ilist_traits, %struct.Argument* }
+%struct.ilist_traits = type { %struct.ilist_half_node }
+%struct.ilist_half_node = type { %struct.Argument* }
+%struct.Argument = type { %struct.Value, %struct.ilist_node, %struct.Function* }
+%struct.ilist_node = type { %struct.ilist_half_node, %struct.Argument* }
+%struct.AttrListPtr = type { %struct.AttributeListImpl* }
+%struct.AttributeListImpl = type opaque
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
+
+; CHECK: _ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_
+; CHECK: store
+; CHECK: ret void
+define void @_ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_(%struct.pair.162* %__a, %struct.pair.162* %__b) nounwind uwtable inlinehint {
+entry:
+ %memtmp = alloca %struct.pair.162, align 8
+ %0 = getelementptr inbounds %struct.pair.162* %memtmp, i64 0, i32 0
+ %1 = getelementptr inbounds %struct.pair.162* %__a, i64 0, i32 0
+ %2 = load %struct.BasicBlock** %1, align 8
+ store %struct.BasicBlock* %2, %struct.BasicBlock** %0, align 8
+ %3 = getelementptr inbounds %struct.pair.162* %memtmp, i64 0, i32 1
+ %4 = getelementptr inbounds %struct.pair.162* %__a, i64 0, i32 1
+ %5 = load i32* %4, align 4
+ store i32 %5, i32* %3, align 8
+ %6 = bitcast %struct.pair.162* %__a to i8*
+ %7 = bitcast %struct.pair.162* %__b to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %6, i8* %7, i64 12, i32 1, i1 false)
+ %8 = bitcast %struct.pair.162* %memtmp to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %7, i8* %8, i64 12, i32 1, i1 false)
+ ret void
+}
diff --git a/test/Transforms/DeadStoreElimination/atomic.ll b/test/Transforms/DeadStoreElimination/atomic.ll
new file mode 100644
index 0000000000000..2e84298ad400a
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/atomic.ll
@@ -0,0 +1,107 @@
+; RUN: opt -basicaa -dse -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-macosx10.7.0"
+
+; Sanity tests for atomic stores.
+; Note that it turns out essentially every transformation DSE does is legal on
+; atomic ops, just some transformations are not allowed across them.
+
+@x = common global i32 0, align 4
+@y = common global i32 0, align 4
+
+declare void @randomop(i32*)
+
+; DSE across unordered store (allowed)
+define void @test1() nounwind uwtable ssp {
+; CHECK: test1
+; CHECK-NOT: store i32 0
+; CHECK: store i32 1
+entry:
+ store i32 0, i32* @x
+ store atomic i32 0, i32* @y unordered, align 4
+ store i32 1, i32* @x
+ ret void
+}
+
+; DSE across seq_cst load (allowed in theory; not implemented ATM)
+define i32 @test2() nounwind uwtable ssp {
+; CHECK: test2
+; CHECK: store i32 0
+; CHECK: store i32 1
+entry:
+ store i32 0, i32* @x
+ %x = load atomic i32* @y seq_cst, align 4
+ store i32 1, i32* @x
+ ret i32 %x
+}
+
+; DSE across seq_cst store (store before atomic store must not be removed)
+define void @test3() nounwind uwtable ssp {
+; CHECK: test3
+; CHECK: store i32
+; CHECK: store atomic i32 2
+entry:
+ store i32 0, i32* @x
+ store atomic i32 2, i32* @y seq_cst, align 4
+ store i32 1, i32* @x
+ ret void
+}
+
+; DSE remove unordered store (allowed)
+define void @test4() nounwind uwtable ssp {
+; CHECK: test4
+; CHECK-NOT: store atomic
+; CHECK: store i32 1
+entry:
+ store atomic i32 0, i32* @x unordered, align 4
+ store i32 1, i32* @x
+ ret void
+}
+
+; DSE unordered store overwriting non-atomic store (allowed)
+define void @test5() nounwind uwtable ssp {
+; CHECK: test5
+; CHECK: store atomic i32 1
+entry:
+ store i32 0, i32* @x
+ store atomic i32 1, i32* @x unordered, align 4
+ ret void
+}
+
+; DSE no-op unordered atomic store (allowed)
+define void @test6() nounwind uwtable ssp {
+; CHECK: test6
+; CHECK-NOT: store
+; CHECK: ret void
+entry:
+ %x = load atomic i32* @x unordered, align 4
+ store atomic i32 %x, i32* @x unordered, align 4
+ ret void
+}
+
+; DSE seq_cst store (be conservative; DSE doesn't have infrastructure
+; to reason about atomic operations).
+define void @test7() nounwind uwtable ssp {
+; CHECK: test7
+; CHECK: store atomic
+entry:
+ %a = alloca i32
+ store atomic i32 0, i32* %a seq_cst, align 4
+ ret void
+}
+
+; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure
+; to reason about atomic operations).
+define i32 @test8() nounwind uwtable ssp {
+; CHECK: test8
+; CHECK: store
+; CHECK: load atomic
+entry:
+ %a = alloca i32
+ call void @randomop(i32* %a)
+ store i32 0, i32* %a, align 4
+ %x = load atomic i32* @x seq_cst, align 4
+ ret i32 %x
+}
+
diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll
index 5f143fcd1ede3..ec2f15737a379 100644
--- a/test/Transforms/DeadStoreElimination/simple.ll
+++ b/test/Transforms/DeadStoreElimination/simple.ll
@@ -42,20 +42,20 @@ define i32 @test3(i32* %g_addr) nounwind {
define void @test4(i32* %Q) {
%a = load i32* %Q
- volatile store i32 %a, i32* %Q
+ store volatile i32 %a, i32* %Q
ret void
; CHECK: @test4
; CHECK-NEXT: load i32
-; CHECK-NEXT: volatile store
+; CHECK-NEXT: store volatile
; CHECK-NEXT: ret void
}
define void @test5(i32* %Q) {
- %a = volatile load i32* %Q
+ %a = load volatile i32* %Q
store i32 %a, i32* %Q
ret void
; CHECK: @test5
-; CHECK-NEXT: volatile load
+; CHECK-NEXT: load volatile
; CHECK-NEXT: ret void
}
diff --git a/test/Transforms/EarlyCSE/basic.ll b/test/Transforms/EarlyCSE/basic.ll
index e3c75f97dcfcf..57b1697ff4deb 100644
--- a/test/Transforms/EarlyCSE/basic.ll
+++ b/test/Transforms/EarlyCSE/basic.ll
@@ -13,21 +13,21 @@ define void @test1(i8 %V, i32 *%P) {
volatile store i32 %C, i32* %P
volatile store i32 %D, i32* %P
; CHECK-NEXT: %C = zext i8 %V to i32
- ; CHECK-NEXT: volatile store i32 %C
- ; CHECK-NEXT: volatile store i32 %C
+ ; CHECK-NEXT: store volatile i32 %C
+ ; CHECK-NEXT: store volatile i32 %C
%E = add i32 %C, %C
%F = add i32 %C, %C
volatile store i32 %E, i32* %P
volatile store i32 %F, i32* %P
; CHECK-NEXT: %E = add i32 %C, %C
- ; CHECK-NEXT: volatile store i32 %E
- ; CHECK-NEXT: volatile store i32 %E
+ ; CHECK-NEXT: store volatile i32 %E
+ ; CHECK-NEXT: store volatile i32 %E
%G = add nuw i32 %C, %C ;; not a CSE with E
volatile store i32 %G, i32* %P
; CHECK-NEXT: %G = add nuw i32 %C, %C
- ; CHECK-NEXT: volatile store i32 %G
+ ; CHECK-NEXT: store volatile i32 %G
ret void
}
diff --git a/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll b/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
index 53857f61ce582..e2bab19e7efdd 100644
--- a/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
+++ b/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
@@ -46,9 +46,13 @@ define i1 @c6(i8* %q, i8 %bit) {
ret0:
ret i1 0
ret1:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i1 1
}
+declare i32 @__gxx_personality_v0(...)
+
define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
diff --git a/test/Transforms/FunctionAttrs/atomic.ll b/test/Transforms/FunctionAttrs/atomic.ll
new file mode 100644
index 0000000000000..7c2bff7a05f71
--- /dev/null
+++ b/test/Transforms/FunctionAttrs/atomic.ll
@@ -0,0 +1,21 @@
+; RUN: opt -basicaa -functionattrs -S < %s | FileCheck %s
+
+; Atomic load/store to local doesn't affect whether a function is
+; readnone/readonly.
+define i32 @test1(i32 %x) uwtable ssp {
+; CHECK: define i32 @test1(i32 %x) uwtable readnone ssp {
+entry:
+ %x.addr = alloca i32, align 4
+ store atomic i32 %x, i32* %x.addr seq_cst, align 4
+ %r = load atomic i32* %x.addr seq_cst, align 4
+ ret i32 %r
+}
+
+; A function with an Acquire load is not readonly.
+define i32 @test2(i32* %x) uwtable ssp {
+; CHECK: define i32 @test2(i32* nocapture %x) uwtable ssp {
+entry:
+ %r = load atomic i32* %x seq_cst, align 4
+ ret i32 %r
+}
+
diff --git a/test/Transforms/GVN/2010-05-08-OneBit.ll b/test/Transforms/GVN/2010-05-08-OneBit.ll
index 1809cf03f900f..480ce8ba0ae13 100644
--- a/test/Transforms/GVN/2010-05-08-OneBit.ll
+++ b/test/Transforms/GVN/2010-05-08-OneBit.ll
@@ -45,6 +45,8 @@ k151.i.i: ; preds = %k133.i.i
ret i32 0
landing_pad: ; preds = %l147.i.i, %l129.i.i, %l117.i.i
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
switch i32 undef, label %fin [
i32 1, label %catch1
i32 2, label %catch
@@ -61,3 +63,5 @@ catch1: ; preds = %landing_pad
}
declare fastcc void @foo()
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/GVN/2011-09-07-TypeIdFor.ll b/test/Transforms/GVN/2011-09-07-TypeIdFor.ll
new file mode 100644
index 0000000000000..314b5bb113a68
--- /dev/null
+++ b/test/Transforms/GVN/2011-09-07-TypeIdFor.ll
@@ -0,0 +1,81 @@
+; RUN: opt < %s -basicaa -gvn -S | FileCheck %s
+%struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
+%struct.__type_info_pseudo = type { i8*, i8* }
+
+@_ZTIi = external constant %struct.__fundamental_type_info_pseudo
+@_ZTIb = external constant %struct.__fundamental_type_info_pseudo
+
+declare void @_Z4barv()
+
+declare void @_Z7cleanupv()
+
+declare i32 @llvm.eh.typeid.for(i8*) nounwind readonly
+
+declare i8* @__cxa_begin_catch(i8*) nounwind
+
+declare void @__cxa_end_catch()
+
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+
+define void @_Z3foov() uwtable {
+entry:
+ invoke void @_Z4barv()
+ to label %return unwind label %lpad
+
+lpad: ; preds = %entry
+ %0 = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ catch %struct.__fundamental_type_info_pseudo* @_ZTIi
+ catch %struct.__fundamental_type_info_pseudo* @_ZTIb
+ catch %struct.__fundamental_type_info_pseudo* @_ZTIi
+ catch %struct.__fundamental_type_info_pseudo* @_ZTIb
+ %exc_ptr2.i = extractvalue { i8*, i32 } %0, 0
+ %filter3.i = extractvalue { i8*, i32 } %0, 1
+ %typeid.i = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*))
+; CHECK: call i32 @llvm.eh.typeid.for
+ %1 = icmp eq i32 %filter3.i, %typeid.i
+ br i1 %1, label %ppad, label %next
+
+next: ; preds = %lpad
+ %typeid1.i = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIb to i8*))
+; CHECK: call i32 @llvm.eh.typeid.for
+ %2 = icmp eq i32 %filter3.i, %typeid1.i
+ br i1 %2, label %ppad2, label %next2
+
+ppad: ; preds = %lpad
+ %3 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind
+ tail call void @__cxa_end_catch() nounwind
+ br label %return
+
+ppad2: ; preds = %next
+ %D.2073_5.i = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind
+ tail call void @__cxa_end_catch() nounwind
+ br label %return
+
+next2: ; preds = %next
+ call void @_Z7cleanupv()
+ %typeid = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*))
+; CHECK-NOT: call i32 @llvm.eh.typeid.for
+ %4 = icmp eq i32 %filter3.i, %typeid
+ br i1 %4, label %ppad3, label %next3
+
+next3: ; preds = %next2
+ %typeid1 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIb to i8*))
+ %5 = icmp eq i32 %filter3.i, %typeid1
+ br i1 %5, label %ppad4, label %unwind
+
+unwind: ; preds = %next3
+ resume { i8*, i32 } %0
+
+ppad3: ; preds = %next2
+ %6 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind
+ tail call void @__cxa_end_catch() nounwind
+ br label %return
+
+ppad4: ; preds = %next3
+ %D.2080_5 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind
+ tail call void @__cxa_end_catch() nounwind
+ br label %return
+
+return: ; preds = %ppad4, %ppad3, %ppad2, %ppad, %entry
+ ret void
+}
diff --git a/test/Transforms/GVN/atomic.ll b/test/Transforms/GVN/atomic.ll
new file mode 100644
index 0000000000000..094e22bd07e19
--- /dev/null
+++ b/test/Transforms/GVN/atomic.ll
@@ -0,0 +1,80 @@
+; RUN: opt -basicaa -gvn -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-macosx10.7.0"
+
+@x = common global i32 0, align 4
+@y = common global i32 0, align 4
+
+; GVN across unordered store (allowed)
+define i32 @test1() nounwind uwtable ssp {
+; CHECK: test1
+; CHECK: add i32 %x, %x
+entry:
+ %x = load i32* @y
+ store atomic i32 %x, i32* @x unordered, align 4
+ %y = load i32* @y
+ %z = add i32 %x, %y
+ ret i32 %z
+}
+
+; GVN across seq_cst store (allowed in theory; not implemented ATM)
+define i32 @test2() nounwind uwtable ssp {
+; CHECK: test2
+; CHECK: add i32 %x, %y
+entry:
+ %x = load i32* @y
+ store atomic i32 %x, i32* @x seq_cst, align 4
+ %y = load i32* @y
+ %z = add i32 %x, %y
+ ret i32 %z
+}
+
+; GVN across unordered load (allowed)
+define i32 @test3() nounwind uwtable ssp {
+; CHECK: test3
+; CHECK: add i32 %x, %x
+entry:
+ %x = load i32* @y
+ %y = load atomic i32* @x unordered, align 4
+ %z = load i32* @y
+ %a = add i32 %x, %z
+ %b = add i32 %y, %a
+ ret i32 %b
+}
+
+; GVN across acquire load (load after atomic load must not be removed)
+define i32 @test4() nounwind uwtable ssp {
+; CHECK: test4
+; CHECK: load atomic i32* @x
+; CHECK: load i32* @y
+entry:
+ %x = load i32* @y
+ %y = load atomic i32* @x seq_cst, align 4
+ %x2 = load i32* @y
+ %x3 = add i32 %x, %x2
+ %y2 = add i32 %y, %x3
+ ret i32 %y2
+}
+
+; GVN load to unordered load (allowed)
+define i32 @test5() nounwind uwtable ssp {
+; CHECK: test5
+; CHECK: add i32 %x, %x
+entry:
+ %x = load atomic i32* @x unordered, align 4
+ %y = load i32* @x
+ %z = add i32 %x, %y
+ ret i32 %z
+}
+
+; GVN unordered load to load (unordered load must not be removed)
+define i32 @test6() nounwind uwtable ssp {
+; CHECK: test6
+; CHECK: load atomic i32* @x unordered
+entry:
+ %x = load i32* @x
+ %x2 = load atomic i32* @x unordered, align 4
+ %x3 = add i32 %x, %x2
+ ret i32 %x3
+}
diff --git a/test/Transforms/GVN/condprop.ll b/test/Transforms/GVN/condprop.ll
index be6c3498fe409..0b31b01b7b143 100644
--- a/test/Transforms/GVN/condprop.ll
+++ b/test/Transforms/GVN/condprop.ll
@@ -2,8 +2,8 @@
@a = external global i32 ; <i32*> [#uses=7]
-; CHECK: @foo
-define i32 @foo() nounwind {
+; CHECK: @test1
+define i32 @test1() nounwind {
entry:
%0 = load i32* @a, align 4
%1 = icmp eq i32 %0, 4
@@ -52,4 +52,81 @@ bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb
return: ; preds = %bb8
ret i32 %.0
-} \ No newline at end of file
+}
+
+declare void @foo(i1)
+
+; CHECK: @test2
+define void @test2(i1 %x, i1 %y) {
+ %z = or i1 %x, %y
+ br i1 %z, label %true, label %false
+true:
+; CHECK: true:
+ %z2 = or i1 %x, %y
+ call void @foo(i1 %z2)
+; CHECK: call void @foo(i1 true)
+ br label %true
+false:
+; CHECK: false:
+ %z3 = or i1 %x, %y
+ call void @foo(i1 %z3)
+; CHECK: call void @foo(i1 false)
+ br label %false
+}
+
+declare void @bar(i32)
+
+; CHECK: @test3
+define void @test3(i32 %x, i32 %y) {
+ %xz = icmp eq i32 %x, 0
+ %yz = icmp eq i32 %y, 0
+ %z = and i1 %xz, %yz
+ br i1 %z, label %both_zero, label %nope
+both_zero:
+ call void @foo(i1 %xz)
+; CHECK: call void @foo(i1 true)
+ call void @foo(i1 %yz)
+; CHECK: call void @foo(i1 true)
+ call void @bar(i32 %x)
+; CHECK: call void @bar(i32 0)
+ call void @bar(i32 %y)
+; CHECK: call void @bar(i32 0)
+ ret void
+nope:
+ call void @foo(i1 %z)
+; CHECK: call void @foo(i1 false)
+ ret void
+}
+
+; CHECK: @test4
+define void @test4(i1 %b, i32 %x) {
+ br i1 %b, label %sw, label %case3
+sw:
+ switch i32 %x, label %default [
+ i32 0, label %case0
+ i32 1, label %case1
+ i32 2, label %case0
+ i32 3, label %case3
+ i32 4, label %default
+ ]
+default:
+; CHECK: default:
+ call void @bar(i32 %x)
+; CHECK: call void @bar(i32 %x)
+ ret void
+case0:
+; CHECK: case0:
+ call void @bar(i32 %x)
+; CHECK: call void @bar(i32 %x)
+ ret void
+case1:
+; CHECK: case1:
+ call void @bar(i32 %x)
+; CHECK: call void @bar(i32 1)
+ ret void
+case3:
+; CHECK: case3:
+ call void @bar(i32 %x)
+; CHECK: call void @bar(i32 %x)
+ ret void
+}
diff --git a/test/Transforms/GVN/phi-translate.ll b/test/Transforms/GVN/phi-translate.ll
index f10537e0c9300..fa91d2919eb20 100644
--- a/test/Transforms/GVN/phi-translate.ll
+++ b/test/Transforms/GVN/phi-translate.ll
@@ -14,7 +14,7 @@ target datalayout = "e-p:64:64:64"
@G = external global [100 x i32]
define i32 @foo(i32 %x, i32 %z) {
entry:
- %tobool = icmp eq i32 %x, 0
+ %tobool = icmp eq i32 %z, 0
br i1 %tobool, label %end, label %then
then:
diff --git a/test/Transforms/GVN/pr10820.ll b/test/Transforms/GVN/pr10820.ll
new file mode 100644
index 0000000000000..12c1e70fc3877
--- /dev/null
+++ b/test/Transforms/GVN/pr10820.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -basicaa -gvn -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-f128:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@g = external global i31
+
+define void @main() nounwind uwtable {
+entry:
+; CHECK: store i32
+ store i32 402662078, i32* bitcast (i31* @g to i32*), align 8
+; CHECK-NOT: load i31
+ %0 = load i31* @g, align 8
+; CHECK: store i31
+ store i31 %0, i31* undef, align 1
+ unreachable
+}
diff --git a/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll b/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
index 0c817005c2737..a6803abc5d360 100644
--- a/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
+++ b/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -globalopt -S | grep {volatile load}
+; RUN: opt < %s -globalopt -S | grep {load volatile}
@t0.1441 = internal global double 0x3FD5555555555555, align 8 ; <double*> [#uses=1]
define double @foo() nounwind {
diff --git a/test/Transforms/IPConstantProp/global.ll b/test/Transforms/IPConstantProp/global.ll
new file mode 100644
index 0000000000000..67152937beec7
--- /dev/null
+++ b/test/Transforms/IPConstantProp/global.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -S -ipsccp | FileCheck %s
+
+@_ZL6test1g = internal global i32 42, align 4
+
+define void @_Z7test1f1v() nounwind {
+entry:
+ %tmp = load i32* @_ZL6test1g, align 4
+ %cmp = icmp eq i32 %tmp, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ store i32 0, i32* @_ZL6test1g, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ ret void
+}
+
+; CHECK: @_Z7test1f2v()
+; CHECK: entry:
+; CHECK-NEXT: ret i32 42
+define i32 @_Z7test1f2v() nounwind {
+entry:
+ %tmp = load i32* @_ZL6test1g, align 4
+ ret i32 %tmp
+}
diff --git a/test/Transforms/IPConstantProp/return-argument.ll b/test/Transforms/IPConstantProp/return-argument.ll
index 6d6eb24cf5425..f4b7018222e94 100644
--- a/test/Transforms/IPConstantProp/return-argument.ll
+++ b/test/Transforms/IPConstantProp/return-argument.ll
@@ -36,14 +36,22 @@ define void @caller(i1 %C) {
;; propagated per-caller).
%S1 = call { i32, i32 } @foo(i32 1, i32 2)
%X1 = extractvalue { i32, i32 } %S1, 0
- %S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %RET
+ %S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %LPAD
+
OK:
%X2 = extractvalue { i32, i32 } %S2, 0
;; Do some stuff with the returned values which we can grep for
%Z = add i32 %X1, %X2
store i32 %Z, i32* %W
br label %RET
+
+LPAD:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ br label %RET
+
RET:
ret void
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/IPConstantProp/return-constant.ll b/test/Transforms/IPConstantProp/return-constant.ll
index b25585952873d..ff15df738816d 100644
--- a/test/Transforms/IPConstantProp/return-constant.ll
+++ b/test/Transforms/IPConstantProp/return-constant.ll
@@ -22,5 +22,9 @@ OK:
%Y = icmp ne i32 %X, 0 ; <i1> [#uses=1]
ret i1 %Y
FAIL:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i1 false
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll b/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
deleted file mode 100644
index ecd5086f73089..0000000000000
--- a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -indvars -S | grep indvar
-
-define i32 @test() {
-; <label>:0
- br i1 true, label %LoopHead, label %LoopHead
-
-LoopHead: ; preds = %LoopHead, %0, %0
- %A = phi i32 [ 7, %0 ], [ 7, %0 ], [ %B, %LoopHead ] ; <i32> [#uses=1]
- %B = add i32 %A, 1 ; <i32> [#uses=2]
- br i1 true, label %LoopHead, label %Out
-
-Out: ; preds = %LoopHead
- ret i32 %B
-}
-
diff --git a/test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll b/test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll
deleted file mode 100644
index 0fc9c8547d9d3..0000000000000
--- a/test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -indvars -S | grep indvar | not grep i32
-
-@G = global i64 0 ; <i64*> [#uses=1]
-
-define void @test() {
-; <label>:0
- br label %Loop
-
-Loop: ; preds = %Loop, %0
- %X = phi i64 [ 1, %0 ], [ %X.next, %Loop ] ; <i64> [#uses=2]
- %X.next = add i64 %X, 1 ; <i64> [#uses=1]
- store i64 %X, i64* @G
- br label %Loop
-}
-
diff --git a/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll b/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll
index 1ed4c44d2650c..708a961272b5a 100644
--- a/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll
+++ b/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll
@@ -110,12 +110,16 @@ declare void @_ZNK4llvm19MachineInstrBuilder7addMRegEiNS_14MachineOperand7UseTyp
declare void @_ZNK4llvm19MachineInstrBuilder7addSImmEi()
+declare i32 @__gxx_personality_v0(...)
+
define void @_ZN4llvm11_GLOBAL__N_22InsertPrologEpilogCode20runOnMachineFunctionERNS_15MachineFunctionE(%"struct.llvm::MachineFunction"* %F) {
entry:
%tmp.8.i = invoke %"struct.llvm::TargetFrameInfo"* null( %"struct.llvm::TargetMachine"* null )
to label %invoke_cont.0.i unwind label %invoke_catch.0.i ; <%"struct.llvm::TargetFrameInfo"*> [#uses=0]
invoke_catch.0.i: ; preds = %invoke_cont.49.i, %invoke_cont.48.i, %invoke_cont.47.i, %invoke_cont.i53.i, %no_exit.i, %invoke_cont.44.i, %invoke_cont.43.i, %invoke_cont.42.i, %invoke_cont.41.i, %invoke_cont.40.i, %invoke_cont.39.i, %invoke_cont.38.i, %invoke_cont.37.i, %then.2.i, %invoke_cont.35.i, %invoke_cont.34.i, %then.1.i, %endif.0.i, %invoke_cont.9.i, %invoke_cont.8.i, %invoke_cont.7.i, %invoke_cont.i.i, %then.0.i, %invoke_cont.4.i, %invoke_cont.3.i, %invoke_cont.2.i, %invoke_cont.1.i, %endif.0.i.i, %tmp.7.i.noexc.i, %invoke_cont.0.i, %entry
+ %exn0.i = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
invoke_cont.0.i: ; preds = %entry
@@ -164,6 +168,8 @@ tmp.0.i.noexc.i: ; preds = %then.0.i
to label %invoke_cont.i.i unwind label %cond_true.i.i
cond_true.i.i: ; preds = %tmp.0.i.noexc.i
+ %exn.i.i = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
invoke_cont.i.i: ; preds = %tmp.0.i.noexc.i
@@ -256,6 +262,8 @@ tmp.0.i.noexc55.i: ; preds = %no_exit.i
to label %invoke_cont.i53.i unwind label %cond_true.i52.i
cond_true.i52.i: ; preds = %tmp.0.i.noexc55.i
+ %exn.i52.i = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
invoke_cont.i53.i: ; preds = %tmp.0.i.noexc55.i
diff --git a/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll b/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll
index aee67ccacc5f4..a5706ca6198eb 100644
--- a/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll
+++ b/test/Transforms/IndVarSimplify/2005-02-11-InvokeCrash.ll
@@ -5,9 +5,6 @@ entry:
%tmp.7 = invoke i32 @_ZN5ArrayISt7complexIdEE8get_sizeERK10dim_vector( )
to label %invoke_cont.0 unwind label %cond_true.1 ; <i32> [#uses=2]
-cond_true.1: ; preds = %entry
- unwind
-
invoke_cont.0: ; preds = %entry
%tmp.4.i = bitcast i32 %tmp.7 to i32 ; <i32> [#uses=0]
%tmp.14.0.i5 = add i32 %tmp.7, -1 ; <i32> [#uses=1]
@@ -17,7 +14,14 @@ no_exit.i: ; preds = %no_exit.i, %invoke_cont.0
%tmp.14.0.i.0 = phi i32 [ %tmp.14.0.i, %no_exit.i ], [ %tmp.14.0.i5, %invoke_cont.0 ] ; <i32> [#uses=1]
%tmp.14.0.i = add i32 %tmp.14.0.i.0, -1 ; <i32> [#uses=1]
br label %no_exit.i
+
+cond_true.1: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %exn
}
+declare i32 @__gxx_personality_v0(...)
+
declare i32 @_ZN5ArrayISt7complexIdEE8get_sizeERK10dim_vector()
diff --git a/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll b/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll
index 70a7a9de05f08..ce043beb7fd95 100644
--- a/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll
+++ b/test/Transforms/IndVarSimplify/2005-02-17-TruncateExprCrash.ll
@@ -10,6 +10,8 @@ entry:
to label %endif.1 unwind label %then.i.i551
then.i.i551: ; preds = %entry
+ %exn551 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
endif.1: ; preds = %entry
@@ -20,6 +22,8 @@ then.2: ; preds = %endif.1
to label %loopentry.0 unwind label %invoke_catch.6
invoke_catch.6: ; preds = %then.2
+ %exn6 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
loopentry.0: ; preds = %then.2
@@ -59,3 +63,5 @@ loopexit.1: ; preds = %no_exit.0, %endif.4
then.i.i: ; preds = %endif.1
ret void
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll b/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll
index 0f6267bd17991..dd400beaa5fa7 100644
--- a/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll
+++ b/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll
@@ -1,6 +1,6 @@
; RUN: opt < %s -indvars -S | not grep {sext}
; ModuleID = '<stdin>'
-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-n:32:64"
+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-n32:64"
target triple = "x86_64-apple-darwin9.6"
@a = external global i32* ; <i32**> [#uses=3]
@b = external global i32* ; <i32**> [#uses=3]
diff --git a/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll b/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll
index 46d6b380f0000..55e8a5073cf19 100644
--- a/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll
+++ b/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll
@@ -13,7 +13,7 @@
; d[(i+2)&15] = e[(i+2)&15]+f[(i+2)&15]+K[i+2];
; }
;}
-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-n:32:64"
+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-n32:64"
target triple = "x86_64-apple-darwin9.6"
@a = external global i32* ; <i32**> [#uses=3]
@b = external global i32* ; <i32**> [#uses=3]
diff --git a/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll b/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
new file mode 100644
index 0000000000000..77354f75106ac
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
+; Test WidenIV::GetExtendedOperandRecurrence.
+; add219 should be extended to i64 because it is nsw, even though its
+; sext cannot be hoisted outside the loop.
+
+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"
+
+define void @test() nounwind {
+entry:
+ br i1 undef, label %for.body11, label %for.end285
+
+for.body11: ; preds = %entry
+ %shl = shl i32 1, 1
+ %shl132 = shl i32 %shl, 1
+ br label %for.body153
+
+for.body153: ; preds = %for.body153, %for.body11
+ br i1 undef, label %for.body170, label %for.body153
+
+; CHECK: add nsw i64 %indvars.iv, 1
+for.body170: ; preds = %for.body170, %for.body153
+ %i2.19 = phi i32 [ %add249, %for.body170 ], [ undef, %for.body153 ]
+ %add219 = add nsw i32 %i2.19, 1
+ %idxprom220 = sext i32 %add219 to i64
+ %add249 = add nsw i32 %i2.19, %shl132
+ br label %for.body170
+
+for.end285: ; preds = %entry
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/2011-09-19-vectoriv.ll b/test/Transforms/IndVarSimplify/2011-09-19-vectoriv.ll
new file mode 100644
index 0000000000000..6a01012fe22ff
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-09-19-vectoriv.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+; PR10946: Vector IVs are not SCEVable.
+; CHECK-NOT: phi
+define void @test() nounwind {
+allocas:
+ br i1 undef, label %cif_done, label %for_loop398
+
+cif_done: ; preds = %allocas
+ ret void
+
+for_loop398: ; preds = %for_loop398, %allocas
+ %storemerge35 = phi <4 x i32> [ %storemerge, %for_loop398 ], [ undef, %allocas ]
+ %bincmp431 = icmp sge <4 x i32> %storemerge35, <i32 5, i32 5, i32 5, i32 5>
+ %storemerge = bitcast <4 x float> undef to <4 x i32>
+ br label %for_loop398
+}
diff --git a/test/Transforms/IndVarSimplify/2011-09-27-hoistsext.ll b/test/Transforms/IndVarSimplify/2011-09-27-hoistsext.ll
new file mode 100644
index 0000000000000..0737489aad5b5
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-09-27-hoistsext.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+; Test indvars' ability to hoist new sext created by WidenIV.
+; From ffbench.
+
+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"
+define internal double @fourn(double* %data, i32 %x, i32 %y, i32 %n) nounwind {
+; CHECK: entry:
+; CHECK: sext
+; CHECK: sext
+entry:
+ br label %for.body
+
+; CHECK: for.body:
+; CHECK-NOT: sext
+; CHECK: br
+for.body:
+ %i2.115 = phi i32 [ 0, %entry ], [ %add249, %for.body ]
+ %add174 = add nsw i32 %i2.115, %x
+ %idxprom177 = sext i32 %add174 to i64
+ %arrayidx179 = getelementptr inbounds double* %data, i64 %idxprom177
+ %tmp180 = load double* %arrayidx179, align 8
+ %add249 = add nsw i32 %i2.115, %y
+ %cmp168 = icmp sgt i32 %add249, %n
+ br i1 %cmp168, label %exit, label %for.body
+
+exit:
+ ret double %tmp180
+}
diff --git a/test/Transforms/IndVarSimplify/ada-loops.ll b/test/Transforms/IndVarSimplify/ada-loops.ll
index 9e635fdc0067b..154de6fea4b6e 100644
--- a/test/Transforms/IndVarSimplify/ada-loops.ll
+++ b/test/Transforms/IndVarSimplify/ada-loops.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -indvars -S | FileCheck %s
-; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
;
; PR1301
@@ -9,13 +9,12 @@
; Note that all four functions should actually be converted to
; memset. However, this test case validates indvars behavior. We
; don't check that phis are "folded together" because that is a job
-; for loop strength reduction. But indvars must remove sext, zext,
-; trunc, and add i8.
+; for loop strength reduction. But indvars must remove sext, zext, and add i8.
;
-; CHECK-NOT: {{sext|zext|trunc|add i8}}
+; CHECK-NOT: {{sext|zext|add i8}}
; ModuleID = 'ada.bc'
-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-n:8:16:32"
+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-n8:16:32"
target triple = "i686-pc-linux-gnu"
define void @kinds__sbytezero([256 x i32]* nocapture %a) nounwind {
diff --git a/test/Transforms/IndVarSimplify/addrec-gep.ll b/test/Transforms/IndVarSimplify/addrec-gep.ll
index 58cba6057045d..b62d093960c32 100644
--- a/test/Transforms/IndVarSimplify/addrec-gep.ll
+++ b/test/Transforms/IndVarSimplify/addrec-gep.ll
@@ -1,15 +1,15 @@
-; RUN: opt < %s -indvars -S > %t
-; RUN: grep getelementptr %t | count 1
-; RUN: grep {mul .*, 37} %t | count 1
-; RUN: grep {add .*, 5203} %t | count 1
-; RUN: not grep cast %t
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; CHECK: getelementptr
+; CHECK: mul {{.*}}, 37
+; CHECK: add {{.*}}, 5203
+; CHECK-NOT: cast
; This test tests several things. The load and store should use the
; same address instead of having it computed twice, and SCEVExpander should
; be able to reconstruct the full getelementptr, despite it having a few
; obstacles set in its way.
-target datalayout = "e-p:64:64:64-n:32:64"
+target datalayout = "e-p:64:64:64-n32:64"
define void @foo(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind {
entry:
diff --git a/test/Transforms/IndVarSimplify/ashr-tripcount.ll b/test/Transforms/IndVarSimplify/ashr-tripcount.ll
index 09d559fe51149..b47c8ad471841 100644
--- a/test/Transforms/IndVarSimplify/ashr-tripcount.ll
+++ b/test/Transforms/IndVarSimplify/ashr-tripcount.ll
@@ -4,7 +4,7 @@
; Indvars should be able to eliminate all of the sign extensions
; inside the loop.
-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-n:32:64"
+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-n32:64"
@pow_2_tab = external constant [0 x float] ; <[0 x float]*> [#uses=1]
@pow_2_025_tab = external constant [0 x float] ; <[0 x float]*> [#uses=1]
@i_pow_2_tab = external constant [0 x float] ; <[0 x float]*> [#uses=1]
diff --git a/test/Transforms/IndVarSimplify/complex-scev.ll b/test/Transforms/IndVarSimplify/complex-scev.ll
index 434c4ec995251..395377e3a48eb 100644
--- a/test/Transforms/IndVarSimplify/complex-scev.ll
+++ b/test/Transforms/IndVarSimplify/complex-scev.ll
@@ -1,7 +1,9 @@
; The i induction variable looks like a wrap-around, but it really is just
; a simple affine IV. Make sure that indvars eliminates it.
-; RUN: opt < %s -indvars -S | grep phi | count 1
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; CHECK: phi
+; CHECK-NOT: phi
define void @foo() {
entry:
diff --git a/test/Transforms/IndVarSimplify/crash.ll b/test/Transforms/IndVarSimplify/crash.ll
index 516fd8084d9e9..3335be781dfc6 100644
--- a/test/Transforms/IndVarSimplify/crash.ll
+++ b/test/Transforms/IndVarSimplify/crash.ll
@@ -53,3 +53,37 @@ bb30: ; preds = %bb29
%2 = add nsw i32 %r.0, 1 ; <i32> [#uses=1]
br label %bb24
}
+
+; PR10770
+
+declare void @__go_panic() noreturn
+
+declare void @__go_undefer()
+
+declare i32 @__gccgo_personality_v0(i32, i64, i8*, i8*)
+
+define void @main.main() uwtable {
+entry:
+ invoke void @__go_panic() noreturn
+ to label %0 unwind label %"5.i"
+
+; <label>:0 ; preds = %entry
+ unreachable
+
+"3.i": ; preds = %"7.i", %"5.i"
+ invoke void @__go_undefer()
+ to label %main.f.exit unwind label %"7.i"
+
+"5.i": ; preds = %entry
+ %1 = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gccgo_personality_v0
+ catch i8* null
+ br label %"3.i"
+
+"7.i": ; preds = %"3.i"
+ %2 = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gccgo_personality_v0
+ catch i8* null
+ br label %"3.i"
+
+main.f.exit: ; preds = %"3.i"
+ unreachable
+}
diff --git a/test/Transforms/IndVarSimplify/elim-extend.ll b/test/Transforms/IndVarSimplify/elim-extend.ll
index 0367e117e677d..43c162fed7f1c 100644
--- a/test/Transforms/IndVarSimplify/elim-extend.ll
+++ b/test/Transforms/IndVarSimplify/elim-extend.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -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"
diff --git a/test/Transforms/IndVarSimplify/floating-point-iv.ll b/test/Transforms/IndVarSimplify/floating-point-iv.ll
index 8f4b87048a4d3..266eebd5bb656 100644
--- a/test/Transforms/IndVarSimplify/floating-point-iv.ll
+++ b/test/Transforms/IndVarSimplify/floating-point-iv.ll
@@ -67,7 +67,8 @@ bb: ; preds = %bb, %entry
return:
ret void
; CHECK: @test4
-; CHECK: fcmp
+; CHECK-NOT: cmp
+; CHECK: br i1 false
}
; PR6761
@@ -84,9 +85,8 @@ define void @test5() nounwind {
exit:
ret void
-
+
; CHECK: @test5
-; CHECK: icmp eq i32 {{.*}}, 10
+; CHECK: icmp slt i32 {{.*}}, 0
; CHECK-NEXT: br i1
}
-
diff --git a/test/Transforms/IndVarSimplify/gep-with-mul-base.ll b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
index 19d54ff2a22fd..7e1e2a31768c6 100644
--- a/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
+++ b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
@@ -1,7 +1,16 @@
-; RUN: opt < %s -indvars -S > %t
-; RUN: grep add %t | count 6
-; RUN: grep sub %t | count 2
-; RUN: grep mul %t | count 6
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; CHECK: define void @foo
+; CHECK: mul
+; CHECK: mul
+; CHECK: mul
+; CHECK: add
+; CHECK: sub
+; CHECK: define void @bar
+; CHECK: mul
+; CHECK: mul
+; CHECK: mul
+; CHECK: add
+; CHECK: sub
define void @foo(i64 %n, i64 %m, i64 %o, double* nocapture %p) nounwind {
entry:
diff --git a/test/Transforms/IndVarSimplify/interesting-invoke-use.ll b/test/Transforms/IndVarSimplify/interesting-invoke-use.ll
index 8adc0e5257777..69bea6eaaed4d 100644
--- a/test/Transforms/IndVarSimplify/interesting-invoke-use.ll
+++ b/test/Transforms/IndVarSimplify/interesting-invoke-use.ll
@@ -47,9 +47,13 @@ bb178: ; preds = %invcont127
br label %bb123
lpad266: ; preds = %invcont129, %bb128, %bb123
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
+declare i32 @__gxx_personality_v0(...)
+
declare void @system__img_int__image_integer(%struct.string___XUP* noalias sret, i32)
declare void @system__string_ops__str_concat(%struct.string___XUP* noalias sret, [0 x i8]*, %struct.string___XUB*, [0 x i8]*, %struct.string___XUB*)
diff --git a/test/Transforms/IndVarSimplify/iv-fold.ll b/test/Transforms/IndVarSimplify/iv-fold.ll
new file mode 100644
index 0000000000000..2e191184225c0
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/iv-fold.ll
@@ -0,0 +1,56 @@
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -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-n32:64"
+
+; Indvars should be able to fold IV increments into shr when low bits are zero.
+;
+; CHECK: @foldIncShr
+; CHECK: shr.1 = lshr i32 %0, 5
+define i32 @foldIncShr(i32* %bitmap, i32 %bit_addr, i32 %nbits) nounwind {
+entry:
+ br label %while.body
+
+while.body:
+ %0 = phi i32 [ 0, %entry ], [ %inc.2, %while.body ]
+ %shr = lshr i32 %0, 5
+ %arrayidx = getelementptr inbounds i32* %bitmap, i32 %shr
+ %tmp6 = load i32* %arrayidx, align 4
+ %inc.1 = add i32 %0, 1
+ %shr.1 = lshr i32 %inc.1, 5
+ %arrayidx.1 = getelementptr inbounds i32* %bitmap, i32 %shr.1
+ %tmp6.1 = load i32* %arrayidx.1, align 4
+ %inc.2 = add i32 %inc.1, 1
+ %exitcond.3 = icmp eq i32 %inc.2, 128
+ br i1 %exitcond.3, label %while.end, label %while.body
+
+while.end:
+ %r = add i32 %tmp6, %tmp6.1
+ ret i32 %r
+}
+
+; Invdars should not fold an increment into shr unless 2^shiftBits is
+; a multiple of the recurrence step.
+;
+; CHECK: @noFoldIncShr
+; CHECK: shr.1 = lshr i32 %inc.1, 5
+define i32 @noFoldIncShr(i32* %bitmap, i32 %bit_addr, i32 %nbits) nounwind {
+entry:
+ br label %while.body
+
+while.body:
+ %0 = phi i32 [ 0, %entry ], [ %inc.3, %while.body ]
+ %shr = lshr i32 %0, 5
+ %arrayidx = getelementptr inbounds i32* %bitmap, i32 %shr
+ %tmp6 = load i32* %arrayidx, align 4
+ %inc.1 = add i32 %0, 1
+ %shr.1 = lshr i32 %inc.1, 5
+ %arrayidx.1 = getelementptr inbounds i32* %bitmap, i32 %shr.1
+ %tmp6.1 = load i32* %arrayidx.1, align 4
+ %inc.3 = add i32 %inc.1, 2
+ %exitcond.3 = icmp eq i32 %inc.3, 96
+ br i1 %exitcond.3, label %while.end, label %while.body
+
+while.end:
+ %r = add i32 %tmp6, %tmp6.1
+ ret i32 %r
+}
diff --git a/test/Transforms/IndVarSimplify/iv-sext.ll b/test/Transforms/IndVarSimplify/iv-sext.ll
index 6c7a6279ab3f8..04df0f9aa5fa0 100644
--- a/test/Transforms/IndVarSimplify/iv-sext.ll
+++ b/test/Transforms/IndVarSimplify/iv-sext.ll
@@ -4,7 +4,7 @@
; inner loop to i64.
; TODO: it should promote hiPart to i64 in the outer loop too.
-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-n:32:64"
+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-n32:64"
define void @t(float* %pTmp1, float* %peakWeight, float* %nrgReducePeakrate, i32 %bandEdgeIndex, float %tmp1) nounwind {
entry:
diff --git a/test/Transforms/IndVarSimplify/iv-zext.ll b/test/Transforms/IndVarSimplify/iv-zext.ll
index 3a05c893fb49e..646e6c00ce6f3 100644
--- a/test/Transforms/IndVarSimplify/iv-zext.ll
+++ b/test/Transforms/IndVarSimplify/iv-zext.ll
@@ -1,9 +1,9 @@
; RUN: opt < %s -indvars -S | FileCheck %s
-; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
; CHECK-NOT: and
; CHECK-NOT: zext
-target datalayout = "-p:64:64:64-n:32:64"
+target datalayout = "-p:64:64:64-n32:64"
define void @foo(double* %d, i64 %n) nounwind {
entry:
diff --git a/test/Transforms/IndVarSimplify/lftr-reuse.ll b/test/Transforms/IndVarSimplify/lftr-reuse.ll
new file mode 100644
index 0000000000000..490eee9c221d2
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/lftr-reuse.ll
@@ -0,0 +1,230 @@
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
+;
+; Make sure that indvars can perform LFTR without a canonical IV.
+
+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"
+
+; Perform LFTR using the original pointer-type IV.
+
+; for(char* p = base; p < base + n; ++p) {
+; *p = p-base;
+; }
+define void @ptriv(i8* %base, i32 %n) nounwind {
+entry:
+ %idx.ext = sext i32 %n to i64
+ %add.ptr = getelementptr inbounds i8* %base, i64 %idx.ext
+ %cmp1 = icmp ult i8* %base, %add.ptr
+ br i1 %cmp1, label %for.body, label %for.end
+
+; CHECK: for.body:
+; CHECK: phi i8*
+; CHECK-NOT: phi
+; CHECK-NOT: add
+; CHECK: icmp ne i8*
+; CHECK: br i1
+for.body:
+ %p.02 = phi i8* [ %base, %entry ], [ %incdec.ptr, %for.body ]
+ ; cruft to make the IV useful
+ %sub.ptr.lhs.cast = ptrtoint i8* %p.02 to i64
+ %sub.ptr.rhs.cast = ptrtoint i8* %base to i64
+ %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
+ %conv = trunc i64 %sub.ptr.sub to i8
+ store i8 %conv, i8* %p.02
+ %incdec.ptr = getelementptr inbounds i8* %p.02, i32 1
+ %cmp = icmp ult i8* %incdec.ptr, %add.ptr
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ ret void
+}
+
+; It would be nice if SCEV and any loop analysis could assume that
+; preheaders exist. Unfortunately it is not always the case. This test
+; checks that SCEVExpander can handle an outer loop that has not yet
+; been simplified. As a result, the inner loop's exit test will not be
+; rewritten.
+define void @expandOuterRecurrence(i32 %arg) nounwind {
+entry:
+ %sub1 = sub nsw i32 %arg, 1
+ %cmp1 = icmp slt i32 0, %sub1
+ br i1 %cmp1, label %outer, label %exit
+
+outer:
+ %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ]
+ %sub2 = sub nsw i32 %arg, %i
+ %sub3 = sub nsw i32 %sub2, 1
+ %cmp2 = icmp slt i32 0, %sub3
+ br i1 %cmp2, label %inner.ph, label %outer.inc
+
+inner.ph:
+ br label %inner
+
+; CHECK: inner:
+; CHECK: icmp slt
+; CHECK: br i1
+inner:
+ %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ]
+ %j.inc = add nsw i32 %j, 1
+ %cmp3 = icmp slt i32 %j.inc, %sub3
+ br i1 %cmp3, label %inner, label %outer.inc
+
+; CHECK: outer.inc:
+; CHECK: icmp ne
+; CHECK: br i1
+outer.inc:
+ %i.inc = add nsw i32 %i, 1
+ %cmp4 = icmp slt i32 %i.inc, %sub1
+ br i1 %cmp4, label %outer, label %exit
+
+exit:
+ ret void
+}
+
+; Force SCEVExpander to look for an existing well-formed phi.
+; Perform LFTR without generating extra preheader code.
+define void @guardedloop([0 x double]* %matrix, [0 x double]* %vector,
+ i32 %irow, i32 %ilead) nounwind {
+; CHECK: entry:
+; CHECK-NOT: zext
+; CHECK-NOT: add
+; CHECK: loop:
+; CHECK: phi i64
+; CHECK: phi i64
+; CHECK-NOT: phi
+; CHECK: icmp ne
+; CHECK: br i1
+entry:
+ %cmp = icmp slt i32 1, %irow
+ br i1 %cmp, label %loop, label %return
+
+loop:
+ %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
+ %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
+ %diagidx = add nsw i32 %rowidx, %i
+ %diagidxw = sext i32 %diagidx to i64
+ %matrixp = getelementptr inbounds [0 x double]* %matrix, i32 0, i64 %diagidxw
+ %v1 = load double* %matrixp
+ %iw = sext i32 %i to i64
+ %vectorp = getelementptr inbounds [0 x double]* %vector, i32 0, i64 %iw
+ %v2 = load double* %vectorp
+ %row.inc = add nsw i32 %rowidx, %ilead
+ %i.inc = add nsw i32 %i, 1
+ %cmp196 = icmp slt i32 %i.inc, %irow
+ br i1 %cmp196, label %loop, label %return
+
+return:
+ ret void
+}
+
+; Avoid generating extra code to materialize a trip count. Skip LFTR.
+define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector,
+ i32 %irow, i32 %ilead) nounwind {
+entry:
+ br label %loop
+
+; CHECK: entry:
+; CHECK-NOT: zext
+; CHECK-NOT: add
+; CHECK: loop:
+; CHECK: phi i64
+; CHECK: phi i64
+; CHECK-NOT: phi
+; CHECK: icmp slt
+; CHECK: br i1
+loop:
+ %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
+ %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
+ %diagidx = add nsw i32 %rowidx, %i
+ %diagidxw = sext i32 %diagidx to i64
+ %matrixp = getelementptr inbounds [0 x double]* %matrix, i32 0, i64 %diagidxw
+ %v1 = load double* %matrixp
+ %iw = sext i32 %i to i64
+ %vectorp = getelementptr inbounds [0 x double]* %vector, i32 0, i64 %iw
+ %v2 = load double* %vectorp
+ %row.inc = add nsw i32 %rowidx, %ilead
+ %i.inc = add nsw i32 %i, 1
+ %cmp196 = icmp slt i32 %i.inc, %irow
+ br i1 %cmp196, label %loop, label %return
+
+return:
+ ret void
+}
+
+; Remove %i which is only used by the exit test.
+; Verify that SCEV can still compute a backedge count from the sign
+; extended %n, used for pointer comparison by LFTR.
+define void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind {
+entry:
+ %x.ext = sext i32 %x to i64
+ %add.ptr = getelementptr inbounds i8* %base, i64 %x.ext
+ %y.ext = sext i32 %y to i64
+ %add.ptr10 = getelementptr inbounds i8* %add.ptr, i64 %y.ext
+ %lim = add i32 %x, %n
+ %cmp.ph = icmp ult i32 %x, %lim
+ br i1 %cmp.ph, label %loop, label %exit
+
+; CHECK: loop:
+; CHECK: phi i8*
+; CHECK-NOT: phi
+; CHECK: getelementptr
+; CHECK: store
+; CHECK: icmp ne i8*
+; CHECK: br i1
+loop:
+ %i = phi i32 [ %x, %entry ], [ %inc, %loop ]
+ %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ]
+ %incdec.ptr = getelementptr inbounds i8* %aptr, i32 1
+ store i8 3, i8* %aptr
+ %inc = add i32 %i, 1
+ %cmp = icmp ult i32 %inc, %lim
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+; Exercise backedge taken count verification with a never-taken loop.
+define void @nevertaken() nounwind uwtable ssp {
+entry:
+ br label %loop
+
+; CHECK: loop:
+; CHECK-NOT: phi
+; CHECK-NOT: add
+; CHECK-NOT: icmp
+; CHECK: exit:
+loop:
+ %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
+ %inc = add nsw i32 %i, 1
+ %cmp = icmp sle i32 %inc, 0
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+; Test LFTR on an IV whose recurrence start is a non-unit pointer type.
+define void @aryptriv([256 x i8]* %base, i32 %n) nounwind {
+entry:
+ %ivstart = getelementptr inbounds [256 x i8]* %base, i32 0, i32 0
+ %ivend = getelementptr inbounds [256 x i8]* %base, i32 0, i32 %n
+ %cmp.ph = icmp ult i8* %ivstart, %ivend
+ br i1 %cmp.ph, label %loop, label %exit
+
+; CHECK: loop:
+; CHECK: phi i8*
+; CHECK-NOT: phi
+; CHECK: getelementptr
+; CHECK: store
+; CHECK: icmp ne i8*
+; CHECK: br i1
+loop:
+ %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ]
+ %incdec.ptr = getelementptr inbounds i8* %aptr, i32 1
+ store i8 3, i8* %aptr
+ %cmp = icmp ult i8* %incdec.ptr, %ivend
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/max-pointer.ll b/test/Transforms/IndVarSimplify/max-pointer.ll
deleted file mode 100644
index 46ac2d89b5043..0000000000000
--- a/test/Transforms/IndVarSimplify/max-pointer.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; RUN: opt < %s -indvars -S > %t
-; RUN: grep {icmp ugt i8\\\*} %t | count 1
-; RUN: grep {icmp sgt i8\\\*} %t | count 1
-
-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-n:32:64"
-
- %struct.CKenCodeCodec = type <{ i8 }>
-
-define void @foo(i8* %str1Ptr, i8* %str2Ptr, i8* %inLastBytePtr) nounwind {
-entry:
- %0 = icmp ult i8* %str2Ptr, %str1Ptr ; <i1> [#uses=1]
- %str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr ; <i8*> [#uses=1]
- br label %bb2
-
-bb2: ; preds = %bb2, %entry
- %str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ] ; <i8*> [#uses=1]
- %1 = getelementptr i8* %str2Ptr_addr.1, i64 1 ; <i8*> [#uses=2]
- %2 = icmp ult i8* %1, %inLastBytePtr ; <i1> [#uses=0]
- br i1 undef, label %bb2, label %return
-
-return: ; preds = %bb2
- ret void
-}
-
-define void @sfoo(i8* %str1Ptr, i8* %str2Ptr, i8* %inLastBytePtr) nounwind {
-entry:
- %0 = icmp slt i8* %str2Ptr, %str1Ptr ; <i1> [#uses=1]
- %str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr ; <i8*> [#uses=1]
- br label %bb2
-
-bb2: ; preds = %bb2, %entry
- %str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ] ; <i8*> [#uses=1]
- %1 = getelementptr i8* %str2Ptr_addr.1, i64 1 ; <i8*> [#uses=2]
- %2 = icmp slt i8* %1, %inLastBytePtr ; <i1> [#uses=0]
- br i1 undef, label %bb2, label %return
-
-return: ; preds = %bb2
- ret void
-}
diff --git a/test/Transforms/IndVarSimplify/no-iv-rewrite.ll b/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
index 9605670b86e1f..9c2abd0f31c7d 100644
--- a/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
+++ b/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
;
; Make sure that indvars isn't inserting canonical IVs.
; This is kinda hard to do until linear function test replacement is removed.
@@ -125,9 +125,9 @@ return:
ret void
}
-%struct = type { i32 }
+%structI = type { i32 }
-define void @bitcastiv(i32 %start, i32 %limit, i32 %step, %struct* %base)
+define void @bitcastiv(i32 %start, i32 %limit, i32 %step, %structI* %base)
nounwind
{
entry:
@@ -142,12 +142,12 @@ entry:
; CHECK: exit:
loop:
%iv = phi i32 [%start, %entry], [%next, %loop]
- %p = phi %struct* [%base, %entry], [%pinc, %loop]
- %adr = getelementptr %struct* %p, i32 0, i32 0
+ %p = phi %structI* [%base, %entry], [%pinc, %loop]
+ %adr = getelementptr %structI* %p, i32 0, i32 0
store i32 3, i32* %adr
- %pp = bitcast %struct* %p to i32*
+ %pp = bitcast %structI* %p to i32*
store i32 4, i32* %pp
- %pinc = getelementptr %struct* %p, i32 1
+ %pinc = getelementptr %structI* %p, i32 1
%next = add i32 %iv, 1
%cond = icmp ne i32 %next, %limit
br i1 %cond, label %loop, label %exit
@@ -281,6 +281,7 @@ return:
; CHECK-NOT: phi
; CHECK: add i32
; CHECK: add i32
+; CHECK: add i32
; CHECK-NOT: add
; CHECK: return:
;
@@ -320,3 +321,72 @@ return:
%sum4 = add i32 %sum1, %l.next
ret i32 %sum4
}
+
+; Test a GEP IV that is derived from another GEP IV by a nop gep that
+; lowers the type without changing the expression.
+%structIF = type { i32, float }
+
+define void @congruentgepiv(%structIF* %base) nounwind uwtable ssp {
+entry:
+ %first = getelementptr inbounds %structIF* %base, i64 0, i32 0
+ br label %loop
+
+; CHECK: loop:
+; CHECK: phi %structIF*
+; CHECK: phi i32*
+; CHECK: getelementptr inbounds
+; CHECK: getelementptr inbounds
+; CHECK: exit:
+loop:
+ %ptr.iv = phi %structIF* [ %ptr.inc, %latch ], [ %base, %entry ]
+ %next = phi i32* [ %next.inc, %latch ], [ %first, %entry ]
+ store i32 4, i32* %next
+ br i1 undef, label %latch, label %exit
+
+latch: ; preds = %for.inc50.i
+ %ptr.inc = getelementptr inbounds %structIF* %ptr.iv, i64 1
+ %next.inc = getelementptr inbounds %structIF* %ptr.inc, i64 0, i32 0
+ br label %loop
+
+exit:
+ ret void
+}
+
+; Test a widened IV that is used by a phi on different paths within the loop.
+;
+; CHECK: for.body:
+; CHECK: phi i64
+; CHECK: trunc i64
+; CHECK: if.then:
+; CHECK: for.inc:
+; CHECK: phi i32
+; CHECK: for.end:
+define void @phiUsesTrunc() nounwind {
+entry:
+ br i1 undef, label %for.body, label %for.end
+
+for.body:
+ %iv = phi i32 [ %inc, %for.inc ], [ 1, %entry ]
+ br i1 undef, label %if.then, label %if.else
+
+if.then:
+ br i1 undef, label %if.then33, label %for.inc
+
+if.then33:
+ br label %for.inc
+
+if.else:
+ br i1 undef, label %if.then97, label %for.inc
+
+if.then97:
+ %idxprom100 = sext i32 %iv to i64
+ br label %for.inc
+
+for.inc:
+ %kmin.1 = phi i32 [ %iv, %if.then33 ], [ 0, %if.then ], [ %iv, %if.then97 ], [ 0, %if.else ]
+ %inc = add nsw i32 %iv, 1
+ br i1 undef, label %for.body, label %for.end
+
+for.end:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pointer-indvars.ll b/test/Transforms/IndVarSimplify/pointer-indvars.ll
deleted file mode 100644
index 6d25f90542ca1..0000000000000
--- a/test/Transforms/IndVarSimplify/pointer-indvars.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -indvars -S | grep indvar
-@G = global i32* null ; <i32**> [#uses=1]
-@Array = external global [40 x i32] ; <[40 x i32]*> [#uses=1]
-
-define void @test() {
-; <label>:0
- br label %Loop
-
-Loop: ; preds = %Loop, %0
- %X = phi i32* [ getelementptr ([40 x i32]* @Array, i64 0, i64 0), %0 ], [ %X.next, %Loop ] ; <i32*> [#uses=2]
- %X.next = getelementptr i32* %X, i64 1 ; <i32*> [#uses=1]
- store i32* %X, i32** @G
- br label %Loop
-}
-
diff --git a/test/Transforms/IndVarSimplify/pointer.ll b/test/Transforms/IndVarSimplify/pointer.ll
deleted file mode 100644
index d55bf98d31362..0000000000000
--- a/test/Transforms/IndVarSimplify/pointer.ll
+++ /dev/null
@@ -1,38 +0,0 @@
-; RUN: opt < %s -indvars -S > %t
-; RUN: grep {%exitcond = icmp eq i64 %indvar.next, %n} %t
-; RUN: grep {getelementptr i8\\* %A, i64 %indvar} %t
-; RUN: grep getelementptr %t | count 1
-; RUN: grep add %t | count 1
-; RUN: not grep scevgep %t
-; RUN: not grep ptrtoint %t
-
-; Indvars should be able to expand the pointer-arithmetic
-; IV into an integer IV indexing into a simple getelementptr.
-
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-n:32:64"
-
-define void @foo(i8* %A, i64 %n) nounwind {
-entry:
- %0 = icmp eq i64 %n, 0 ; <i1> [#uses=1]
- br i1 %0, label %return, label %bb.nph
-
-bb.nph: ; preds = %entry
- %1 = getelementptr i8* %A, i64 %n ; <i8*> [#uses=1]
- br label %bb
-
-bb: ; preds = %bb1, %bb.nph
- %q.01 = phi i8* [ %2, %bb1 ], [ %A, %bb.nph ] ; <i8*> [#uses=2]
- store i8 0, i8* %q.01, align 1
- %2 = getelementptr i8* %q.01, i64 1 ; <i8*> [#uses=2]
- br label %bb1
-
-bb1: ; preds = %bb
- %3 = icmp eq i8* %1, %2 ; <i1> [#uses=1]
- br i1 %3, label %bb1.return_crit_edge, label %bb
-
-bb1.return_crit_edge: ; preds = %bb1
- br label %return
-
-return: ; preds = %bb1.return_crit_edge, %entry
- ret void
-}
diff --git a/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll b/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll
index 26f05c4b1ee91..251d34ec383ad 100644
--- a/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll
+++ b/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll
@@ -1,8 +1,8 @@
-; RUN: opt < %s -indvars -S > %t
-; RUN: not grep inttoptr %t
-; RUN: not grep ptrtoint %t
-; RUN: grep scevgep %t
-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-n:32:64"
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; CHECK-NOT: {{inttoptr|ptrtoint}}
+; CHECK: scevgep
+; CHECK-NOT: {{inttoptr|ptrtoint}}
+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-n32:64"
; Indvars shouldn't need inttoptr/ptrtoint to expand an address here.
diff --git a/test/Transforms/IndVarSimplify/preserve-gep-nested.ll b/test/Transforms/IndVarSimplify/preserve-gep-nested.ll
index b41de5828a9dd..cdcaaa0c9254a 100644
--- a/test/Transforms/IndVarSimplify/preserve-gep-nested.ll
+++ b/test/Transforms/IndVarSimplify/preserve-gep-nested.ll
@@ -1,19 +1,20 @@
-; RUN: opt < %s -indvars -S > %t
-; Exactly one getelementptr for each load+store.
-; RUN: grep getelementptr %t | count 6
-; Each getelementptr using %struct.Q* %s as a base and not i8*.
-; RUN: grep {getelementptr \[%\]struct\\.Q\\* \[%\]s,} %t | count 6
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
; No explicit integer multiplications!
-; RUN: not grep {= mul} %t
; No i8* arithmetic or pointer casting anywhere!
-; RUN: not grep {i8\\*} %t
-; RUN: not grep bitcast %t
-; RUN: not grep inttoptr %t
-; RUN: not grep ptrtoint %t
+; CHECK-NOT: = {{= mul|i8\*|bitcast|inttoptr|ptrtoint}}
+; Exactly one getelementptr for each load+store.
+; Each getelementptr using %struct.Q* %s as a base and not i8*.
+; CHECK: getelementptr %struct.Q* %s,
+; CHECK: getelementptr %struct.Q* %s,
+; CHECK: getelementptr %struct.Q* %s,
+; CHECK: getelementptr %struct.Q* %s,
+; CHECK: getelementptr %struct.Q* %s,
+; CHECK: getelementptr %struct.Q* %s,
+; CHECK-NOT: = {{= mul|i8\*|bitcast|inttoptr|ptrtoint}}
; FIXME: This test should pass with or without TargetData. Until opt
; supports running tests without targetdata, just hardware this in.
-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-n:32:64"
+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-n32:64"
%struct.Q = type { [10 x %struct.N] }
%struct.N = type { %struct.S }
diff --git a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll
index ca0c399927602..2f3100fcafbdc 100644
--- a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll
+++ b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll
@@ -1,6 +1,6 @@
-; RUN: opt < %s -indvars -S \
-; RUN: | grep {\[%\]p.2.ip.1 = getelementptr \\\[3 x \\\[3 x double\\\]\\\]\\* \[%\]p, i64 2, i64 \[%\]tmp, i64 1}
-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-n:32:64"
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; CHECK: %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 2, i64 %0, i64 1
+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-n32:64"
; Indvars shouldn't expand this to
; %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 0, i64 %tmp, i64 19
diff --git a/test/Transforms/IndVarSimplify/preserve-gep.ll b/test/Transforms/IndVarSimplify/preserve-gep.ll
index 82eda0386e7fd..fec8a28959889 100644
--- a/test/Transforms/IndVarSimplify/preserve-gep.ll
+++ b/test/Transforms/IndVarSimplify/preserve-gep.ll
@@ -1,12 +1,12 @@
-; RUN: opt < %s -indvars -S > %t
-; RUN: not grep ptrtoint %t
-; RUN: not grep inttoptr %t
-; RUN: grep getelementptr %t | count 1
+; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; CHECK-NOT: {{ptrtoint|inttoptr}}
+; CHECK: getelementptr
+; CHECK-NOT: {{ptrtoint|inttoptr|getelementptr}}
; Indvars shouldn't leave getelementptrs expanded out as
; inttoptr+ptrtoint in its output in common cases.
-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-n:32:64"
+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-n32:64"
target triple = "x86_64-unknown-linux-gnu"
%struct.Foo = type { i32, i32, [10 x i32], i32 }
diff --git a/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll b/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll
index 5063b17454422..22e209283b769 100644
--- a/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll
+++ b/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -indvars -S | FileCheck %s
-; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
; Indvars should insert a 64-bit induction variable to eliminate the
; sext for the addressing, however it shouldn't eliminate the sext
diff --git a/test/Transforms/IndVarSimplify/subtract.ll b/test/Transforms/IndVarSimplify/subtract.ll
deleted file mode 100644
index f45bdab4be587..0000000000000
--- a/test/Transforms/IndVarSimplify/subtract.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -indvars -S | grep indvar
-
-@G = global i64 0 ; <i64*> [#uses=1]
-
-define void @test(i64 %V) {
-; <label>:0
- br label %Loop
-
-Loop: ; preds = %Loop, %0
- %X = phi i64 [ 1, %0 ], [ %X.next, %Loop ] ; <i64> [#uses=2]
- %X.next = sub i64 %X, %V ; <i64> [#uses=1]
- store i64 %X, i64* @G
- br label %Loop
-}
-
diff --git a/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll b/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
index ace74ffb8622d..fc906cdcfb152 100644
--- a/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
+++ b/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -indvars -instcombine -S | FileCheck %s
-; RUN: opt < %s -indvars -disable-iv-rewrite -instcombine -S | FileCheck %s
+; RUN: opt < %s -indvars -enable-iv-rewrite=false -instcombine -S | FileCheck %s
;
; Test that -indvars can reduce variable stride IVs. If it can reduce variable
; stride iv's, it will make %iv. and %m.0.0 isomorphic to each other without
diff --git a/test/Transforms/Inline/2003-09-14-InlineValue.ll b/test/Transforms/Inline/2003-09-14-InlineValue.ll
index 49a27e195e2a7..98bc08b378e0a 100644
--- a/test/Transforms/Inline/2003-09-14-InlineValue.ll
+++ b/test/Transforms/Inline/2003-09-14-InlineValue.ll
@@ -16,6 +16,10 @@ Ok: ; preds = %0
ret i32 %V
Bad: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 0
}
+declare i32 @__gxx_personality_v0(...)
+
diff --git a/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll b/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll
index 4418f77c9d0b4..9af93325f1422 100644
--- a/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll
+++ b/test/Transforms/Inline/2003-09-22-PHINodesInExceptionDest.ll
@@ -6,10 +6,15 @@ entry:
to label %Call2Invoke unwind label %LongJmpBlkPre
Call2Invoke: ; preds = %entry
- br label %LongJmpBlkPre
+ br label %exit
LongJmpBlkPre: ; preds = %Call2Invoke, %entry
%i.3 = phi i32 [ 0, %entry ], [ 0, %Call2Invoke ] ; <i32> [#uses=0]
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ br label %exit
+
+exit:
ret i32 0
}
@@ -19,6 +24,8 @@ define void @__main() {
ret void
}
+declare i32 @__gxx_personality_v0(...)
+
declare void @__llvm_getGlobalCtors()
declare void @__llvm_getGlobalDtors()
diff --git a/test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll b/test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll
deleted file mode 100644
index 9afd45040ca97..0000000000000
--- a/test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; The inliner is breaking inlining invoke instructions where there is a PHI
-; node in the exception destination, and the inlined function contains an
-; unwind instruction.
-
-; RUN: opt < %s -inline -disable-output
-
-define linkonce void @foo() {
- unwind
-}
-
-define i32 @test() {
-BB1:
- invoke void @foo( )
- to label %Cont unwind label %Cont
-
-Cont: ; preds = %BB1, %BB1
- %A = phi i32 [ 0, %BB1 ], [ 0, %BB1 ] ; <i32> [#uses=1]
- ret i32 %A
-}
-
diff --git a/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll b/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll
index 38994519cea45..62a7594ba437b 100644
--- a/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll
+++ b/test/Transforms/Inline/2004-04-15-InlineDeletesCall.ll
@@ -5,7 +5,7 @@
; exists.
define internal void @Callee1() {
- unwind
+ unreachable
}
define void @Callee2() {
diff --git a/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll b/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll
index 733cbb9c754f4..866327f64a8f2 100644
--- a/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll
+++ b/test/Transforms/Inline/2004-10-17-InlineFunctionWithoutReturn.ll
@@ -1,7 +1,7 @@
; RUN: opt < %s -inline -disable-output
define i32 @test() {
- unwind
+ unreachable
}
define i32 @caller() {
diff --git a/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll b/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll
index 37cba9801caa4..b4380d01e483f 100644
--- a/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll
+++ b/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll
@@ -114,7 +114,7 @@ entry:
define fastcc void @_ZSt19__throw_ios_failurePKc() {
entry:
call fastcc void @_ZNSsC1EPKcRKSaIcE( )
- unwind
+ unreachable
}
define void @_GLOBAL__D__ZSt23lexicographical_compareIPKaS1_EbT_S2_T0_S3_() {
@@ -133,10 +133,12 @@ entry:
to label %try_exit.0 unwind label %try_catch.0
try_catch.0: ; preds = %entry
- unreachable
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
+ resume { i8*, i32 } %exn
try_exit.0: ; preds = %entry
- unwind
+ unreachable
}
define fastcc void @_ZNSt11logic_errorC1ERKSs() {
@@ -153,7 +155,7 @@ entry:
define fastcc void @_ZSt20__throw_length_errorPKc() {
entry:
call fastcc void @_ZNSt12length_errorC1ERKSs( )
- unwind
+ unreachable
}
define fastcc void @_ZNSt12length_errorC1ERKSs() {
@@ -162,7 +164,9 @@ entry:
to label %_ZNSt11logic_errorC2ERKSs.exit unwind label %invoke_catch.i
invoke_catch.i: ; preds = %entry
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
+ resume { i8*, i32 } %exn
_ZNSt11logic_errorC2ERKSs.exit: ; preds = %entry
ret void
@@ -199,8 +203,10 @@ entry:
to label %invoke_cont.1 unwind label %invoke_catch.1
invoke_catch.1: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
call fastcc void @_ZNSaIcED1Ev( )
- unwind
+ resume { i8*, i32 } %exn
invoke_cont.1: ; preds = %entry
call fastcc void @_ZNSaIcEC2ERKS_( )
@@ -243,3 +249,5 @@ define fastcc void @_ZN9__gnu_cxx12__pool_allocILb1ELi0EE9_S_refillEj() {
entry:
unreachable
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll b/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll
index 279823a4b2811..b754d9f9f5d9c 100644
--- a/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll
+++ b/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll
@@ -155,7 +155,7 @@ endif.0: ; preds = %entry
define fastcc void @_ZSt20__throw_length_errorPKc() {
entry:
call fastcc void @_ZNSt12length_errorC1ERKSs( )
- unwind
+ ret void
}
define fastcc void @_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcE12__false_type() {
@@ -178,8 +178,10 @@ entry:
to label %invoke_cont.1 unwind label %invoke_catch.1
invoke_catch.1: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
call fastcc void @_ZNSaIcED1Ev( )
- unwind
+ resume { i8*, i32 } %exn
invoke_cont.1: ; preds = %entry
call fastcc void @_ZNSaIcEC2ERKS_( )
@@ -306,7 +308,9 @@ entry:
to label %_ZNSt11logic_errorC2ERKSs.exit unwind label %invoke_catch.i
invoke_catch.i: ; preds = %entry
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
+ resume { i8*, i32 } %exn
_ZNSt11logic_errorC2ERKSs.exit: ; preds = %entry
ret void
@@ -336,3 +340,5 @@ define fastcc void @_ZNSt5ctypeIcEC1EPKtbj() {
entry:
ret void
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/2007-04-15-InlineEH.ll b/test/Transforms/Inline/2007-04-15-InlineEH.ll
index 635f93e824285..8fbcf929d024f 100644
--- a/test/Transforms/Inline/2007-04-15-InlineEH.ll
+++ b/test/Transforms/Inline/2007-04-15-InlineEH.ll
@@ -33,9 +33,13 @@ invcont67: ; preds = %invcont65
ret void
cleanup144: ; preds = %invcont65, %invcont64, %invcont, %entry
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %exn
}
+declare i32 @__gxx_personality_v0(...)
+
declare void @gnat__os_lib__getenv(%struct.gnat__strings__string_access*)
declare void @ada__calendar__delays__delay_for()
diff --git a/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll b/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll
index 979157ebc8b40..a5cfc3b9264c4 100644
--- a/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll
+++ b/test/Transforms/Inline/2007-12-19-InlineNoUnwind.ll
@@ -10,7 +10,7 @@ entry:
r:
ret i32 0
u:
- unwind
+ unreachable
}
define i32 @caller() {
diff --git a/test/Transforms/Inline/callgraph-update.ll b/test/Transforms/Inline/callgraph-update.ll
index ff0120b733065..b96fbc39c2ff2 100644
--- a/test/Transforms/Inline/callgraph-update.ll
+++ b/test/Transforms/Inline/callgraph-update.ll
@@ -29,5 +29,8 @@ invcont:
unreachable
lpad:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/crash.ll b/test/Transforms/Inline/crash.ll
index 1df4d6063e84c..e2cd49c2516c8 100644
--- a/test/Transforms/Inline/crash.ll
+++ b/test/Transforms/Inline/crash.ll
@@ -69,9 +69,13 @@ invcont98:
unreachable
lpad156:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
+declare i32 @__gxx_personality_v0(...)
+
declare fastcc void @YYY()
define internal fastcc void @XXX() {
@@ -84,7 +88,9 @@ bb260:
ret void
lpad:
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %exn
}
@@ -105,6 +111,8 @@ invcont3: ; preds = %bb1
ret void
lpad18: ; preds = %invcont3, %bb1
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
diff --git a/test/Transforms/Inline/inline_invoke.ll b/test/Transforms/Inline/inline_invoke.ll
index 2a1b8836c76e5..9f5f670b859bc 100644
--- a/test/Transforms/Inline/inline_invoke.ll
+++ b/test/Transforms/Inline/inline_invoke.ll
@@ -18,14 +18,8 @@ declare void @use(i32) nounwind
declare void @opaque()
-declare i8* @llvm.eh.exception() nounwind readonly
-
-declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
-
declare i32 @llvm.eh.typeid.for(i8*) nounwind
-declare void @llvm.eh.resume(i8*, i32)
-
declare i32 @__gxx_personality_v0(...)
declare i8* @__cxa_begin_catch(i8*)
@@ -51,18 +45,17 @@ invoke.cont1:
ret void
lpad:
- %exn = call i8* @llvm.eh.exception() nounwind
- %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0) nounwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
invoke void @_ZN1AD1Ev(%struct.A* %a)
to label %invoke.cont2 unwind label %terminate.lpad
invoke.cont2:
- call void @llvm.eh.resume(i8* %exn, i32 %eh.selector) noreturn
- unreachable
+ resume { i8*, i32 } %exn
terminate.lpad:
- %exn3 = call i8* @llvm.eh.exception() nounwind
- %eh.selector4 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn3, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) nounwind
+ %exn1 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
call void @_ZSt9terminatev() noreturn nounwind
unreachable
}
@@ -76,20 +69,21 @@ ret:
ret void
lpad: ; preds = %entry
- %exn = call i8* @llvm.eh.exception() nounwind
- %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* bitcast (i8** @_ZTIi to i8*)
+ %eh.exc = extractvalue { i8*, i32 } %exn, 0
+ %eh.selector = extractvalue { i8*, i32 } %exn, 1
%0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
%1 = icmp eq i32 %eh.selector, %0
br i1 %1, label %catch, label %eh.resume
catch:
- %ignored = call i8* @__cxa_begin_catch(i8* %exn) nounwind
+ %ignored = call i8* @__cxa_begin_catch(i8* %eh.exc) nounwind
call void @__cxa_end_catch() nounwind
br label %ret
eh.resume:
- call void @llvm.eh.resume(i8* %exn, i32 %eh.selector) noreturn
- unreachable
+ resume { i8*, i32 } %exn
}
; CHECK: define void @test0_out()
@@ -99,18 +93,21 @@ eh.resume:
; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[B]])
; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[B]])
; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
-; CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
; CHECK-NEXT: to label %[[LBL:[^\s]+]] unwind
; CHECK: [[LBL]]:
; CHECK-NEXT: br label %[[LPAD:[^\s]+]]
; CHECK: ret void
-; CHECK: call i8* @llvm.eh.exception()
-; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: br label %[[LPAD]]
; CHECK: [[LPAD]]:
-; CHECK-NEXT: phi i8* [
-; CHECK-NEXT: phi i32 [
+; CHECK-NEXT: phi { i8*, i32 } [
+; CHECK-NEXT: extractvalue { i8*, i32 }
+; CHECK-NEXT: extractvalue { i8*, i32 }
; CHECK-NEXT: call i32 @llvm.eh.typeid.for(
@@ -131,22 +128,23 @@ ret:
lpad:
%x = phi i32 [ 0, %entry ], [ 1, %cont ]
%y = phi i32 [ 1, %entry ], [ 4, %cont ]
- %exn = call i8* @llvm.eh.exception() nounwind
- %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* bitcast (i8** @_ZTIi to i8*)
+ %eh.exc = extractvalue { i8*, i32 } %exn, 0
+ %eh.selector = extractvalue { i8*, i32 } %exn, 1
%0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
%1 = icmp eq i32 %eh.selector, %0
br i1 %1, label %catch, label %eh.resume
catch:
- %ignored = call i8* @__cxa_begin_catch(i8* %exn) nounwind
+ %ignored = call i8* @__cxa_begin_catch(i8* %eh.exc) nounwind
call void @use(i32 %x)
call void @use(i32 %y)
call void @__cxa_end_catch() nounwind
br label %ret
eh.resume:
- call void @llvm.eh.resume(i8* %exn, i32 %eh.selector) noreturn
- unreachable
+ resume { i8*, i32 } %exn
}
; CHECK: define void @test1_out()
@@ -165,8 +163,9 @@ eh.resume:
; Inner landing pad from first inlining.
; CHECK: [[LPAD1]]:
-; CHECK-NEXT: [[EXN1:%.*]] = call i8* @llvm.eh.exception()
-; CHECK-NEXT: [[SEL1:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[EXN1]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: [[LPADVAL1:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A1]])
; CHECK-NEXT: to label %[[RESUME1:[^\s]+]] unwind
; CHECK: [[RESUME1]]:
@@ -183,8 +182,9 @@ eh.resume:
; Inner landing pad from second inlining.
; CHECK: [[LPAD2]]:
-; CHECK-NEXT: [[EXN2:%.*]] = call i8* @llvm.eh.exception()
-; CHECK-NEXT: [[SEL2:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[EXN2]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: [[LPADVAL2:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A2]])
; CHECK-NEXT: to label %[[RESUME2:[^\s]+]] unwind
; CHECK: [[RESUME2]]:
@@ -195,29 +195,29 @@ eh.resume:
; CHECK: [[LPAD]]:
; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, %entry ], [ 0, {{%.*}} ], [ 1, %cont ], [ 1, {{%.*}} ]
; CHECK-NEXT: [[Y:%.*]] = phi i32 [ 1, %entry ], [ 1, {{%.*}} ], [ 4, %cont ], [ 4, {{%.*}} ]
-; CHECK-NEXT: [[EXN:%.*]] = call i8* @llvm.eh.exception()
-; CHECK-NEXT: [[SEL:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[EXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: [[LPADVAL:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: br label %[[LPAD_JOIN2]]
; CHECK: [[LPAD_JOIN2]]:
; CHECK-NEXT: [[XJ2:%.*]] = phi i32 [ [[X]], %[[LPAD]] ], [ 1, %[[RESUME2]] ]
; CHECK-NEXT: [[YJ2:%.*]] = phi i32 [ [[Y]], %[[LPAD]] ], [ 4, %[[RESUME2]] ]
-; CHECK-NEXT: [[EXNJ2:%.*]] = phi i8* [ [[EXN]], %[[LPAD]] ], [ [[EXN2]], %[[RESUME2]] ]
-; CHECK-NEXT: [[SELJ2:%.*]] = phi i32 [ [[SEL]], %[[LPAD]] ], [ [[SEL2]], %[[RESUME2]] ]
+; CHECK-NEXT: [[EXNJ2:%.*]] = phi { i8*, i32 } [ [[LPADVAL]], %[[LPAD]] ], [ [[LPADVAL2]], %[[RESUME2]] ]
; CHECK-NEXT: br label %[[LPAD_JOIN1]]
; CHECK: [[LPAD_JOIN1]]:
; CHECK-NEXT: [[XJ1:%.*]] = phi i32 [ [[XJ2]], %[[LPAD_JOIN2]] ], [ 0, %[[RESUME1]] ]
; CHECK-NEXT: [[YJ1:%.*]] = phi i32 [ [[YJ2]], %[[LPAD_JOIN2]] ], [ 1, %[[RESUME1]] ]
-; CHECK-NEXT: [[EXNJ1:%.*]] = phi i8* [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[EXN1]], %[[RESUME1]] ]
-; CHECK-NEXT: [[SELJ1:%.*]] = phi i32 [ [[SELJ2]], %[[LPAD_JOIN2]] ], [ [[SEL1]], %[[RESUME1]] ]
+; CHECK-NEXT: [[EXNJ1:%.*]] = phi { i8*, i32 } [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[LPADVAL1]], %[[RESUME1]] ]
+; CHECK-NEXT: extractvalue { i8*, i32 } [[EXNJ1]], 0
+; CHECK-NEXT: [[SELJ1:%.*]] = extractvalue { i8*, i32 } [[EXNJ1]], 1
; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for(
; CHECK-NEXT: icmp eq i32 [[SELJ1]], [[T]]
; CHECK: call void @use(i32 [[XJ1]])
; CHECK: call void @use(i32 [[YJ1]])
-; CHECK: call void @llvm.eh.resume(i8* [[EXNJ1]], i32 [[SELJ1]])
+; CHECK: resume { i8*, i32 }
;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls
@@ -230,6 +230,8 @@ ret:
ret void
lpad:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
call void @_ZSt9terminatev()
unreachable
}
@@ -257,24 +259,25 @@ ret:
ret void
lpad:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* bitcast (i8** @_ZTIi to i8*)
br label %lpad.cont
lpad.cont:
- %exn = call i8* @llvm.eh.exception() nounwind
- %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
call void @_ZSt9terminatev()
unreachable
}
; CHECK: define void @test3_out()
-; CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(
; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
; CHECK: [[L]]:
; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
; CHECK: [[JOIN]]:
-; CHECK-NEXT: phi
-; CHECK-NEXT: phi
+; CHECK-NEXT: phi { i8*, i32 }
; CHECK-NEXT: br label %lpad.cont
; CHECK: lpad.cont:
; CHECK-NEXT: call void @_ZSt9terminatev()
@@ -294,20 +297,27 @@ ret:
ret void
lpad.crit:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* bitcast (i8** @_ZTIi to i8*)
call void @opaque() nounwind
- br label %lpad
+ br label %terminate
lpad:
- %phi = phi i32 [ 0, %lpad.crit ], [ 1, %cont ]
- %exn = call i8* @llvm.eh.exception() nounwind
- %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
+ %exn2 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* bitcast (i8** @_ZTIi to i8*)
+ br label %terminate
+
+terminate:
+ %phi = phi i32 [ 0, %lpad.crit ], [ 1, %lpad ]
call void @use(i32 %phi)
call void @_ZSt9terminatev()
unreachable
}
; CHECK: define void @test4_out()
-; CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(
; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
; CHECK: [[L]]:
@@ -315,22 +325,18 @@ lpad:
; CHECK: invoke void @opaque()
; CHECK-NEXT: unwind label %lpad
; CHECK: lpad.crit:
-; CHECK-NEXT: call i8* @llvm.eh.exception()
-; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %4, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: br label %[[JOIN]]
; CHECK: [[JOIN]]:
-; CHECK-NEXT: phi i8*
-; CHECK-NEXT: phi i32
+; CHECK-NEXT: phi { i8*, i32 }
; CHECK-NEXT: call void @opaque() nounwind
; CHECK-NEXT: br label %[[FIX:[^\s]+]]
; CHECK: lpad:
-; CHECK-NEXT: [[T0:%.*]] = phi i32 [ 1, %cont ]
-; CHECK-NEXT: call i8* @llvm.eh.exception() nounwind
-; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: br label %[[FIX]]
; CHECK: [[FIX]]:
-; CHECK-NEXT: [[T1:%.*]] = phi i32 [ [[T0]], %lpad ], [ 0, %[[JOIN]] ]
-; CHECK-NEXT: phi i8*
-; CHECK-NEXT: phi i32
+; CHECK-NEXT: [[T1:%.*]] = phi i32 [ 0, %[[JOIN]] ], [ 1, %lpad ]
; CHECK-NEXT: call void @use(i32 [[T1]])
; CHECK-NEXT: call void @_ZSt9terminatev()
diff --git a/test/Transforms/Inline/invoke_test-1.ll b/test/Transforms/Inline/invoke_test-1.ll
index 0d27e2a7f5e4c..e0e6d600bbb36 100644
--- a/test/Transforms/Inline/invoke_test-1.ll
+++ b/test/Transforms/Inline/invoke_test-1.ll
@@ -20,5 +20,9 @@ cont: ; preds = %0
ret i32 0
exc: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/invoke_test-2.ll b/test/Transforms/Inline/invoke_test-2.ll
index bbb9ab055393d..680a5ca2542a2 100644
--- a/test/Transforms/Inline/invoke_test-2.ll
+++ b/test/Transforms/Inline/invoke_test-2.ll
@@ -14,6 +14,8 @@ cont: ; preds = %0
ret i32 0
exc: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 1
}
@@ -26,5 +28,9 @@ cont: ; preds = %0
ret i32 %X
UnreachableExceptionHandler: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 -1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/invoke_test-3.ll b/test/Transforms/Inline/invoke_test-3.ll
index b360526fb3484..f5ce95aa516cf 100644
--- a/test/Transforms/Inline/invoke_test-3.ll
+++ b/test/Transforms/Inline/invoke_test-3.ll
@@ -14,7 +14,9 @@ cont: ; preds = %0
exc: ; preds = %0a
; This just rethrows the exception!
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %exn
}
; caller returns true if might_throw throws an exception... which gets
@@ -28,5 +30,9 @@ cont: ; preds = %0
Handler: ; preds = %0
; This consumes an exception thrown by might_throw
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll b/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll
index cfe5df6d30a36..56493e2e5e320 100644
--- a/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll
+++ b/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll
@@ -10,6 +10,9 @@ invoke_cont: ; preds = %0
ret float* %tmp.11
X: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret float* null
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll b/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll
index bec0b9e0c5733..6df30c7e7fd14 100644
--- a/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll
+++ b/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll
@@ -23,6 +23,9 @@ cont: ; preds = %call, %entry
ret i32 %V
N: ; preds = %call
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 0
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll b/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll
index 9bb940893935f..aacea9df5b31e 100644
--- a/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll
+++ b/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll
@@ -3,7 +3,8 @@
%struct.FRAME.nest = type { i32, i32 (...)* }
%struct.__builtin_trampoline = type { [10 x i8] }
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind
+declare void @llvm.init.trampoline(i8*, i8*, i8*) nounwind
+declare i8* @llvm.adjust.trampoline(i8*) nounwind
declare i32 @f(%struct.FRAME.nest* nest , ...)
@@ -15,7 +16,8 @@ entry:
%tmp3 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 0 ; <i32*> [#uses=1]
store i32 %n, i32* %tmp3, align 8
%FRAME.06 = bitcast %struct.FRAME.nest* %FRAME.0 to i8* ; <i8*> [#uses=1]
- %tramp = call i8* @llvm.init.trampoline( i8* %TRAMP.216.sub, i8* bitcast (i32 (%struct.FRAME.nest*, ...)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
+ call void @llvm.init.trampoline( i8* %TRAMP.216.sub, i8* bitcast (i32 (%struct.FRAME.nest*, ...)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
+ %tramp = call i8* @llvm.adjust.trampoline( i8* %TRAMP.216.sub)
%tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (...)**> [#uses=1]
%tmp89 = bitcast i8* %tramp to i32 (...)* ; <i32 (...)*> [#uses=2]
store i32 (...)* %tmp89, i32 (...)** %tmp7, align 8
diff --git a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
index 626564da936a4..6847f5ed0534a 100644
--- a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
+++ b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep {volatile store}
+; RUN: opt < %s -instcombine -S | grep {store volatile}
define void @test() {
%votf = alloca <4 x float> ; <<4 x float>*> [#uses=1]
diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
index f2cc7254a3255..a24f3071c9ac7 100644
--- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
+++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep {volatile load} | count 2
+; RUN: opt < %s -instcombine -S | grep {load volatile} | count 2
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-darwin8"
@g_1 = internal global i32 0 ; <i32*> [#uses=3]
diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
index 176162d386363..5fb11ffb32da0 100644
--- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
+++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep {volatile load} | count 2
+; RUN: opt < %s -instcombine -S | grep {load volatile} | count 2
; PR2262
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-darwin8"
diff --git a/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll b/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll
index d56a1a0b786ae..f6eb24843fb88 100644
--- a/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll
+++ b/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll
@@ -29,5 +29,9 @@ invcont37: ; preds = %invcont31
ret void
lpad: ; preds = %invcont31, %invcont, %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
index ccfb1182769f6..81044083c6026 100644
--- a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
+++ b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep {volatile load} | count 2
+; RUN: opt < %s -instcombine -S | grep {load volatile} | count 2
; PR2496
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-darwin8"
diff --git a/test/Transforms/InstCombine/2011-09-03-Trampoline.ll b/test/Transforms/InstCombine/2011-09-03-Trampoline.ll
new file mode 100644
index 0000000000000..5456e03573939
--- /dev/null
+++ b/test/Transforms/InstCombine/2011-09-03-Trampoline.ll
@@ -0,0 +1,87 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+declare void @llvm.init.trampoline(i8*, i8*, i8*)
+declare i8* @llvm.adjust.trampoline(i8*)
+declare i32 @f(i8 * nest, i32)
+
+; Most common case
+define i32 @test0(i32 %n) {
+ %alloca = alloca [10 x i8], align 16
+ %gep = getelementptr [10 x i8]* %alloca, i32 0, i32 0
+ call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*),
+ i8* null)
+ %tramp = call i8* @llvm.adjust.trampoline(i8* %gep)
+ %function = bitcast i8* %tramp to i32(i32)*
+ %ret = call i32 %function(i32 %n)
+ ret i32 %ret
+
+; CHECK: define i32 @test0(i32 %n) {
+; CHECK: %ret = call i32 @f(i8* nest null, i32 %n)
+}
+
+define i32 @test1(i32 %n, i8* %trampmem) {
+ call void @llvm.init.trampoline(i8* %trampmem,
+ i8* bitcast (i32 (i8*, i32)* @f to i8*),
+ i8* null)
+ %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem)
+ %function = bitcast i8* %tramp to i32(i32)*
+ %ret = call i32 %function(i32 %n)
+ ret i32 %ret
+; CHECK: define i32 @test1(i32 %n, i8* %trampmem) {
+; CHECK: %ret = call i32 @f(i8* nest null, i32 %n)
+}
+
+define i32 @test2(i32 %n, i8* %trampmem) {
+ %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem)
+ %functiona = bitcast i8* %tramp to i32(i32)*
+ %ret = call i32 %functiona(i32 %n)
+ ret i32 %ret
+; CHECK: define i32 @test2(i32 %n, i8* %trampmem) {
+; CHECK: %ret = call i32 %functiona(i32 %n)
+}
+
+define i32 @test3(i32 %n, i8* %trampmem) {
+ call void @llvm.init.trampoline(i8* %trampmem,
+ i8* bitcast (i32 (i8*, i32)* @f to i8*),
+ i8* null)
+
+; CHECK: define i32 @test3(i32 %n, i8* %trampmem) {
+; CHECK: %ret0 = call i32 @f(i8* nest null, i32 %n)
+ %tramp0 = call i8* @llvm.adjust.trampoline(i8* %trampmem)
+ %function0 = bitcast i8* %tramp0 to i32(i32)*
+ %ret0 = call i32 %function0(i32 %n)
+
+ ;; Not optimized since previous call could be writing.
+ %tramp1 = call i8* @llvm.adjust.trampoline(i8* %trampmem)
+ %function1 = bitcast i8* %tramp1 to i32(i32)*
+ %ret1 = call i32 %function1(i32 %n)
+; CHECK: %ret1 = call i32 %function1(i32 %n)
+
+ ret i32 %ret1
+}
+
+define i32 @test4(i32 %n) {
+ %alloca = alloca [10 x i8], align 16
+ %gep = getelementptr [10 x i8]* %alloca, i32 0, i32 0
+ call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*),
+ i8* null)
+
+ %tramp0 = call i8* @llvm.adjust.trampoline(i8* %gep)
+ %function0 = bitcast i8* %tramp0 to i32(i32)*
+ %ret0 = call i32 %function0(i32 %n)
+
+ %tramp1 = call i8* @llvm.adjust.trampoline(i8* %gep)
+ %function1 = bitcast i8* %tramp0 to i32(i32)*
+ %ret1 = call i32 %function1(i32 %n)
+
+ %tramp2 = call i8* @llvm.adjust.trampoline(i8* %gep)
+ %function2 = bitcast i8* %tramp2 to i32(i32)*
+ %ret2 = call i32 %function2(i32 %n)
+
+ ret i32 %ret2
+
+; CHECK: define i32 @test4(i32 %n) {
+; CHECK: %ret0 = call i32 @f(i8* nest null, i32 %n)
+; CHECK: %ret1 = call i32 @f(i8* nest null, i32 %n)
+; CHECK: %ret2 = call i32 @f(i8* nest null, i32 %n)
+}
diff --git a/test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll b/test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll
new file mode 100644
index 0000000000000..22061b272a85f
--- /dev/null
+++ b/test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll
@@ -0,0 +1,20 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+; rdar://problem/10063307
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
+target triple = "thumbv7-apple-ios5.0.0"
+
+%0 = type { [2 x i32] }
+%struct.CGPoint = type { float, float }
+
+define void @t(%struct.CGPoint* %a) nounwind {
+ %Point = alloca %struct.CGPoint, align 4
+ %1 = bitcast %struct.CGPoint* %a to i64*
+ %2 = bitcast %struct.CGPoint* %Point to i64*
+ %3 = load i64* %1, align 4
+ store i64 %3, i64* %2, align 4
+ call void @foo(i64* %2) nounwind
+ ret void
+; CHECK: %Point = alloca i64, align 4
+}
+
+declare void @foo(i64*)
diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll
new file mode 100644
index 0000000000000..055bdcc81b564
--- /dev/null
+++ b/test/Transforms/InstCombine/LandingPadClauses.ll
@@ -0,0 +1,181 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+@T1 = external constant i32
+@T2 = external constant i32
+@T3 = external constant i32
+
+declare i32 @generic_personality(i32, i64, i8*, i8*)
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+
+declare void @bar()
+
+define void @foo_generic() {
+; CHECK: @foo_generic
+ invoke void @bar()
+ to label %cont.a unwind label %lpad.a
+cont.a:
+ invoke void @bar()
+ to label %cont.b unwind label %lpad.b
+cont.b:
+ invoke void @bar()
+ to label %cont.c unwind label %lpad.c
+cont.c:
+ invoke void @bar()
+ to label %cont.d unwind label %lpad.d
+cont.d:
+ invoke void @bar()
+ to label %cont.e unwind label %lpad.e
+cont.e:
+ invoke void @bar()
+ to label %cont.f unwind label %lpad.f
+cont.f:
+ invoke void @bar()
+ to label %cont.g unwind label %lpad.g
+cont.g:
+ invoke void @bar()
+ to label %cont.h unwind label %lpad.h
+cont.h:
+ invoke void @bar()
+ to label %cont.i unwind label %lpad.i
+cont.i:
+ ret void
+
+lpad.a:
+ %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ catch i32* @T1
+ catch i32* @T2
+ catch i32* @T1
+ catch i32* @T2
+ unreachable
+; CHECK: %a = landingpad
+; CHECK-NEXT: @T1
+; CHECK-NEXT: @T2
+; CHECK-NEXT: unreachable
+
+lpad.b:
+ %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [0 x i32*] zeroinitializer
+ catch i32* @T1
+ unreachable
+; CHECK: %b = landingpad
+; CHECK-NEXT: filter
+; CHECK-NEXT: unreachable
+
+lpad.c:
+ %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ catch i32* @T1
+ filter [1 x i32*] [i32* @T1]
+ catch i32* @T2
+ unreachable
+; CHECK: %c = landingpad
+; CHECK-NEXT: @T1
+; CHECK-NEXT: filter [0 x i32*]
+; CHECK-NEXT: unreachable
+
+lpad.d:
+ %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [3 x i32*] zeroinitializer
+ unreachable
+; CHECK: %d = landingpad
+; CHECK-NEXT: filter [1 x i32*] zeroinitializer
+; CHECK-NEXT: unreachable
+
+lpad.e:
+ %e = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ catch i32* @T1
+ filter [3 x i32*] [i32* @T1, i32* @T2, i32* @T2]
+ unreachable
+; CHECK: %e = landingpad
+; CHECK-NEXT: @T1
+; CHECK-NEXT: filter [1 x i32*] [i32* @T2]
+; CHECK-NEXT: unreachable
+
+lpad.f:
+ %f = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [2 x i32*] [i32* @T2, i32* @T1]
+ filter [1 x i32*] [i32* @T1]
+ unreachable
+; CHECK: %f = landingpad
+; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
+; CHECK-NEXT: unreachable
+
+lpad.g:
+ %g = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [1 x i32*] [i32* @T1]
+ catch i32* @T3
+ filter [2 x i32*] [i32* @T2, i32* @T1]
+ unreachable
+; CHECK: %g = landingpad
+; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
+; CHECK-NEXT: catch i32* @T3
+; CHECK-NEXT: unreachable
+
+lpad.h:
+ %h = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ filter [2 x i32*] [i32* @T1, i32* null]
+ filter [1 x i32*] zeroinitializer
+ unreachable
+; CHECK: %h = landingpad
+; CHECK-NEXT: filter [1 x i32*] zeroinitializer
+; CHECK-NEXT: unreachable
+
+lpad.i:
+ %i = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality
+ cleanup
+ filter [0 x i32*] zeroinitializer
+ unreachable
+; CHECK: %i = landingpad
+; CHECK-NEXT: filter
+; CHECK-NEXT: unreachable
+}
+
+define void @foo_cxx() {
+; CHECK: @foo_cxx
+ invoke void @bar()
+ to label %cont.a unwind label %lpad.a
+cont.a:
+ invoke void @bar()
+ to label %cont.b unwind label %lpad.b
+cont.b:
+ invoke void @bar()
+ to label %cont.c unwind label %lpad.c
+cont.c:
+ invoke void @bar()
+ to label %cont.d unwind label %lpad.d
+cont.d:
+ ret void
+
+lpad.a:
+ %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ catch i32* null
+ catch i32* @T1
+ unreachable
+; CHECK: %a = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+
+lpad.b:
+ %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ filter [1 x i32*] zeroinitializer
+ unreachable
+; CHECK: %b = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+
+lpad.c:
+ %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ filter [2 x i32*] [i32* @T1, i32* null]
+ unreachable
+; CHECK: %c = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+
+lpad.d:
+ %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ cleanup
+ catch i32* null
+ unreachable
+; CHECK: %d = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+}
diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll
index a8881522eac4b..531aedb668a01 100644
--- a/test/Transforms/InstCombine/and2.ll
+++ b/test/Transforms/InstCombine/and2.ll
@@ -35,3 +35,10 @@ define i1 @test4(i32 %X) {
; CHECK: @test4
; CHECK-NEXT: ret i1 false
}
+
+; Make sure we don't go into an infinite loop with this test
+define <4 x i32> @test5(<4 x i32> %A) {
+ %1 = xor <4 x i32> %A, <i32 1, i32 2, i32 3, i32 4>
+ %2 = and <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %1
+ ret <4 x i32> %2
+}
diff --git a/test/Transforms/InstCombine/atomic.ll b/test/Transforms/InstCombine/atomic.ll
new file mode 100644
index 0000000000000..097cf5eafe068
--- /dev/null
+++ b/test/Transforms/InstCombine/atomic.ll
@@ -0,0 +1,24 @@
+; RUN: opt -S < %s -instcombine | 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-macosx10.7.0"
+
+; Check transforms involving atomic operations
+
+define i32* @test1(i8** %p) {
+; CHECK: define i32* @test1
+; CHECK: load atomic i8** %p monotonic, align 8
+ %c = bitcast i8** %p to i32**
+ %r = load atomic i32** %c monotonic, align 8
+ ret i32* %r
+}
+
+define i32 @test2(i32* %p) {
+; CHECK: define i32 @test2
+; CHECK: %x = load atomic i32* %p seq_cst, align 4
+; CHECK: shl i32 %x, 1
+ %x = load atomic i32* %p seq_cst, align 4
+ %y = load i32* %p, align 4
+ %z = add i32 %x, %y
+ ret i32 %z
+}
diff --git a/test/Transforms/InstCombine/bitcast.ll b/test/Transforms/InstCombine/bitcast.ll
index 0718b8a3aee04..8f6ae7d83527e 100644
--- a/test/Transforms/InstCombine/bitcast.ll
+++ b/test/Transforms/InstCombine/bitcast.ll
@@ -1,5 +1,8 @@
; RUN: opt < %s -instcombine -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"
+
; Bitcasts between vectors and scalars are valid.
; PR4487
define i32 @test1(i64 %a) {
@@ -103,3 +106,34 @@ define <2 x float> @test6(float %A){
; CHECK-NEXT: insertelement <2 x float> <float 4.200000e+01, float undef>, float %A, i32 1
; CHECK: ret
}
+
+define i64 @ISPC0(i64 %in) {
+ %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1> to i64), i64 -1)
+ ret i64 %out
+; CHECK: @ISPC0
+; CHECK: ret i64 0
+}
+
+
+define i64 @Vec2(i64 %in) {
+ %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 0> to i64), i64 0)
+ ret i64 %out
+; CHECK: @Vec2
+; CHECK: ret i64 0
+}
+
+define i64 @All11(i64 %in) {
+ %out = and i64 %in, xor (i64 bitcast (<2 x float> bitcast (i64 -1 to <2 x float>) to i64), i64 -1)
+ ret i64 %out
+; CHECK: @All11
+; CHECK: ret i64 0
+}
+
+
+define i32 @All111(i32 %in) {
+ %out = and i32 %in, xor (i32 bitcast (<1 x float> bitcast (i32 -1 to <1 x float>) to i32), i32 -1)
+ ret i32 %out
+; CHECK: @All111
+; CHECK: ret i32 0
+}
+
diff --git a/test/Transforms/InstCombine/call.ll b/test/Transforms/InstCombine/call.ll
index d0848739cdcc2..96ec420eaa8e6 100644
--- a/test/Transforms/InstCombine/call.ll
+++ b/test/Transforms/InstCombine/call.ll
@@ -9,8 +9,8 @@ declare void @test1a(i8*)
define void @test1(i32* %A) {
call void bitcast (void (i8*)* @test1a to void (i32*)*)( i32* %A )
ret void
-; CHECK: %tmp = bitcast i32* %A to i8*
-; CHECK: call void @test1a(i8* %tmp)
+; CHECK: %1 = bitcast i32* %A to i8*
+; CHECK: call void @test1a(i8* %1)
; CHECK: ret void
}
@@ -24,8 +24,8 @@ define void @test2a(i8 %A) {
define i32 @test2(i32 %A) {
call void bitcast (void (i8)* @test2a to void (i32)*)( i32 %A )
ret i32 %A
-; CHECK: %tmp = trunc i32 %A to i8
-; CHECK: call void @test2a(i8 %tmp)
+; CHECK: %1 = trunc i32 %A to i8
+; CHECK: call void @test2a(i8 %1)
; CHECK: ret i32 %A
}
@@ -38,8 +38,8 @@ define void @test3(i8 %A, i8 %B) {
call void bitcast (void (i8, ...)* @test3a to void (i8, i8)*)( i8 %A, i8 %B
)
ret void
-; CHECK: %tmp = zext i8 %B to i32
-; CHECK: call void (i8, ...)* @test3a(i8 %A, i32 %tmp)
+; CHECK: %1 = zext i8 %B to i32
+; CHECK: call void (i8, ...)* @test3a(i8 %A, i32 %1)
; CHECK: ret void
}
@@ -54,8 +54,8 @@ define i32 @test4() {
%X = call i32 bitcast (i8 ()* @test4a to i32 ()*)( ) ; <i32> [#uses=1]
ret i32 %X
; CHECK: %X = call i8 @test4a()
-; CHECK: %tmp = zext i8 %X to i32
-; CHECK: ret i32 %tmp
+; CHECK: %1 = zext i8 %X to i32
+; CHECK: ret i32 %1
}
@@ -107,9 +107,13 @@ invoke.cont: ; preds = %entry
unreachable
try.handler: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i8* null
}
+declare i32 @__gxx_personality_v0(...)
+
; Don't turn this into "unreachable": the callee and caller don't agree in
; calling conv, but the implementation of test8a may actually end up using the
; right calling conv.
diff --git a/test/Transforms/InstCombine/canonicalize_branch.ll b/test/Transforms/InstCombine/canonicalize_branch.ll
index 24090abcb5acd..869546d57dcd9 100644
--- a/test/Transforms/InstCombine/canonicalize_branch.ll
+++ b/test/Transforms/InstCombine/canonicalize_branch.ll
@@ -1,8 +1,23 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
+; Test an already canonical branch to make sure we don't flip those.
+define i32 @test0(i32 %X, i32 %Y) {
+ %C = icmp eq i32 %X, %Y
+ br i1 %C, label %T, label %F, !prof !0
+
+; CHECK: @test0
+; CHECK: %C = icmp eq i32 %X, %Y
+; CHECK: br i1 %C, label %T, label %F
+
+T:
+ ret i32 12
+F:
+ ret i32 123
+}
+
define i32 @test1(i32 %X, i32 %Y) {
%C = icmp ne i32 %X, %Y
- br i1 %C, label %T, label %F
+ br i1 %C, label %T, label %F, !prof !1
; CHECK: @test1
; CHECK: %C = icmp eq i32 %X, %Y
@@ -16,7 +31,7 @@ F:
define i32 @test2(i32 %X, i32 %Y) {
%C = icmp ule i32 %X, %Y
- br i1 %C, label %T, label %F
+ br i1 %C, label %T, label %F, !prof !2
; CHECK: @test2
; CHECK: %C = icmp ugt i32 %X, %Y
@@ -30,7 +45,7 @@ F:
define i32 @test3(i32 %X, i32 %Y) {
%C = icmp uge i32 %X, %Y
- br i1 %C, label %T, label %F
+ br i1 %C, label %T, label %F, !prof !3
; CHECK: @test3
; CHECK: %C = icmp ult i32 %X, %Y
@@ -42,3 +57,13 @@ F:
ret i32 123
}
+!0 = metadata !{metadata !"branch_weights", i32 1, i32 2}
+!1 = metadata !{metadata !"branch_weights", i32 3, i32 4}
+!2 = metadata !{metadata !"branch_weights", i32 5, i32 6}
+!3 = metadata !{metadata !"branch_weights", i32 7, i32 8}
+; Base case shouldn't change.
+; CHECK: !0 = {{.*}} i32 1, i32 2}
+; Ensure that the branch metadata is reversed to match the reversals above.
+; CHECK: !1 = {{.*}} i32 4, i32 3}
+; CHECK: !2 = {{.*}} i32 6, i32 5}
+; CHECK: !3 = {{.*}} i32 8, i32 7}
diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll
index f85636f8df54d..19d5a0ae772d1 100644
--- a/test/Transforms/InstCombine/cast.ll
+++ b/test/Transforms/InstCombine/cast.ll
@@ -630,3 +630,50 @@ entry:
; CHECK: uitofp
}
+define <4 x float> @test64(<4 x float> %c) nounwind {
+ %t0 = bitcast <4 x float> %c to <4 x i32>
+ %t1 = bitcast <4 x i32> %t0 to <4 x float>
+ ret <4 x float> %t1
+; CHECK: @test64
+; CHECK-NEXT: ret <4 x float> %c
+}
+
+define <4 x float> @test65(<4 x float> %c) nounwind {
+ %t0 = bitcast <4 x float> %c to <2 x double>
+ %t1 = bitcast <2 x double> %t0 to <4 x float>
+ ret <4 x float> %t1
+; CHECK: @test65
+; CHECK-NEXT: ret <4 x float> %c
+}
+
+define <2 x float> @test66(<2 x float> %c) nounwind {
+ %t0 = bitcast <2 x float> %c to double
+ %t1 = bitcast double %t0 to <2 x float>
+ ret <2 x float> %t1
+; CHECK: @test66
+; CHECK-NEXT: ret <2 x float> %c
+}
+
+define float @test2c() {
+ ret float extractelement (<2 x float> bitcast (double bitcast (<2 x float> <float -1.000000e+00, float -1.000000e+00> to double) to <2 x float>), i32 0)
+; CHECK: @test2c
+; CHECK-NOT: extractelement
+}
+
+define i64 @test_mmx(<2 x i32> %c) nounwind {
+ %A = bitcast <2 x i32> %c to x86_mmx
+ %B = bitcast x86_mmx %A to <2 x i32>
+ %C = bitcast <2 x i32> %B to i64
+ ret i64 %C
+; CHECK: @test_mmx
+; CHECK-NOT: x86_mmx
+}
+
+define i64 @test_mmx_const(<2 x i32> %c) nounwind {
+ %A = bitcast <2 x i32> zeroinitializer to x86_mmx
+ %B = bitcast x86_mmx %A to <2 x i32>
+ %C = bitcast <2 x i32> %B to i64
+ ret i64 %C
+; CHECK: @test_mmx_const
+; CHECK-NOT: x86_mmx
+}
diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll
index e17774d7b0e27..1a657f53a6076 100644
--- a/test/Transforms/InstCombine/crash.ll
+++ b/test/Transforms/InstCombine/crash.ll
@@ -135,6 +135,8 @@ define void @test5() {
store i1 true, i1* undef
%1 = invoke i32 @test5a() to label %exit unwind label %exit
exit:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
}
@@ -219,6 +221,8 @@ invoke.cont: ; preds = %entry
unreachable
try.handler: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
ret i8* %self
}
diff --git a/test/Transforms/InstCombine/deadcode.ll b/test/Transforms/InstCombine/deadcode.ll
index 52af0ef4e8d4e..7c7f1abc0ca66 100644
--- a/test/Transforms/InstCombine/deadcode.ll
+++ b/test/Transforms/InstCombine/deadcode.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -instcombine -S | grep {ret i32 %A}
-; RUN: opt < %s -die -S | not grep call.*llvm.stacksave
+; RUN: opt < %s -die -S | not grep call.*llvm
define i32 @test(i32 %A) {
%X = or i1 false, false
@@ -22,3 +22,12 @@ define i32* @test2(i32 %width) {
declare i8* @llvm.stacksave()
+declare void @llvm.lifetime.start(i64, i8*)
+declare void @llvm.lifetime.end(i64, i8*)
+
+define void @test3() {
+ call void @llvm.lifetime.start(i64 -1, i8* undef)
+ call void @llvm.lifetime.end(i64 -1, i8* undef)
+ ret void
+}
+
diff --git a/test/Transforms/InstCombine/devirt.ll b/test/Transforms/InstCombine/devirt.ll
new file mode 100644
index 0000000000000..6189dc2af4f94
--- /dev/null
+++ b/test/Transforms/InstCombine/devirt.ll
@@ -0,0 +1,39 @@
+; RUN: opt -instcombine -S -o - %s | FileCheck %s
+
+; CHECK-NOT: getelementptr
+; CHECK-NOT: ptrtoint
+; CHECK: bitcast i8*
+%struct.S = type { i32 (...)** }
+
+@_ZL1p = internal constant { i64, i64 } { i64 1, i64 0 }, align 8
+
+define void @_Z1g1S(%struct.S* %s) nounwind {
+entry:
+ %tmp = load { i64, i64 }* @_ZL1p, align 8
+ %memptr.adj = extractvalue { i64, i64 } %tmp, 1
+ %0 = bitcast %struct.S* %s to i8*
+ %1 = getelementptr inbounds i8* %0, i64 %memptr.adj
+ %this.adjusted = bitcast i8* %1 to %struct.S*
+ %memptr.ptr = extractvalue { i64, i64 } %tmp, 0
+ %2 = and i64 %memptr.ptr, 1
+ %memptr.isvirtual = icmp ne i64 %2, 0
+ br i1 %memptr.isvirtual, label %memptr.virtual, label %memptr.nonvirtual
+
+memptr.virtual: ; preds = %entry
+ %3 = bitcast %struct.S* %this.adjusted to i8**
+ %memptr.vtable = load i8** %3
+ %4 = sub i64 %memptr.ptr, 1
+ %5 = getelementptr i8* %memptr.vtable, i64 %4
+ %6 = bitcast i8* %5 to void (%struct.S*)**
+ %memptr.virtualfn = load void (%struct.S*)** %6
+ br label %memptr.end
+
+memptr.nonvirtual: ; preds = %entry
+ %memptr.nonvirtualfn = inttoptr i64 %memptr.ptr to void (%struct.S*)*
+ br label %memptr.end
+
+memptr.end: ; preds = %memptr.nonvirtual, %memptr.virtual
+ %7 = phi void (%struct.S*)* [ %memptr.virtualfn, %memptr.virtual ], [ %memptr.nonvirtualfn, %memptr.nonvirtual ]
+ call void %7(%struct.S* %this.adjusted)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/extractvalue.ll b/test/Transforms/InstCombine/extractvalue.ll
index 64edc18d45072..cf36b8f237177 100644
--- a/test/Transforms/InstCombine/extractvalue.ll
+++ b/test/Transforms/InstCombine/extractvalue.ll
@@ -96,7 +96,7 @@ define i32 @nogep-multiuse({i32, i32}* %pair) {
}
; CHECK: define i32 @nogep-volatile
-; CHECK-NEXT: volatile load {{.*}} %pair
+; CHECK-NEXT: load volatile {{.*}} %pair
; CHECK-NEXT: extractvalue
; CHECK-NEXT: ret
define i32 @nogep-volatile({i32, i32}* %pair) {
diff --git a/test/Transforms/InstCombine/fcmp.ll b/test/Transforms/InstCombine/fcmp.ll
index 2eb4f058692d9..d08cbf574a231 100644
--- a/test/Transforms/InstCombine/fcmp.ll
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -58,3 +58,14 @@ define i1 @test7(float %x) nounwind readnone ssp noredzone {
; CHECK: @test7
; CHECK-NEXT: fpext float %x to ppc_fp128
}
+
+define float @test8(float %x) nounwind readnone optsize ssp {
+ %conv = fpext float %x to double
+ %cmp = fcmp olt double %conv, 0.000000e+00
+ %conv1 = zext i1 %cmp to i32
+ %conv2 = sitofp i32 %conv1 to float
+ ret float %conv2
+; Float comparison to zero shouldn't cast to double.
+; CHECK: @test8
+; CHECK-NEXT: fcmp olt float %x, 0.000000e+00
+}
diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll
index 26c0e47f4b14a..1c120ecbe9eb7 100644
--- a/test/Transforms/InstCombine/getelementptr.ll
+++ b/test/Transforms/InstCombine/getelementptr.ll
@@ -472,3 +472,23 @@ entry:
; CHECK: @pr10322_f1
; CHECK: %tmp2 = getelementptr inbounds %pr10322_t* %arrayidx8, i64 0, i32 0
}
+
+; Test that we combine the last two geps in this sequence, before we
+; would wait for gep1 and gep2 to be combined and never combine 2 and 3.
+%three_gep_t = type {i32}
+%three_gep_t2 = type {%three_gep_t}
+
+define void @three_gep_f(%three_gep_t2* %x) {
+ %gep1 = getelementptr %three_gep_t2* %x, i64 2
+ call void @three_gep_h(%three_gep_t2* %gep1)
+ %gep2 = getelementptr %three_gep_t2* %gep1, i64 0, i32 0
+ %gep3 = getelementptr %three_gep_t* %gep2, i64 0, i32 0
+ call void @three_gep_g(i32* %gep3)
+
+; CHECK: @three_gep_f
+; CHECK: %gep3 = getelementptr %three_gep_t2* %gep1, i64 0, i32 0, i32 0
+ ret void
+}
+
+declare void @three_gep_g(i32*)
+declare void @three_gep_h(%three_gep_t2*)
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index 0d84ae474388e..f033e510368bd 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -152,9 +152,9 @@ entry:
ret void
; CHECK: @powi
; CHECK: %A = fdiv double 1.0{{.*}}, %V
-; CHECK: volatile store double %A,
-; CHECK: volatile store double 1.0
-; CHECK: volatile store double %V
+; CHECK: store volatile double %A,
+; CHECK: store volatile double 1.0
+; CHECK: store volatile double %V
}
define i32 @cttz(i32 %a) {
@@ -194,11 +194,11 @@ entry:
; CHECK: @cmp.simplify
; CHECK-NEXT: entry:
; CHECK-NEXT: %lz.cmp = icmp eq i32 %a, 0
-; CHECK-NEXT: volatile store i1 %lz.cmp, i1* %c
+; CHECK-NEXT: store volatile i1 %lz.cmp, i1* %c
; CHECK-NEXT: %tz.cmp = icmp ne i32 %a, 0
-; CHECK-NEXT: volatile store i1 %tz.cmp, i1* %c
+; CHECK-NEXT: store volatile i1 %tz.cmp, i1* %c
; CHECK-NEXT: %pop.cmp = icmp eq i32 %b, 0
-; CHECK-NEXT: volatile store i1 %pop.cmp, i1* %c
+; CHECK-NEXT: store volatile i1 %pop.cmp, i1* %c
}
diff --git a/test/Transforms/InstCombine/malloc-free-delete.ll b/test/Transforms/InstCombine/malloc-free-delete.ll
index 8455300c98cad..eae973df0a54a 100644
--- a/test/Transforms/InstCombine/malloc-free-delete.ll
+++ b/test/Transforms/InstCombine/malloc-free-delete.ll
@@ -12,7 +12,7 @@ define i32 @main(i32 %argc, i8** %argv) {
; CHECK: ret i32 0
}
-declare i8* @malloc(i32)
+declare noalias i8* @malloc(i32)
declare void @free(i8*)
define i1 @foo() {
@@ -23,3 +23,26 @@ define i1 @foo() {
call void @free(i8* %m)
ret i1 %z
}
+
+declare void @llvm.lifetime.start(i64, i8*)
+declare void @llvm.lifetime.end(i64, i8*)
+
+define void @test3() {
+; CHECK: @test3
+; CHECK-NEXT: ret void
+ %a = call noalias i8* @malloc(i32 10)
+ call void @llvm.lifetime.start(i64 10, i8* %a)
+ call void @llvm.lifetime.end(i64 10, i8* %a)
+ ret void
+}
+
+;; This used to crash.
+define void @test4() {
+; CHECK: @test4
+; CHECK-NEXT: ret void
+ %A = call i8* @malloc(i32 16000)
+ %B = bitcast i8* %A to double*
+ %C = bitcast double* %B to i8*
+ call void @free(i8* %C)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/nsw.ll b/test/Transforms/InstCombine/nsw.ll
index 681bdc234b7d9..0140c2f801221 100644
--- a/test/Transforms/InstCombine/nsw.ll
+++ b/test/Transforms/InstCombine/nsw.ll
@@ -37,3 +37,47 @@ define i64 @shl1(i64 %X, i64* %P) nounwind {
%B = shl i64 %A, 8
ret i64 %B
}
+
+; CHECK: @preserve1
+; CHECK: add nsw i32 %x, 5
+define i32 @preserve1(i32 %x) nounwind {
+ %add = add nsw i32 %x, 2
+ %add3 = add nsw i32 %add, 3
+ ret i32 %add3
+}
+
+; CHECK: @nopreserve1
+; CHECK: add i8 %x, -126
+define i8 @nopreserve1(i8 %x) nounwind {
+ %add = add nsw i8 %x, 127
+ %add3 = add nsw i8 %add, 3
+ ret i8 %add3
+}
+
+; CHECK: @nopreserve2
+; CHECK: add i8 %x, 3
+define i8 @nopreserve2(i8 %x) nounwind {
+ %add = add i8 %x, 1
+ %add3 = add nsw i8 %add, 2
+ ret i8 %add3
+}
+
+; CHECK: @nopreserve3
+; CHECK: add i8 %A, %B
+; CHECK: add i8
+define i8 @nopreserve3(i8 %A, i8 %B) nounwind {
+ %x = add i8 %A, 10
+ %y = add i8 %B, 10
+ %add = add nsw i8 %x, %y
+ ret i8 %add
+}
+
+; CHECK: @nopreserve4
+; CHECK: add i8 %A, %B
+; CHECK: add i8
+define i8 @nopreserve4(i8 %A, i8 %B) nounwind {
+ %x = add nsw i8 %A, 10
+ %y = add nsw i8 %B, 10
+ %add = add nsw i8 %x, %y
+ ret i8 %add
+}
diff --git a/test/Transforms/InstCombine/ptr-int-cast.ll b/test/Transforms/InstCombine/ptr-int-cast.ll
index ad11e430d9a93..9524d449dd8b0 100644
--- a/test/Transforms/InstCombine/ptr-int-cast.ll
+++ b/test/Transforms/InstCombine/ptr-int-cast.ll
@@ -5,22 +5,22 @@ define i1 @test1(i32 *%x) nounwind {
entry:
; CHECK: test1
; CHECK: ptrtoint i32* %x to i64
- %tmp = ptrtoint i32* %x to i1
- ret i1 %tmp
+ %0 = ptrtoint i32* %x to i1
+ ret i1 %0
}
define i32* @test2(i128 %x) nounwind {
entry:
; CHECK: test2
-; CHECK: inttoptr i64 %tmp1 to i32*
- %tmp = inttoptr i128 %x to i32*
- ret i32* %tmp
+; CHECK: inttoptr i64 %0 to i32*
+ %0 = inttoptr i128 %x to i32*
+ ret i32* %0
}
; PR3574
; CHECK: f0
-; CHECK: %tmp = zext i32 %a0 to i64
-; CHECK: ret i64 %tmp
+; CHECK: %1 = zext i32 %a0 to i64
+; CHECK: ret i64 %1
define i64 @f0(i32 %a0) nounwind {
%t0 = inttoptr i32 %a0 to i8*
%t1 = ptrtoint i8* %t0 to i64
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 4ca9bd2c07c08..46615613eb9c0 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -799,3 +799,13 @@ define i1 @test60(i32 %x, i1* %y) nounwind {
; CHECK: @test60
; CHECK: select
}
+
+@glbl = constant i32 10
+define i32 @test61(i32* %ptr) {
+ %A = load i32* %ptr
+ %B = icmp eq i32* %ptr, @glbl
+ %C = select i1 %B, i32 %A, i32 10
+ ret i32 %C
+; CHECK: @test61
+; CHECK: ret i32 10
+}
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll
index d9ac9cbfe9ee0..132d51a660bbe 100644
--- a/test/Transforms/InstCombine/shift.ll
+++ b/test/Transforms/InstCombine/shift.ll
@@ -525,5 +525,20 @@ define i32 @test43(i32 %a, i32 %b) nounwind {
; CHECK-NEXT: ret
}
-
-
+define i32 @test44(i32 %a) nounwind {
+ %y = shl nuw i32 %a, 1
+ %z = shl i32 %y, 4
+ ret i32 %z
+; CHECK: @test44
+; CHECK-NEXT: %y = shl i32 %a, 5
+; CHECK-NEXT: ret i32 %y
+}
+
+define i32 @test45(i32 %a) nounwind {
+ %y = lshr exact i32 %a, 1
+ %z = lshr i32 %y, 4
+ ret i32 %z
+; CHECK: @test45
+; CHECK-NEXT: %y = lshr i32 %a, 5
+; CHECK-NEXT: ret i32 %y
+}
diff --git a/test/Transforms/InstCombine/vec_demanded_elts.ll b/test/Transforms/InstCombine/vec_demanded_elts.ll
index e0188fe91aeb2..cc63371eded67 100644
--- a/test/Transforms/InstCombine/vec_demanded_elts.ll
+++ b/test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -152,3 +152,14 @@ entry:
ret <4 x i32> %0
}
declare <4 x i32> @llvm.x86.sse41.pmovzxwd(<8 x i16>) nounwind readnone
+
+define <4 x float> @dead_shuffle_elt(<4 x float> %x, <2 x float> %y) nounwind {
+entry:
+; CHECK: define <4 x float> @dead_shuffle_elt
+; CHECK: shufflevector <2 x float> %y, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
+ %shuffle.i = shufflevector <2 x float> %y, <2 x float> %y, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+ %shuffle9.i = shufflevector <4 x float> %x, <4 x float> %shuffle.i, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
+ ret <4 x float> %shuffle9.i
+}
+
+
diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll
index e931dc79ef413..7bbf53c270f48 100644
--- a/test/Transforms/InstCombine/vector-casts.ll
+++ b/test/Transforms/InstCombine/vector-casts.ll
@@ -7,7 +7,7 @@ define <2 x i1> @test1(<2 x i64> %a) {
; CHECK: @test1
; CHECK: and <2 x i64> %a, <i64 1, i64 1>
-; CHECK: icmp ne <2 x i64> %tmp, zeroinitializer
+; CHECK: icmp ne <2 x i64> %1, zeroinitializer
}
; The ashr turns into an lshr.
diff --git a/test/Transforms/InstCombine/volatile_store.ll b/test/Transforms/InstCombine/volatile_store.ll
index 5316bd772e13a..0518e5aa02629 100644
--- a/test/Transforms/InstCombine/volatile_store.ll
+++ b/test/Transforms/InstCombine/volatile_store.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -instcombine -S | grep {volatile store}
-; RUN: opt < %s -instcombine -S | grep {volatile load}
+; RUN: opt < %s -instcombine -S | grep {store volatile}
+; RUN: opt < %s -instcombine -S | grep {load volatile}
@x = weak global i32 0 ; <i32*> [#uses=2]
diff --git a/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll b/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll
new file mode 100644
index 0000000000000..d10c61fe2cf77
--- /dev/null
+++ b/test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+declare void @bar()
+
+define void @test1() {
+entry:
+ invoke void @bar() to label %cont unwind label %lpad
+cont:
+ ret void
+lpad:
+ %ex = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 cleanup
+ %exc_ptr = extractvalue { i8*, i32 } %ex, 0
+ %filter = extractvalue { i8*, i32 } %ex, 1
+ %exc_ptr2 = insertvalue { i8*, i32 } undef, i8* %exc_ptr, 0
+ %filter2 = insertvalue { i8*, i32 } %exc_ptr2, i32 %filter, 1
+ resume { i8*, i32 } %filter2
+; CHECK: @test1
+; CHECK-NOT: extractvalue
+; CHECK-NOT: insertvalue
+}
+
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+
+define { i8, i32 } @test2({ i8*, i32 } %x) {
+ %ex = extractvalue { i8*, i32 } %x, 1
+ %ins = insertvalue { i8, i32 } undef, i32 %ex, 1
+ ret { i8, i32 } %ins
+; CHECK: @test2
+}
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index d2c564f567b44..2cbd641a7426f 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -283,17 +283,6 @@ define i1 @srem3(i16 %X, i32 %Y) {
ret i1 %E
}
-; CHECK: @srem4
-; CHECK-NEXT: ret i1 false
-define i1 @srem4(i16 %X, i32 %Y) {
- %A = zext i16 %X to i32
- %B = or i32 2147483648, %A
- %C = sub nsw i32 %A, %B
- %D = srem i32 %C, %Y
- %E = icmp slt i32 %D, 0
- ret i1 %E
-}
-
define i1 @udiv1(i32 %X) {
; CHECK: @udiv1
%A = udiv i32 %X, 1000000
diff --git a/test/Transforms/JumpThreading/no-irreducible-loops.ll b/test/Transforms/JumpThreading/no-irreducible-loops.ll
index 97276b039aaab..7c7fe3929ae02 100644
--- a/test/Transforms/JumpThreading/no-irreducible-loops.ll
+++ b/test/Transforms/JumpThreading/no-irreducible-loops.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -jump-threading -loop-rotate -instcombine -indvars -loop-unroll -simplifycfg -S -verify-dom-info -verify-loop-info > %t
-; RUN: grep {volatile store} %t | count 3
+; RUN: grep {store volatile} %t | count 3
; RUN: not grep {br label} %t
; Jump threading should not prevent this loop from being unrolled.
diff --git a/test/Transforms/LCSSA/invoke-dest.ll b/test/Transforms/LCSSA/invoke-dest.ll
index 454715089c3b6..22b320296afd8 100644
--- a/test/Transforms/LCSSA/invoke-dest.ll
+++ b/test/Transforms/LCSSA/invoke-dest.ll
@@ -110,12 +110,18 @@ bb106: ; preds = %invcont105, %bb61
to label %.noexc unwind label %lpad119 ; <i8*> [#uses=1]
lpad: ; preds = %_ZN7cObjectnwEj.exit
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
br label %Unwind
lpad119: ; preds = %bb106, %invcont104, %invcont103, %bb102, %bb49, %bb34, %bb12, %invcont10, %invcont9, %bb8
+ %exn119 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
lpad123: ; preds = %.noexc
+ %exn123 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
%tmp5 = icmp eq i8* %tmp4, null ; <i1> [#uses=1]
br i1 %tmp5, label %Unwind, label %bb.i2
@@ -126,6 +132,8 @@ Unwind: ; preds = %bb.i2, %lpad123, %lpad
unreachable
}
+declare i32 @__gxx_personality_v0(...)
+
declare void @_ZN8EtherBus8tokenizeEPKcRSt6vectorIdSaIdEE(i8* nocapture, i8*, i8*)
declare i8* @_Znaj(i32)
diff --git a/test/Transforms/LICM/2007-05-22-VolatileSink.ll b/test/Transforms/LICM/2007-05-22-VolatileSink.ll
index c12e13beccf59..17383c2ebb631 100644
--- a/test/Transforms/LICM/2007-05-22-VolatileSink.ll
+++ b/test/Transforms/LICM/2007-05-22-VolatileSink.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -licm -S | grep {volatile store}
+; RUN: opt < %s -licm -S | grep {store volatile}
; PR1435
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"
diff --git a/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll b/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll
index 5774f587f1c3d..fd114f4ccc114 100644
--- a/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll
+++ b/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll
@@ -15,7 +15,7 @@ for.body4.lr.ph:
br label %for.body4
; CHECK: for.body4:
-; CHECK: volatile load i16* @g_39
+; CHECK: load volatile i16* @g_39
for.body4:
%l_612.11 = phi i32* [ undef, %for.body4.lr.ph ], [ %call19, %for.body4 ]
diff --git a/test/Transforms/LICM/atomics.ll b/test/Transforms/LICM/atomics.ll
new file mode 100644
index 0000000000000..3902152ba2e5e
--- /dev/null
+++ b/test/Transforms/LICM/atomics.ll
@@ -0,0 +1,79 @@
+; RUN: opt < %s -S -basicaa -licm | FileCheck %s
+
+; Check that we can hoist unordered loads
+define i32 @test1(i32* nocapture %y) nounwind uwtable ssp {
+entry:
+ br label %loop
+
+loop:
+ %i = phi i32 [ %inc, %loop ], [ 0, %entry ]
+ %val = load atomic i32* %y unordered, align 4
+ %inc = add nsw i32 %i, 1
+ %exitcond = icmp eq i32 %inc, %val
+ br i1 %exitcond, label %end, label %loop
+
+end:
+ ret i32 %val
+; CHECK: define i32 @test1(
+; CHECK: load atomic
+; CHECK-NEXT: br label %loop
+}
+
+; Check that we don't sink/hoist monotonic loads
+; (Strictly speaking, it's not forbidden, but it's supposed to be possible to
+; use monotonic for spinlock-like constructs.)
+define i32 @test2(i32* nocapture %y) nounwind uwtable ssp {
+entry:
+ br label %loop
+
+loop:
+ %val = load atomic i32* %y monotonic, align 4
+ %exitcond = icmp ne i32 %val, 0
+ br i1 %exitcond, label %end, label %loop
+
+end:
+ ret i32 %val
+; CHECK: define i32 @test2(
+; CHECK: load atomic
+; CHECK-NEXT: %exitcond = icmp ne
+; CHECK-NEXT: br i1 %exitcond, label %end, label %loop
+}
+
+; Check that we hoist unordered around monotonic.
+; (The noalias shouldn't be necessary in theory, but LICM isn't quite that
+; smart yet.)
+define i32 @test3(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
+entry:
+ br label %loop
+
+loop:
+ %vala = load atomic i32* %y monotonic, align 4
+ %valb = load atomic i32* %x unordered, align 4
+ %exitcond = icmp ne i32 %vala, %valb
+ br i1 %exitcond, label %end, label %loop
+
+end:
+ ret i32 %vala
+; CHECK: define i32 @test3(
+; CHECK: load atomic i32* %x unordered
+; CHECK-NEXT: br label %loop
+}
+
+; Don't try to "sink" unordered stores yet; it is legal, but the machinery
+; isn't there.
+define i32 @test4(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
+entry:
+ br label %loop
+
+loop:
+ %vala = load atomic i32* %y monotonic, align 4
+ store atomic i32 %vala, i32* %x unordered, align 4
+ %exitcond = icmp ne i32 %vala, 0
+ br i1 %exitcond, label %end, label %loop
+
+end:
+ ret i32 %vala
+; CHECK: define i32 @test4(
+; CHECK: load atomic i32* %y monotonic
+; CHECK-NEXT: store atomic
+}
diff --git a/test/Transforms/LICM/scalar-promote-memmodel.ll b/test/Transforms/LICM/scalar-promote-memmodel.ll
new file mode 100644
index 0000000000000..23d70f51351a5
--- /dev/null
+++ b/test/Transforms/LICM/scalar-promote-memmodel.ll
@@ -0,0 +1,37 @@
+; RUN: opt < %s -basicaa -licm -S | FileCheck %s
+
+; Make sure we don't hoist a conditionally-executed store out of the loop;
+; it would violate the concurrency memory model
+
+@g = common global i32 0, align 4
+
+define void @bar(i32 %n, i32 %b) nounwind uwtable ssp {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tobool = icmp eq i32 %b, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %tmp3 = load i32* @g, align 4
+ %inc = add nsw i32 %tmp3, 1
+ store i32 %inc, i32* @g, align 4
+ br label %for.inc
+
+; CHECK: load i32*
+; CHECK-NEXT: add
+; CHECK-NEXT: store i32
+
+for.inc: ; preds = %for.body, %if.then
+ %inc5 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
diff --git a/test/Transforms/LICM/scalar_promote.ll b/test/Transforms/LICM/scalar_promote.ll
index d8acdc1a3ad75..9aefc4f87eac8 100644
--- a/test/Transforms/LICM/scalar_promote.ll
+++ b/test/Transforms/LICM/scalar_promote.ll
@@ -65,7 +65,7 @@ Loop:
br i1 true, label %Out, label %Loop
; CHECK: Loop:
-; CHECK-NEXT: volatile load
+; CHECK-NEXT: load volatile
Out: ; preds = %Loop
ret void
diff --git a/test/Transforms/LoopDeletion/2008-05-06-Phi.ll b/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
index 4fc6378ee254a..ff6a30d3a3427 100644
--- a/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
+++ b/test/Transforms/LoopDeletion/2008-05-06-Phi.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -inline -tailduplicate -instcombine -jump-threading -licm -loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -verify -disable-output
+; RUN: opt < %s -inline -instcombine -jump-threading -licm -loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -verify -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-f80:128:128"
target triple = "i386-apple-darwin9"
diff --git a/test/Transforms/LoopIdiom/basic.ll b/test/Transforms/LoopIdiom/basic.ll
index 969541813aef4..46ab7e5542b6b 100644
--- a/test/Transforms/LoopIdiom/basic.ll
+++ b/test/Transforms/LoopIdiom/basic.ll
@@ -62,8 +62,8 @@ for.end: ; preds = %for.body, %entry
ret void
; CHECK: @test2
; CHECK: br i1 %cmp10,
-; CHECK: %tmp = mul i64 %Size, 4
-; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base1, i8 1, i64 %tmp, i32 4, i1 false)
+; CHECK: %0 = mul i64 %Size, 4
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base1, i8 1, i64 %0, i32 4, i1 false)
; CHECK-NOT: store
}
diff --git a/test/Transforms/LoopSimplify/2003-08-15-PreheadersFail.ll b/test/Transforms/LoopSimplify/2003-08-15-PreheadersFail.ll
index 11be6941d8b82..73f0813285bac 100644
--- a/test/Transforms/LoopSimplify/2003-08-15-PreheadersFail.ll
+++ b/test/Transforms/LoopSimplify/2003-08-15-PreheadersFail.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -tailduplicate -instcombine -simplifycfg -licm -disable-output
+; RUN: opt < %s -instcombine -simplifycfg -licm -disable-output
target datalayout = "e-p:32:32"
@yy_base = external global [787 x i16] ; <[787 x i16]*> [#uses=1]
@yy_state_ptr = external global i32* ; <i32**> [#uses=3]
diff --git a/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll b/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll
index e7d0f8470ec96..e91d141cc6fff 100644
--- a/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll
+++ b/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll
@@ -1,892 +1,29 @@
-; RUN: opt < %s -loop-simplify -disable-output
+; RUN: llvm-as < %s | opt -loop-simplify -disable-output
; PR1752
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-s0:0:64-f80:32:32"
target triple = "i686-pc-mingw32"
- %struct.BigInt = type { %"struct.std::vector<ulong,std::allocator<ulong> >" }
- %struct.Fibonacci = type { %"struct.std::vector<BigInt,std::allocator<BigInt> >" }
- %struct.__false_type = type <{ i8 }>
- %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >" = type { %struct.BigInt* }
- %"struct.std::_Vector_base<BigInt,std::allocator<BigInt> >" = type { %"struct.std::_Vector_base<BigInt,std::allocator<BigInt> >::_Vector_impl" }
- %"struct.std::_Vector_base<BigInt,std::allocator<BigInt> >::_Vector_impl" = type { %struct.BigInt*, %struct.BigInt*, %struct.BigInt* }
- %"struct.std::_Vector_base<ulong,std::allocator<ulong> >" = type { %"struct.std::_Vector_base<ulong,std::allocator<ulong> >::_Vector_impl" }
- %"struct.std::_Vector_base<ulong,std::allocator<ulong> >::_Vector_impl" = type { i32*, i32*, i32* }
- %"struct.std::basic_ios<char,std::char_traits<char> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8, i8, %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, %"struct.std::ctype<char>"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"* }
- %"struct.std::basic_ostream<char,std::char_traits<char> >" = type { i32 (...)**, %"struct.std::basic_ios<char,std::char_traits<char> >" }
- %"struct.std::basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" }
- %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider" }
- %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider" = type { i8* }
- %"struct.std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.std::basic_streambuf<char,std::char_traits<char> >", i32, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" }
- %"struct.std::ctype<char>" = type { %"struct.std::locale::facet", i32*, i8, i32*, i32*, i16*, i8, [256 x i8], [256 x i8], i8 }
- %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" }
- %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 }
- %"struct.std::ios_base::_Words" = type { i8*, i32 }
- %"struct.std::locale" = type { %"struct.std::locale::_Impl"* }
- %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** }
- %"struct.std::locale::facet" = type { i32 (...)**, i32 }
- %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
- %"struct.std::ostringstream" = type { [4 x i8], %"struct.std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char> >", %"struct.std::basic_ios<char,std::char_traits<char> >" }
- %"struct.std::vector<BigInt,std::allocator<BigInt> >" = type { %"struct.std::_Vector_base<BigInt,std::allocator<BigInt> >" }
- %"struct.std::vector<ulong,std::allocator<ulong> >" = type { %"struct.std::_Vector_base<ulong,std::allocator<ulong> >" }
-@.str13 = external constant [6 x i8] ; <[6 x i8]*> [#uses=1]
-@.str14 = external constant [5 x i8] ; <[5 x i8]*> [#uses=1]
-@.str15 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1]
-@_ZSt4cout = external global %"struct.std::basic_ostream<char,std::char_traits<char> >" ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=1]
-declare void @_ZN9Fibonacci10get_numberEj(%struct.BigInt* sret , %struct.Fibonacci*, i32)
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8*)
-
-declare void @_ZNSsD1Ev(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"*)
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSolsEm(%"struct.std::basic_ostream<char,std::char_traits<char> >"*, i32)
-
-declare void @_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* sret , %"struct.std::ostringstream"*)
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E(%"struct.std::basic_ostream<char,std::char_traits<char> >"*, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"*)
-
-declare void @_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev(%"struct.std::ostringstream"*)
-
-declare %"struct.std::basic_ostream<char,std::char_traits<char> >"* @___ZlsRSoRK6BigInt___ZN9__gnu_cxx13new_allocatorI6BigIntE10deallocateEPS1_j(i32, %"struct.std::basic_ostream<char,std::char_traits<char> >"*, %struct.BigInt*, %struct.__false_type*, i32)
-
-declare void @___ZNSt12_Vector_baseI6BigIntSaIS0_EE13_M_deallocateEPS0_j___ZNSt12_Vector_baseI6BigIntSaIS0_EED2Ev___ZNSt6vectorI6BigIntSaIS0_EEC1ERKS1_(%"struct.std::_Vector_base<BigInt,std::allocator<BigInt> >"*, i32, %struct.BigInt*, i32, %"struct.std::vector<BigInt,std::allocator<BigInt> >"*, %struct.__false_type*)
-
-declare i32 @___ZN9__gnu_cxxmiIPK6BigIntS3_St6vectorIS1_SaIS1_EEEENS_17__normal_iteratorIT_T1_E15difference_typeERKSA_RKNS7_IT0_S9_EE___ZNKSt6vectorI6BigIntSaIS0_EE4sizeEv___ZNK9Fibonacci16show_all_numbersEv___ZNKSt6vectorI6BigIntSaIS0_EE8capacityEv(%"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"*, %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"*, %"struct.std::vector<BigInt,std::allocator<BigInt> >"*, i32, %struct.Fibonacci*)
-
-declare %struct.BigInt* @___ZNSt6vectorI6BigIntSaIS0_EEixEj___ZNSt6vectorI6BigIntSaIS0_EE3endEv(%"struct.std::vector<BigInt,std::allocator<BigInt> >"*, i32, i32)
-
-declare %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* @___ZN9__gnu_cxx17__normal_iteratorIP6BigIntSt6vectorIS1_SaIS1_EEEppEv___ZNSt6vectorImSaImEED1Ev___ZN6BigIntD1Ev___ZN9__gnu_cxx13new_allocatorI6BigIntE7destroyEPS1____ZSt8_DestroyIP6BigIntSaIS0_EEvT_S3_T0_(i32, %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"*, %"struct.std::vector<ulong,std::allocator<ulong> >"*, %struct.BigInt*, %struct.__false_type*, %struct.BigInt*, %struct.__false_type* noalias )
-
-declare void @___ZNSt6vectorI6BigIntSaIS0_EED1Ev___ZN9FibonacciD1Ev___ZNSt6vectorImSaImEEC1ERKS0_(i32, %"struct.std::vector<BigInt,std::allocator<BigInt> >"*, %struct.Fibonacci*, %"struct.std::vector<ulong,std::allocator<ulong> >"*, %struct.__false_type*)
-
-define void @___ZN9FibonacciC1Ej___ZN9Fibonacci11show_numberEm(%struct.Fibonacci* %this_this, i32 %functionID, i32 %n_i_n_i) {
+define void @func() {
bb_init:
br label %bb_main
-bb_main: ; preds = %meshBB349, %meshBB348, %meshBB347, %meshBB346, %meshBB345.unwinddest, %meshBB345, %meshBB344, %meshBB343, %meshBB342, %meshBB341, %meshBB340.normaldest, %meshBB340, %meshBB339, %invcont17.normaldest.normaldest, %invcont17.normaldest, %meshBB338.unwinddest, %meshBB338, %meshBB337.unwinddest, %meshBB337, %meshBB336.unwinddest, %meshBB336, %meshBB335, %meshBB334, %meshBB333, %meshBB332, %meshBB331, %meshBB330.normaldest, %meshBB330, %meshBB329.normaldest, %meshBB329, %meshBB328, %meshBB327, %meshBB326, %meshBB325.unwinddest, %meshBB325, %meshBB324, %meshBB323.normaldest, %meshBB323, %meshBB322.unwinddest, %meshBB322, %meshBB321, %meshBB320.unwinddest, %meshBB320, %meshBB319.unwinddest, %meshBB319, %meshBB318.unwinddest, %meshBB318, %meshBB317, %meshBB37.fragment, %meshBB37.unwinddest, %meshBB37, %meshBB36.fragment, %meshBB36, %meshBB35.fragment, %meshBB35, %meshBB34.fragment, %meshBB34, %meshBB33.fragment, %meshBB33, %meshBB32.fragment, %meshBB32, %meshBB31.fragment, %meshBB31, %meshBB30.fragment, %meshBB30.normaldest, %meshBB30, %meshBB29.fragment, %meshBB29.unwinddest, %meshBB29, %meshBB28.fragment, %meshBB28.unwinddest, %meshBB28, %meshBB27.fragment, %meshBB27, %meshBB26.fragment, %meshBB26.normaldest, %meshBB26, %meshBB25.fragment, %meshBB25, %meshBB24.fragment, %meshBB24.unwinddest, %meshBB24, %meshBB23.fragment, %meshBB23.normaldest, %meshBB23, %entry1.fragment.normaldest.normaldest, %entry1.fragment.normaldest, %meshBB22.fragment, %meshBB22.unwinddest, %meshBB22, %meshBB.fragment, %meshBB.unwinddest, %meshBB, %Unwind20, %unwind78.Unwind_crit_edge, %unwind78.fragment.fragment, %unwind78.fragment, %unwind78.fragment316, %unwind78, %invcont70, %unwind66.Unwind_crit_edge, %unwind66.fragment.fragment, %unwind66.fragment, %unwind66.fragment315, %unwind66, %unwind53.nofilter_crit_edge, %unwind53.fragment.fragment, %unwind53.fragment, %unwind53.fragment314, %unwind53, %nofilter.Unwind_crit_edge.normaldest, %nofilter.Unwind_crit_edge, %nofilter, %unwind43.nofilter_crit_edge, %unwind43.fragment.fragment, %unwind43.fragment, %unwind43.fragment313, %unwind43, %invcont41.normaldest, %invcont41, %unwind37.nofilter_crit_edge, %unwind37, %invcont36, %invcont33.unwind_crit_edge.unwinddest, %invcont33.unwind_crit_edge, %invcont30.unwind_crit_edge.unwinddest, %invcont30.unwind_crit_edge, %invcont30.normaldest, %invcont30, %invcont28.unwind_crit_edge, %invcont28.normaldest, %invcont28, %invcont25.unwind_crit_edge.unwinddest, %invcont25.unwind_crit_edge, %invcont25, %invcont22.unwind_crit_edge, %invcont22, %invcont17.unwind_crit_edge, %invcont17, %cond_next.unwind_crit_edge, %cond_next, %invcont12.cond_next_crit_edge, %invcont12.unwind_crit_edge, %invcont12, %cond_true.unwind_crit_edge.unwinddest, %cond_true.unwind_crit_edge, %invcont.cond_next_crit_edge, %invcont16.fragment, %invcont16, %unwind11.fragment, %unwind11, %entry.unwind_crit_edge, %entry1.fragment, %entry1.fragment312, %entry1, %Unwind, %unwind20.Unwind_crit_edge, %unwind20.fragment.fragment, %unwind20.fragment, %unwind20.fragment311, %unwind20, %invcont15, %invcont14.unwind10_crit_edge, %invcont14, %unwind10.Unwind_crit_edge, %unwind10.fragment, %unwind10.fragment310, %unwind10, %invcont.unwind10_crit_edge, %invcont, %unwind.fragment, %unwind, %entry.fragment, %entry.fragment309, %entry, %NewDefault, %LeafBlock, %LeafBlock914, %NodeBlock, %comb_entry.fragment, %old_entry, %bb_init
- switch i32 0, label %old_entry [
- i32 2739, label %invcont28.fragment
- i32 2688, label %meshBB28.fragment
- i32 1318, label %meshBB32.fragment
- i32 2964, label %unwind53.fragment.fragment
- i32 824, label %unwind78.fragment.fragment
- i32 1983, label %meshBB33.fragment
- i32 2582, label %invcont30.fragment
- i32 2235, label %meshBB36.fragment
- i32 1275, label %meshBB343
- i32 2719, label %invcont.fragment
- i32 1500, label %entry1.fragment.fragment
- i32 815, label %unwind11.fragment
- i32 1051, label %entry
- i32 2342, label %unwind
- i32 1814, label %invcont
- i32 315, label %invcont.unwind10_crit_edge
- i32 2422, label %unwind10
- i32 2663, label %unwind10.Unwind_crit_edge
- i32 266, label %invcont14
- i32 367, label %invcont14.unwind10_crit_edge
- i32 2242, label %invcont15
- i32 452, label %unwind20
- i32 419, label %invcont.cond_next_crit_edge
- i32 181, label %cond_true
- i32 2089, label %unwind20.Unwind_crit_edge
- i32 633, label %filter
- i32 455, label %Unwind
- i32 2016, label %entry1
- i32 263, label %invcont33.unwind_crit_edge
- i32 2498, label %invcont36
- i32 2992, label %unwind37
- i32 616, label %entry.unwind_crit_edge
- i32 622, label %unwind11
- i32 875, label %invcont16
- i32 766, label %unwind53.nofilter_crit_edge
- i32 668, label %filter62
- i32 2138, label %unwind66
- i32 713, label %unwind66.Unwind_crit_edge
- i32 1422, label %invcont70
- i32 1976, label %cond_true.unwind_crit_edge
- i32 1263, label %invcont12
- i32 2453, label %invcont12.unwind_crit_edge
- i32 2876, label %invcont12.cond_next_crit_edge
- i32 2271, label %cond_next
- i32 2938, label %cond_next.unwind_crit_edge
- i32 1082, label %invcont17
- i32 531, label %invcont17.unwind_crit_edge
- i32 111, label %invcont22
- i32 1935, label %invcont22.unwind_crit_edge
- i32 2004, label %invcont25
- i32 1725, label %invcont25.unwind_crit_edge
- i32 1701, label %invcont28
- i32 957, label %invcont28.unwind_crit_edge
- i32 165, label %invcont30
- i32 899, label %invcont30.unwind_crit_edge
- i32 1092, label %invcont33
- i32 2869, label %unwind37.nofilter_crit_edge
- i32 203, label %invcont41
- i32 693, label %unwind43
- i32 2895, label %unwind43.nofilter_crit_edge
- i32 1174, label %invcont47
- i32 1153, label %filter19
- i32 2304, label %nofilter
- i32 848, label %nofilter.Unwind_crit_edge
- i32 1207, label %unwind53
- i32 2848, label %filter75
- i32 59, label %unwind78
- i32 1213, label %unwind78.Unwind_crit_edge
- i32 2199, label %filter87
- i32 1268, label %Unwind20
- i32 743, label %old_entry
- i32 1276, label %meshBB319
- i32 1619, label %meshBB320
- i32 2047, label %meshBB331
- i32 2828, label %meshBB23.fragment
- i32 2530, label %meshBB332
- i32 1389, label %meshBB318
- i32 1450, label %meshBB317
- i32 1416, label %meshBB31.fragment
- i32 82, label %meshBB322
- i32 853, label %unwind78.fragment316
- i32 107, label %meshBB24.fragment
- i32 1200, label %meshBB37.fragment
- i32 605, label %unwind53.fragment314
- i32 209, label %meshBB29.fragment
- i32 1513, label %meshBB27.fragment
- i32 1542, label %meshBB35.fragment
- i32 1873, label %meshBB348
- i32 472, label %meshBB325
- i32 2615, label %meshBB22.fragment
- i32 359, label %meshBB.fragment
- i32 2467, label %Unwind20.fragment
- i32 1671, label %unwind66.fragment.fragment
- i32 1006, label %meshBB25.fragment
- i32 1243, label %meshBB333
- i32 2795, label %unwind43.fragment313
- i32 1591, label %meshBB335
- i32 773, label %meshBB341
- i32 2440, label %cond_next.fragment
- i32 487, label %meshBB326
- i32 394, label %meshBB324
- i32 14, label %invcont16.fragment
- i32 574, label %entry1.fragment312
- i32 1453, label %meshBB35
- i32 345, label %entry1.fragment
- i32 2951, label %unwind20.fragment
- i32 1960, label %meshBB31
- i32 2163, label %meshBB32
- i32 1978, label %Unwind.fragment
- i32 1559, label %unwind20.fragment.fragment
- i32 950, label %unwind10.fragment
- i32 1724, label %unwind53.fragment
- i32 514, label %meshBB36
- i32 1928, label %unwind10.fragment.fragment
- i32 1266, label %meshBB26
- i32 3148, label %unwind20.fragment311
- i32 1581, label %unwind43.fragment
- i32 1829, label %meshBB34
- i32 1472, label %meshBB28
- i32 2657, label %unwind66.fragment
- i32 2169, label %meshBB22
- i32 2619, label %meshBB
- i32 1397, label %entry.fragment
- i32 231, label %invcont41.fragment
- i32 2557, label %meshBB338
- i32 2387, label %meshBB30.fragment
- i32 2927, label %meshBB340
- i32 2331, label %meshBB321
- i32 47, label %meshBB328
- i32 1753, label %meshBB342
- i32 2074, label %meshBB323
- i32 2128, label %meshBB334
- i32 2396, label %meshBB337
- i32 1811, label %meshBB29
- i32 1113, label %meshBB27
- i32 2232, label %unwind10.fragment310
- i32 804, label %meshBB24
- i32 3099, label %meshBB30
- i32 564, label %meshBB33
- i32 1359, label %unwind.fragment
- i32 1906, label %entry.fragment309
- i32 2644, label %entry.fragment.fragment
- i32 134, label %entry1.fragment.normaldest
- i32 2767, label %comb_entry.fragment
- i32 2577, label %meshBB25
- i32 3128, label %meshBB37
- i32 2360, label %meshBB23
- i32 286, label %unwind78.fragment
- i32 976, label %meshBB346
- i32 2412, label %meshBB339
- i32 876, label %meshBB345
- i32 3078, label %meshBB329
- i32 1297, label %meshBB347
- i32 3051, label %meshBB336
- i32 1342, label %meshBB344
- i32 728, label %meshBB330
- i32 1778, label %meshBB349
- i32 2784, label %meshBB327
- i32 1854, label %meshBB26.fragment
- i32 1025, label %meshBB34.fragment
- i32 2139, label %unwind43.fragment.fragment
- i32 2217, label %nofilter.fragment
- i32 665, label %invcont12.fragment
- i32 316, label %invcont22.fragment
- i32 1467, label %unwind66.fragment315
- i32 3018, label %unwind37.fragment
- i32 1123, label %invcont17.normaldest
- i32 2104, label %NewDefault
- i32 1639, label %LeafBlock
- i32 925, label %LeafBlock914
- i32 2880, label %NodeBlock
- ]
-
-old_entry: ; preds = %bb_main, %bb_main
- br label %bb_main
-
-comb_entry.fragment: ; preds = %bb_main
- br label %bb_main
-
-NodeBlock: ; preds = %bb_main
- br label %bb_main
-
-LeafBlock914: ; preds = %bb_main
- br label %bb_main
-
-LeafBlock: ; preds = %bb_main
- br label %bb_main
-
-NewDefault: ; preds = %bb_main
- br label %bb_main
-
-entry: ; preds = %bb_main
- br label %bb_main
-
-entry.fragment309: ; preds = %bb_main
- br label %bb_main
-
-entry.fragment: ; preds = %bb_main
- br label %bb_main
-
-entry.fragment.fragment: ; preds = %bb_main
- invoke void @___ZNSt12_Vector_baseI6BigIntSaIS0_EE13_M_deallocateEPS0_j___ZNSt12_Vector_baseI6BigIntSaIS0_EED2Ev___ZNSt6vectorI6BigIntSaIS0_EEC1ERKS1_( %"struct.std::_Vector_base<BigInt,std::allocator<BigInt> >"* null, i32 28, %struct.BigInt* null, i32 0, %"struct.std::vector<BigInt,std::allocator<BigInt> >"* null, %struct.__false_type* null )
- to label %meshBB340 unwind label %meshBB325
-
-unwind: ; preds = %bb_main
- br label %bb_main
-
-unwind.fragment: ; preds = %bb_main
- br label %bb_main
-
-invcont: ; preds = %bb_main
- br label %bb_main
-
-invcont.fragment: ; preds = %bb_main
- invoke void @_ZN9Fibonacci10get_numberEj( %struct.BigInt* sret null , %struct.Fibonacci* %this_this, i32 %n_i_n_i )
- to label %invcont14 unwind label %meshBB37
-
-invcont.unwind10_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-unwind10: ; preds = %bb_main
- br label %bb_main
-
-unwind10.fragment310: ; preds = %bb_main
- br label %bb_main
-
-unwind10.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind10.fragment.fragment: ; preds = %bb_main
- invoke void @___ZNSt6vectorI6BigIntSaIS0_EED1Ev___ZN9FibonacciD1Ev___ZNSt6vectorImSaImEEC1ERKS0_( i32 57, %"struct.std::vector<BigInt,std::allocator<BigInt> >"* null, %struct.Fibonacci* null, %"struct.std::vector<ulong,std::allocator<ulong> >"* null, %struct.__false_type* null )
- to label %meshBB329 unwind label %meshBB24
-
-unwind10.Unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont14: ; preds = %invcont.fragment, %bb_main
- br label %bb_main
-
-invcont14.normaldest: ; No predecessors!
- invoke %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* @___ZN9__gnu_cxx17__normal_iteratorIP6BigIntSt6vectorIS1_SaIS1_EEEppEv___ZNSt6vectorImSaImEED1Ev___ZN6BigIntD1Ev___ZN9__gnu_cxx13new_allocatorI6BigIntE7destroyEPS1____ZSt8_DestroyIP6BigIntSaIS0_EEvT_S3_T0_( i32 14, %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* null, %"struct.std::vector<ulong,std::allocator<ulong> >"* null, %struct.BigInt* null, %struct.__false_type* null, %struct.BigInt* null, %struct.__false_type* noalias null )
- to label %invcont15 unwind label %meshBB345 ; <%"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"*>:0 [#uses=0]
-
-invcont14.unwind10_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont15: ; preds = %invcont14.normaldest, %bb_main
- br label %bb_main
-
-invcont15.normaldest: ; No predecessors!
- br label %UnifiedReturnBlock
-
-unwind20: ; preds = %bb_main
- br label %bb_main
-
-unwind20.fragment311: ; preds = %bb_main
- br label %bb_main
-
-unwind20.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind20.fragment.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind20.Unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-filter: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-Unwind: ; preds = %bb_main
- br label %bb_main
-
-Unwind.fragment: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-entry1: ; preds = %bb_main
- br label %bb_main
-
-entry1.fragment312: ; preds = %bb_main
- br label %bb_main
-
-entry1.fragment: ; preds = %bb_main
- br label %bb_main
-
-entry1.fragment.fragment: ; preds = %bb_main
- %tmp52 = invoke i32 @___ZN9__gnu_cxxmiIPK6BigIntS3_St6vectorIS1_SaIS1_EEEENS_17__normal_iteratorIT_T1_E15difference_typeERKSA_RKNS7_IT0_S9_EE___ZNKSt6vectorI6BigIntSaIS0_EE4sizeEv___ZNK9Fibonacci16show_all_numbersEv___ZNKSt6vectorI6BigIntSaIS0_EE8capacityEv( %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* null, %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* null, %"struct.std::vector<BigInt,std::allocator<BigInt> >"* null, i32 16, %struct.Fibonacci* null )
- to label %entry1.fragment.normaldest unwind label %meshBB320 ; <i32> [#uses=0]
-
-entry.unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-unwind11: ; preds = %bb_main
- br label %bb_main
-
-unwind11.fragment: ; preds = %bb_main
- br label %bb_main
-
-invcont16: ; preds = %bb_main
- br label %bb_main
-
-invcont16.fragment: ; preds = %bb_main
- br label %bb_main
-
-invcont.cond_next_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-cond_true: ; preds = %bb_main
- invoke void @_ZN9Fibonacci10get_numberEj( %struct.BigInt* sret null , %struct.Fibonacci* %this_this, i32 %n_i_n_i )
- to label %meshBB323 unwind label %cond_true.unwind_crit_edge
-
-cond_true.unwind_crit_edge: ; preds = %cond_true, %bb_main
- br label %bb_main
-
-cond_true.unwind_crit_edge.unwinddest: ; No predecessors!
- br label %bb_main
-
-invcont12: ; preds = %bb_main
- br label %bb_main
-
-invcont12.fragment: ; preds = %bb_main
- invoke %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* @___ZN9__gnu_cxx17__normal_iteratorIP6BigIntSt6vectorIS1_SaIS1_EEEppEv___ZNSt6vectorImSaImEED1Ev___ZN6BigIntD1Ev___ZN9__gnu_cxx13new_allocatorI6BigIntE7destroyEPS1____ZSt8_DestroyIP6BigIntSaIS0_EEvT_S3_T0_( i32 14, %"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"* null, %"struct.std::vector<ulong,std::allocator<ulong> >"* null, %struct.BigInt* null, %struct.__false_type* null, %struct.BigInt* null, %struct.__false_type* noalias null )
- to label %meshBB30 unwind label %meshBB337 ; <%"struct.__gnu_cxx::__normal_iterator<BigInt*,std::vector<BigInt, std::allocator<BigInt> > >"*>:1 [#uses=0]
-
-invcont12.unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont12.cond_next_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-cond_next: ; preds = %bb_main
- br label %bb_main
-
-cond_next.fragment: ; preds = %bb_main
- %tmp183 = invoke %struct.BigInt* @___ZNSt6vectorI6BigIntSaIS0_EEixEj___ZNSt6vectorI6BigIntSaIS0_EE3endEv( %"struct.std::vector<BigInt,std::allocator<BigInt> >"* null, i32 %n_i_n_i, i32 29 )
- to label %invcont17 unwind label %meshBB336 ; <%struct.BigInt*> [#uses=0]
-
-cond_next.unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont17: ; preds = %cond_next.fragment, %bb_main
- br label %bb_main
+bb_main:
+ br label %invcont17.normaldest
invcont17.normaldest917: ; No predecessors!
- %tmp23 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc( %"struct.std::basic_ostream<char,std::char_traits<char> >"* null, i8* getelementptr ([6 x i8]* @.str13, i32 0, i32 0) )
- to label %invcont17.normaldest unwind label %meshBB318 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=1]
-
-invcont17.unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont22: ; preds = %bb_main
- br label %bb_main
-
-invcont22.fragment: ; preds = %bb_main
- %tmp26 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZNSolsEm( %"struct.std::basic_ostream<char,std::char_traits<char> >"* undef, i32 %n_i_n_i )
- to label %invcont25 unwind label %meshBB319 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=1]
-
-invcont22.unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont25: ; preds = %invcont22.fragment, %bb_main
- br label %bb_main
-
-invcont25.normaldest: ; No predecessors!
- %tmp2918 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc( %"struct.std::basic_ostream<char,std::char_traits<char> >"* %tmp26, i8* getelementptr ([5 x i8]* @.str14, i32 0, i32 0) )
- to label %invcont28 unwind label %invcont25.unwind_crit_edge ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-invcont25.unwind_crit_edge: ; preds = %invcont25.normaldest, %bb_main
- br label %bb_main
-
-invcont25.unwind_crit_edge.unwinddest: ; No predecessors!
- br label %bb_main
-
-invcont28: ; preds = %invcont25.normaldest, %bb_main
- br label %bb_main
-
-invcont28.normaldest: ; No predecessors!
- br label %bb_main
-
-invcont28.fragment: ; preds = %bb_main
- %tmp311 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @___ZlsRSoRK6BigInt___ZN9__gnu_cxx13new_allocatorI6BigIntE10deallocateEPS1_j( i32 32, %"struct.std::basic_ostream<char,std::char_traits<char> >"* undef, %struct.BigInt* undef, %struct.__false_type* null, i32 0 )
- to label %invcont30 unwind label %meshBB322 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-invcont28.unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont30: ; preds = %invcont28.fragment, %bb_main
- br label %bb_main
-
-invcont30.normaldest: ; No predecessors!
- br label %bb_main
-
-invcont30.fragment: ; preds = %bb_main
- %tmp34 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc( %"struct.std::basic_ostream<char,std::char_traits<char> >"* undef, i8* getelementptr ([2 x i8]* @.str15, i32 0, i32 0) )
- to label %meshBB26 unwind label %invcont30.unwind_crit_edge ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-invcont30.unwind_crit_edge: ; preds = %invcont30.fragment, %bb_main
- br label %bb_main
-
-invcont30.unwind_crit_edge.unwinddest: ; No predecessors!
- br label %bb_main
-
-invcont33: ; preds = %bb_main
- invoke void @_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv( %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* sret null , %"struct.std::ostringstream"* null )
- to label %invcont36 unwind label %invcont33.unwind_crit_edge
-
-invcont33.unwind_crit_edge: ; preds = %invcont33, %bb_main
- br label %bb_main
-
-invcont33.unwind_crit_edge.unwinddest: ; No predecessors!
- br label %bb_main
-
-invcont36: ; preds = %invcont33, %bb_main
- br label %bb_main
-
-invcont36.normaldest: ; No predecessors!
- %tmp42 = invoke %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E( %"struct.std::basic_ostream<char,std::char_traits<char> >"* @_ZSt4cout, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* null )
- to label %invcont41 unwind label %meshBB338 ; <%"struct.std::basic_ostream<char,std::char_traits<char> >"*> [#uses=0]
-
-unwind37: ; preds = %bb_main
- br label %bb_main
-
-unwind37.fragment: ; preds = %bb_main
- invoke void @_ZNSsD1Ev( %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* null )
- to label %meshBB330 unwind label %meshBB22
-
-unwind37.nofilter_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont41: ; preds = %invcont36.normaldest, %bb_main
- br label %bb_main
-
-invcont41.normaldest: ; No predecessors!
- br label %bb_main
-
-invcont41.fragment: ; preds = %bb_main
- invoke void @_ZNSsD1Ev( %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* null )
- to label %meshBB23 unwind label %meshBB29
-
-unwind43: ; preds = %bb_main
- br label %bb_main
-
-unwind43.fragment313: ; preds = %bb_main
- br label %bb_main
-
-unwind43.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind43.fragment.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind43.nofilter_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont47: ; preds = %bb_main
- invoke void @_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev( %"struct.std::ostringstream"* null )
- to label %invcont70 unwind label %meshBB28
-
-filter19: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-nofilter: ; preds = %bb_main
- br label %bb_main
-
-nofilter.fragment: ; preds = %bb_main
- invoke void @_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev( %"struct.std::ostringstream"* null )
- to label %nofilter.Unwind_crit_edge unwind label %meshBB
-
-nofilter.Unwind_crit_edge: ; preds = %nofilter.fragment, %bb_main
- br label %bb_main
-
-nofilter.Unwind_crit_edge.normaldest: ; No predecessors!
- br label %bb_main
-
-unwind53: ; preds = %bb_main
- br label %bb_main
-
-unwind53.fragment314: ; preds = %bb_main
- br label %bb_main
-
-unwind53.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind53.fragment.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind53.nofilter_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-filter62: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-unwind66: ; preds = %bb_main
- br label %bb_main
-
-unwind66.fragment315: ; preds = %bb_main
- br label %bb_main
-
-unwind66.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind66.fragment.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind66.Unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-invcont70: ; preds = %invcont47, %bb_main
- br label %bb_main
-
-invcont70.normaldest: ; No predecessors!
- br label %UnifiedReturnBlock
-
-filter75: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-unwind78: ; preds = %bb_main
- br label %bb_main
-
-unwind78.fragment316: ; preds = %bb_main
- br label %bb_main
-
-unwind78.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind78.fragment.fragment: ; preds = %bb_main
- br label %bb_main
-
-unwind78.Unwind_crit_edge: ; preds = %bb_main
- br label %bb_main
-
-filter87: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-Unwind20: ; preds = %bb_main
- br label %bb_main
-
-Unwind20.fragment: ; preds = %bb_main
- br label %UnifiedUnreachableBlock
-
-meshBB: ; preds = %nofilter.fragment, %bb_main
- br label %bb_main
-
-meshBB.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB22: ; preds = %unwind37.fragment, %bb_main
- br label %bb_main
-
-meshBB22.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB22.fragment: ; preds = %bb_main
- br label %bb_main
-
-entry1.fragment.normaldest: ; preds = %entry1.fragment.fragment, %bb_main
- br label %bb_main
-
-entry1.fragment.normaldest.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB23: ; preds = %invcont41.fragment, %bb_main
- br label %bb_main
-
-meshBB23.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB23.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB24: ; preds = %unwind10.fragment.fragment, %bb_main
- br label %bb_main
-
-meshBB24.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB24.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB25: ; preds = %bb_main
- br label %bb_main
-
-meshBB25.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB26: ; preds = %invcont30.fragment, %bb_main
- br label %bb_main
-
-meshBB26.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB26.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB27: ; preds = %bb_main
- br label %bb_main
-
-meshBB27.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB28: ; preds = %invcont47, %bb_main
- br label %bb_main
-
-meshBB28.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB28.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB29: ; preds = %invcont41.fragment, %bb_main
- br label %bb_main
-
-meshBB29.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB29.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB30: ; preds = %invcont12.fragment, %bb_main
- br label %bb_main
-
-meshBB30.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB30.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB31: ; preds = %bb_main
- br label %bb_main
-
-meshBB31.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB32: ; preds = %bb_main
- br label %bb_main
-
-meshBB32.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB33: ; preds = %bb_main
- br label %bb_main
-
-meshBB33.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB34: ; preds = %bb_main
- br label %bb_main
-
-meshBB34.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB35: ; preds = %bb_main
- br label %bb_main
-
-meshBB35.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB36: ; preds = %bb_main
- br label %bb_main
-
-meshBB36.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB37: ; preds = %invcont.fragment, %bb_main
- br label %bb_main
-
-meshBB37.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB37.fragment: ; preds = %bb_main
- br label %bb_main
-
-meshBB317: ; preds = %bb_main
- br label %bb_main
-
-meshBB318: ; preds = %invcont17.normaldest917, %bb_main
- br label %bb_main
-
-meshBB318.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB319: ; preds = %invcont22.fragment, %bb_main
- br label %bb_main
-
-meshBB319.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB320: ; preds = %entry1.fragment.fragment, %bb_main
- br label %bb_main
-
-meshBB320.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB321: ; preds = %bb_main
- br label %bb_main
-
-meshBB322: ; preds = %invcont28.fragment, %bb_main
- br label %bb_main
-
-meshBB322.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB323: ; preds = %cond_true, %bb_main
- br label %bb_main
-
-meshBB323.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB324: ; preds = %bb_main
- br label %bb_main
-
-meshBB325: ; preds = %entry.fragment.fragment, %bb_main
- br label %bb_main
-
-meshBB325.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB326: ; preds = %bb_main
- br label %bb_main
-
-meshBB327: ; preds = %bb_main
- br label %bb_main
-
-meshBB328: ; preds = %bb_main
- br label %bb_main
-
-meshBB329: ; preds = %unwind10.fragment.fragment, %bb_main
- br label %bb_main
-
-meshBB329.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB330: ; preds = %unwind37.fragment, %bb_main
- br label %bb_main
-
-meshBB330.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB331: ; preds = %bb_main
- br label %bb_main
-
-meshBB332: ; preds = %bb_main
- br label %bb_main
-
-meshBB333: ; preds = %bb_main
- br label %bb_main
-
-meshBB334: ; preds = %bb_main
- br label %bb_main
-
-meshBB335: ; preds = %bb_main
- br label %bb_main
-
-meshBB336: ; preds = %cond_next.fragment, %bb_main
- br label %bb_main
-
-meshBB336.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB337: ; preds = %invcont12.fragment, %bb_main
- br label %bb_main
-
-meshBB337.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB338: ; preds = %invcont36.normaldest, %bb_main
- br label %bb_main
-
-meshBB338.unwinddest: ; No predecessors!
- br label %bb_main
+ %tmp23 = invoke i32 @foo()
+ to label %invcont17.normaldest unwind label %invcont17.normaldest.normaldest
invcont17.normaldest: ; preds = %invcont17.normaldest917, %bb_main
br label %bb_main
invcont17.normaldest.normaldest: ; No predecessors!
- store %"struct.std::basic_ostream<char,std::char_traits<char> >"* %tmp23, %"struct.std::basic_ostream<char,std::char_traits<char> >"** undef
- br label %bb_main
-
-meshBB339: ; preds = %bb_main
- br label %bb_main
-
-meshBB340: ; preds = %entry.fragment.fragment, %bb_main
- br label %bb_main
-
-meshBB340.normaldest: ; No predecessors!
- br label %bb_main
-
-meshBB341: ; preds = %bb_main
- br label %bb_main
-
-meshBB342: ; preds = %bb_main
- br label %bb_main
-
-meshBB343: ; preds = %bb_main
- br label %bb_main
-
-meshBB344: ; preds = %bb_main
- br label %bb_main
-
-meshBB345: ; preds = %invcont14.normaldest, %bb_main
- br label %bb_main
-
-meshBB345.unwinddest: ; No predecessors!
- br label %bb_main
-
-meshBB346: ; preds = %bb_main
- br label %bb_main
-
-meshBB347: ; preds = %bb_main
- br label %bb_main
-
-meshBB348: ; preds = %bb_main
- br label %bb_main
-
-meshBB349: ; preds = %bb_main
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
+ store i32 %tmp23, i32* undef
br label %bb_main
+}
-UnifiedUnreachableBlock: ; preds = %Unwind20.fragment, %filter87, %filter75, %filter62, %filter19, %Unwind.fragment, %filter
- unreachable
+declare i32 @foo()
-UnifiedReturnBlock: ; preds = %invcont70.normaldest, %invcont15.normaldest
- ret void
-}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/LoopSimplify/merge-exits.ll b/test/Transforms/LoopSimplify/merge-exits.ll
index e5e471766b9a2..40ad2f44e717e 100644
--- a/test/Transforms/LoopSimplify/merge-exits.ll
+++ b/test/Transforms/LoopSimplify/merge-exits.ll
@@ -7,7 +7,7 @@
; that indvars can promote the induction variable to i64
; without needing casts.
-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-n:32:64"
+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-n32:64"
define float @t(float* %pTmp1, float* %peakWeight, i32 %bandEdgeIndex) nounwind {
entry:
diff --git a/test/Transforms/LoopSimplify/preserve-scev.ll b/test/Transforms/LoopSimplify/preserve-scev.ll
index 017a0d2108498..23ac7f257a384 100644
--- a/test/Transforms/LoopSimplify/preserve-scev.ll
+++ b/test/Transforms/LoopSimplify/preserve-scev.ll
@@ -48,3 +48,91 @@ return: ; preds = %for.body18, %for.bo
}
declare void @foo() nounwind
+
+; Notify SCEV when removing an ExitingBlock.
+; CHECK: @mergeExit
+; CHECK: while.cond191:
+; CHECK: br i1 %or.cond, label %while.body197
+; CHECK-NOT: land.rhs:
+; CHECK: ret
+define void @mergeExit(i32 %MapAttrCount) nounwind uwtable ssp {
+entry:
+ br i1 undef, label %if.then124, label %if.end126
+
+if.then124: ; preds = %entry
+ unreachable
+
+if.end126: ; preds = %entry
+ br i1 undef, label %while.body.lr.ph, label %if.end591
+
+while.body.lr.ph: ; preds = %if.end126
+ br i1 undef, label %if.end140, label %if.then137
+
+if.then137: ; preds = %while.body.lr.ph
+ unreachable
+
+if.end140: ; preds = %while.body.lr.ph
+ br i1 undef, label %while.cond191.outer, label %if.then148
+
+if.then148: ; preds = %if.end140
+ unreachable
+
+while.cond191.outer: ; preds = %if.then205, %if.end140
+ br label %while.cond191
+
+while.cond191: ; preds = %while.body197, %while.cond191.outer
+ %CppIndex.0 = phi i32 [ %inc, %while.body197 ], [ undef, %while.cond191.outer ]
+ br i1 undef, label %land.rhs, label %if.then216
+
+land.rhs: ; preds = %while.cond191
+ %inc = add i32 %CppIndex.0, 1
+ %cmp196 = icmp ult i32 %inc, %MapAttrCount
+ br i1 %cmp196, label %while.body197, label %if.then216
+
+while.body197: ; preds = %land.rhs
+ br i1 undef, label %if.then205, label %while.cond191
+
+if.then205: ; preds = %while.body197
+ br label %while.cond191.outer
+
+if.then216: ; preds = %land.rhs, %while.cond191
+ br i1 undef, label %if.else, label %if.then221
+
+if.then221: ; preds = %if.then216
+ unreachable
+
+if.else: ; preds = %if.then216
+ br i1 undef, label %if.then266, label %if.end340
+
+if.then266: ; preds = %if.else
+ switch i32 undef, label %if.else329 [
+ i32 17, label %if.then285
+ i32 19, label %if.then285
+ i32 18, label %if.then285
+ i32 15, label %if.then285
+ ]
+
+if.then285: ; preds = %if.then266, %if.then266, %if.then266, %if.then266
+ br i1 undef, label %if.then317, label %if.else324
+
+if.then317: ; preds = %if.then285
+ br label %if.end340
+
+if.else324: ; preds = %if.then285
+ unreachable
+
+if.else329: ; preds = %if.then266
+ unreachable
+
+if.end340: ; preds = %if.then317, %if.else
+ unreachable
+
+if.end591: ; preds = %if.end126
+ br i1 undef, label %cond.end, label %cond.false
+
+cond.false: ; preds = %if.end591
+ unreachable
+
+cond.end: ; preds = %if.end591
+ ret void
+}
diff --git a/test/Transforms/LoopSimplify/single-backedge.ll b/test/Transforms/LoopSimplify/single-backedge.ll
index f9567f124291e..aedd6f23091c9 100644
--- a/test/Transforms/LoopSimplify/single-backedge.ll
+++ b/test/Transforms/LoopSimplify/single-backedge.ll
@@ -1,8 +1,11 @@
-; The loop canonicalization pass should guarantee that there is one backedge
-; for all loops. This allows the -indvars pass to recognize the %IV
+; The loop canonicalization pass should guarantee that there is one backedge
+; for all loops. This allows the -indvars pass to recognize the %IV
; induction variable in this testcase.
-; RUN: opt < %s -indvars -S | grep indvar
+; RUN: opt < %s -indvars -S | FileCheck %s
+; CHECK: Loop.backedge:
+; CHECK-NOT: br
+; CHECK: br label %Loop
define i32 @test(i1 %C) {
; <label>:0
diff --git a/test/Transforms/LoopStrengthReduce/2011-07-19-CritEdgeBreakCrash.ll b/test/Transforms/LoopStrengthReduce/2011-07-19-CritEdgeBreakCrash.ll
new file mode 100644
index 0000000000000..b9bd7c9bf4a3e
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-07-19-CritEdgeBreakCrash.ll
@@ -0,0 +1,52 @@
+; ModuleID = '<stdin>'
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+; PR10386
+
+declare i1 @foo()
+declare i8* @bar(i8*,i8*,i8*,i8*)
+
+define void @f(i64* %a,i64* %b,i64* %c,i64* %d,i64* %e,i64* %f,i64* %g) nounwind uwtable {
+entry:
+ br label %b_throw.preheader
+
+D_BREAK_LBL: ; preds = %indirectgoto
+ call i1 @foo()
+ br label %indirectgoto
+
+H_CONST_LBL: ; preds = %indirectgoto
+ call i1 @foo()
+ br label %body_failed
+
+H_MPZ_LBL: ; preds = %indirectgoto
+ %boo3 = call i1 @foo()
+ br i1 %boo3, label %body_failed, label %while.cond.i
+
+while.cond.i: ; preds = %while.body.i15795, %if.then.i15791
+ %phi = phi i64 [ %tmp20916, %while.body.i15795 ], [ 0, %H_MPZ_LBL ]
+ %tmp20916 = add i64 %phi, 1
+ %incdec.ptr.i15793 = getelementptr i64* %pc.0.lcssa.i1610719352, i64 %tmp20916
+ %boo2 = call i1 @foo()
+ br i1 %boo2, label %indirectgoto, label %while.body.i15795
+
+while.body.i15795: ; preds = %while.cond.i
+ %tmp20.i = load i64* %incdec.ptr.i15793, align 8
+ %boo1 = call i1 @foo()
+ br i1 %boo1, label %while.cond.i, label %body_failed
+
+b_throw.preheader: ; preds = %body_failed, %entry
+ call i1 @foo()
+ br label %indirectgoto
+
+body_failed:
+ %pc.0.lcssa.i1610719364 = phi i64* [ %pc.0.lcssa.i1610719352, %indirectgoto ], [ %pc.0.lcssa.i1610719352, %H_MPZ_LBL ], [ %b, %H_CONST_LBL ], [ %pc.0.lcssa.i1610719352, %while.body.i15795 ]
+ call i1 @foo()
+ br label %b_throw.preheader
+
+indirectgoto:
+ %pc.0.lcssa.i1610719352 = phi i64* [ %pc.0.lcssa.i1610719352, %D_BREAK_LBL ], [ %a, %b_throw.preheader ], [ %d, %while.cond.i ]
+ %p = call i8* @bar(i8* blockaddress(@f, %D_BREAK_LBL), i8* blockaddress(@f, %H_CONST_LBL), i8* blockaddress(@f, %H_MPZ_LBL), i8* blockaddress(@f, %body_failed) )
+ indirectbr i8* %p, [label %D_BREAK_LBL, label %H_CONST_LBL, label %H_MPZ_LBL, label %body_failed]
+}
+
+; CHECK: %p = call i8* @bar(i8* blockaddress(@f, %D_BREAK_LBL), i8* blockaddress(@f, %H_CONST_LBL), i8* blockaddress(@f, %H_MPZ_LBL), i8* blockaddress(@f, %body_failed))
+; CHECK: indirectbr i8* %p, [label %D_BREAK_LBL, label %H_CONST_LBL, label %H_MPZ_LBL, label %body_failed]
diff --git a/test/Transforms/LoopStrengthReduce/2011-07-20-DoubleIV.ll b/test/Transforms/LoopStrengthReduce/2011-07-20-DoubleIV.ll
new file mode 100644
index 0000000000000..5d9ed64ef4223
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-07-20-DoubleIV.ll
@@ -0,0 +1,43 @@
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+;
+; Test LSR's OptimizeShadowIV. Handle a floating-point IV with a
+; nonzero initial value.
+; rdar://9786536
+
+; First, make sure LSR doesn't crash on an empty IVUsers list.
+; CHECK: @dummyIV
+; CHECK-NOT: phi
+; CHECK-NOT: sitofp
+; CHECK: br
+define void @dummyIV() nounwind {
+entry:
+ br label %loop
+
+loop:
+ %i.01 = phi i32 [ -39, %entry ], [ %inc, %loop ]
+ %conv = sitofp i32 %i.01 to double
+ %inc = add nsw i32 %i.01, 1
+ br i1 undef, label %loop, label %for.end
+
+for.end:
+ unreachable
+}
+
+; Now check that the computed double constant is correct.
+; CHECK: @doubleIV
+; CHECK: phi double [ -3.900000e+01, %entry ]
+; CHECK: br
+define void @doubleIV() nounwind {
+entry:
+ br label %loop
+
+loop:
+ %i.01 = phi i32 [ -39, %entry ], [ %inc, %loop ]
+ %conv = sitofp i32 %i.01 to double
+ %div = fdiv double %conv, 4.000000e+01
+ %inc = add nsw i32 %i.01, 1
+ br i1 undef, label %loop, label %for.end
+
+for.end:
+ unreachable
+}
diff --git a/test/Transforms/LoopStrengthReduce/2011-10-03-CritEdgeMerge.ll b/test/Transforms/LoopStrengthReduce/2011-10-03-CritEdgeMerge.ll
new file mode 100644
index 0000000000000..a6996a81fb074
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-10-03-CritEdgeMerge.ll
@@ -0,0 +1,43 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; Test LSR's use of SplitCriticalEdge during phi rewriting.
+; Verify that identical edges are merged. rdar://problem/6453893
+
+target triple = "x86-apple-darwin"
+
+; CHECK: @test
+; CHECK: bb89:
+; CHECK: phi i8* [ %lsr.iv.next1, %bbA.bb89_crit_edge ], [ %lsr.iv.next1, %bbB.bb89_crit_edge ]{{$}}
+
+define i8* @test() {
+entry:
+ br label %loop
+
+loop:
+ %rec = phi i32 [ %next, %loop ], [ 0, %entry ]
+ %next = add i32 %rec, 1
+ %tmp75 = getelementptr i8* null, i32 %next
+ br i1 false, label %loop, label %loopexit
+
+loopexit:
+ br i1 false, label %bbA, label %bbB
+
+bbA:
+ switch i32 0, label %bb89 [
+ i32 47, label %bb89
+ i32 58, label %bb89
+ ]
+
+bbB:
+ switch i8 0, label %bb89 [
+ i8 47, label %bb89
+ i8 58, label %bb89
+ ]
+
+bb89:
+ %tmp75phi = phi i8* [ %tmp75, %bbA ], [ %tmp75, %bbA ], [ %tmp75, %bbA ], [ %tmp75, %bbB ], [ %tmp75, %bbB ], [ %tmp75, %bbB ]
+ br label %exit
+
+exit:
+ ret i8* %tmp75phi
+}
diff --git a/test/Transforms/LoopStrengthReduce/2011-10-06-ReusePhi.ll b/test/Transforms/LoopStrengthReduce/2011-10-06-ReusePhi.ll
new file mode 100644
index 0000000000000..1ee9bb409d917
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-10-06-ReusePhi.ll
@@ -0,0 +1,53 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; Test LSR's intelligence regarding phi reuse.
+; Verify that scaled GEPs are not reused. rdar://5064068
+
+target triple = "x86-apple-darwin"
+
+; CHECK: @test
+; multiplies are hoisted out of the loop
+; CHECK: while.body.lr.ph:
+; CHECK: mul i64
+; CHECK: mul i64
+; GEPs are ugly
+; CHECK: while.body:
+; CHECK: phi
+; CHECK: phi
+; CHECK: phi
+; CHECK: phi
+; CHECK-NOT: phi
+; CHECK: bitcast float* {{.*}} to i8*
+; CHECK: bitcast float* {{.*}} to i8*
+; CHECK: getelementptr i8*
+; CHECK: getelementptr i8*
+
+define float @test(float* nocapture %A, float* nocapture %B, i32 %N, i32 %IA, i32 %IB) nounwind uwtable readonly ssp {
+entry:
+ %cmp1 = icmp sgt i32 %N, 0
+ br i1 %cmp1, label %while.body.lr.ph, label %while.end
+
+while.body.lr.ph: ; preds = %entry
+ %idx.ext = sext i32 %IA to i64
+ %idx.ext2 = sext i32 %IB to i64
+ br label %while.body
+
+while.body: ; preds = %while.body.lr.ph, %while.body
+ %A.addr.05 = phi float* [ %A, %while.body.lr.ph ], [ %add.ptr, %while.body ]
+ %B.addr.04 = phi float* [ %B, %while.body.lr.ph ], [ %add.ptr3, %while.body ]
+ %N.addr.03 = phi i32 [ %N, %while.body.lr.ph ], [ %sub, %while.body ]
+ %Sum0.02 = phi float [ 0.000000e+00, %while.body.lr.ph ], [ %add, %while.body ]
+ %0 = load float* %A.addr.05, align 4
+ %1 = load float* %B.addr.04, align 4
+ %mul = fmul float %0, %1
+ %add = fadd float %Sum0.02, %mul
+ %add.ptr = getelementptr inbounds float* %A.addr.05, i64 %idx.ext
+ %add.ptr3 = getelementptr inbounds float* %B.addr.04, i64 %idx.ext2
+ %sub = add nsw i32 %N.addr.03, -1
+ %cmp = icmp sgt i32 %sub, 0
+ br i1 %cmp, label %while.body, label %while.end
+
+while.end: ; preds = %while.body, %entry
+ %Sum0.0.lcssa = phi float [ 0.000000e+00, %entry ], [ %add, %while.body ]
+ ret float %Sum0.0.lcssa
+}
diff --git a/test/Transforms/LoopStrengthReduce/2011-10-13-SCEVChain.ll b/test/Transforms/LoopStrengthReduce/2011-10-13-SCEVChain.ll
new file mode 100644
index 0000000000000..4718529bfd507
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-10-13-SCEVChain.ll
@@ -0,0 +1,111 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; Test TransformForPostIncUse and LSR's expansion of expressions in
+; post-inc form to ensure the implementation can handle expressions
+; DAGs, not just trees.
+
+target triple = "x86_64-apple-darwin"
+
+; Verify that -loop-reduce runs without "hanging" and reuses post-inc
+; expansions.
+; CHECK: @test
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK: icmp
+; CHECK-NOT: icmp
+define void @test(i8* %base, i32 %a0) nounwind {
+entry:
+ br label %bb1
+bb1:
+ %n0 = sub i32 0, %a0
+ %t0 = icmp ugt i32 %n0, -4
+ %m0 = select i1 %t0, i32 %n0, i32 -4
+ %a1 = add i32 %m0, %a0
+ %n1 = sub i32 0, %a1
+ %t1 = icmp ugt i32 %n1, -4
+ %m1 = select i1 %t1, i32 %n1, i32 -4
+ %a2 = add i32 %m1, %a1
+ %n2 = sub i32 0, %a2
+ %t2 = icmp ugt i32 %n2, -4
+ %m2 = select i1 %t2, i32 %n2, i32 -4
+ %a3 = add i32 %m2, %a2
+ %n3 = sub i32 0, %a3
+ %t3 = icmp ugt i32 %n3, -4
+ %m3 = select i1 %t3, i32 %n3, i32 -4
+ %a4 = add i32 %m3, %a3
+ %n4 = sub i32 0, %a4
+ %t4 = icmp ugt i32 %n4, -4
+ %m4 = select i1 %t4, i32 %n4, i32 -4
+ %a5 = add i32 %m4, %a4
+ %n5 = sub i32 0, %a5
+ %t5 = icmp ugt i32 %n5, -4
+ %m5 = select i1 %t5, i32 %n5, i32 -4
+ %a6 = add i32 %m5, %a5
+ %n6 = sub i32 0, %a6
+ %t6 = icmp ugt i32 %n6, -4
+ %m6 = select i1 %t6, i32 %n6, i32 -4
+ %a7 = add i32 %m6, %a6
+ %n7 = sub i32 0, %a7
+ %t7 = icmp ugt i32 %n7, -4
+ %m7 = select i1 %t7, i32 %n7, i32 -4
+ %a8 = add i32 %m7, %a7
+ %n8 = sub i32 0, %a8
+ %t8 = icmp ugt i32 %n8, -4
+ %m8 = select i1 %t8, i32 %n8, i32 -4
+ %a9 = add i32 %m8, %a8
+ %n9 = sub i32 0, %a9
+ %t9 = icmp ugt i32 %n9, -4
+ %m9 = select i1 %t9, i32 %n9, i32 -4
+ %a10 = add i32 %m9, %a9
+ %n10 = sub i32 0, %a10
+ %t10 = icmp ugt i32 %n10, -4
+ %m10 = select i1 %t10, i32 %n10, i32 -4
+ %a11 = add i32 %m10, %a10
+ %n11 = sub i32 0, %a11
+ %t11 = icmp ugt i32 %n11, -4
+ %m11 = select i1 %t11, i32 %n11, i32 -4
+ %a12 = add i32 %m11, %a11
+ %n12 = sub i32 0, %a12
+ %t12 = icmp ugt i32 %n12, -4
+ %m12 = select i1 %t12, i32 %n12, i32 -4
+ %a13 = add i32 %m12, %a12
+ %n13 = sub i32 0, %a13
+ %t13 = icmp ugt i32 %n13, -4
+ %m13 = select i1 %t13, i32 %n13, i32 -4
+ %a14 = add i32 %m13, %a13
+ %n14 = sub i32 0, %a14
+ %t14 = icmp ugt i32 %n14, -4
+ %m14 = select i1 %t14, i32 %n14, i32 -4
+ %a15 = add i32 %m14, %a14
+ %n15 = sub i32 0, %a15
+ %t15 = icmp ugt i32 %n15, -4
+ %m15 = select i1 %t15, i32 %n15, i32 -4
+ %a16 = add i32 %m15, %a15
+ %gep = getelementptr i8* %base, i32 %a16
+ %ofs = add i32 %a16, 4
+ %limit = getelementptr i8* %base, i32 %ofs
+ br label %loop
+
+loop:
+ %iv = phi i8* [ %gep, %bb1 ], [ %inc, %loop ]
+ %inc = getelementptr inbounds i8* %iv, i64 1
+ %exitcond = icmp eq i8* %inc, %limit
+ br i1 %exitcond, label %loop, label %exit
+
+exit:
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/2011-10-14-IntPtr.ll b/test/Transforms/LoopStrengthReduce/2011-10-14-IntPtr.ll
new file mode 100644
index 0000000000000..60cc7a5163268
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-10-14-IntPtr.ll
@@ -0,0 +1,27 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; Test SCEVExpander reusing a phi->gep->phi IV when SCEV "wrongly"
+; reports the expression as an IntegerTy.
+
+target triple = "x86_64-apple-darwin"
+
+; CHECK: @test
+; CHECK: phi
+; CHECK-NOT: phi
+define void @test(i32 %rowStride) ssp align 2 {
+entry:
+ %cond = select i1 undef, i32 %rowStride, i32 4
+ br label %for.end
+
+for.end.critedge: ; preds = %for.end
+ br label %for.end
+
+for.end: ; preds = %for.end.critedge, %entry
+ br i1 undef, label %for.body83, label %for.end.critedge
+
+for.body83: ; preds = %for.body83, %for.end
+ %ptr.0157 = phi i8* [ %add.ptr96, %for.body83 ], [ null, %for.end ]
+ store i8 undef, i8* %ptr.0157, align 1
+ %add.ptr96 = getelementptr inbounds i8* %ptr.0157, i32 %cond
+ br label %for.body83
+}
diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
index 986a55a3f6c4e..2ca678761feda 100644
--- a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
+++ b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll
@@ -2,7 +2,7 @@
; RUN: opt < %s -loop-reduce -S | \
; RUN: not grep {getelementptr.*%outer.*%INDVAR}
-target datalayout = "e-p:32:32:32-n:8:16:32"
+target datalayout = "e-p:32:32:32-n8:16:32"
declare i1 @pred()
declare i32 @foo()
diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
index 1d43961c356e1..86c4d915a00d1 100644
--- a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
+++ b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
@@ -2,7 +2,7 @@
; RUN: opt < %s -loop-reduce -S | \
; RUN: not grep {getelementptr.*%outer.*%INDVAR}
-target datalayout = "e-p:32:32:32-n:32"
+target datalayout = "e-p:32:32:32-n32"
declare i1 @pred()
define void @test([10000 x i32]* %P, i32 %outer) {
diff --git a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
index 00bd068d0b8f0..ec55179d64953 100644
--- a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
+++ b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
@@ -3,7 +3,7 @@
; RUN: opt < %s -loop-reduce -S | not grep INDVAR
-target datalayout = "e-p:32:32:32-n:32"
+target datalayout = "e-p:32:32:32-n32"
declare i1 @pred()
diff --git a/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll b/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll
index 294c0904194ae..27609157ec8c5 100644
--- a/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll
+++ b/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll
@@ -4,15 +4,15 @@
; LSR should property handle the post-inc offset when folding the
; non-IV operand of an icmp into the IV.
-; CHECK: %tmp2 = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
-; CHECK: %tmp3 = lshr i64 %tmp2, 1
-; CHECK: %tmp4 = mul i64 %tmp3, 2
+; CHECK: %5 = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
+; CHECK: %6 = lshr i64 %5, 1
+; CHECK: %7 = mul i64 %6, 2
; CHECK: br label %for.body
; CHECK: for.body:
-; CHECK: %lsr.iv5 = phi i64 [ %lsr.iv.next, %for.body ], [ %tmp4, %for.body.lr.ph ]
-; CHECK: %lsr.iv.next = add i64 %lsr.iv5, -2
-; CHECK: %lsr.iv.next6 = inttoptr i64 %lsr.iv.next to i16*
-; CHECK: %cmp27 = icmp eq i16* %lsr.iv.next6, null
+; CHECK: %lsr.iv2 = phi i64 [ %lsr.iv.next, %for.body ], [ %7, %for.body.lr.ph ]
+; CHECK: %lsr.iv.next = add i64 %lsr.iv2, -2
+; CHECK: %lsr.iv.next3 = inttoptr i64 %lsr.iv.next to i16*
+; CHECK: %cmp27 = icmp eq i16* %lsr.iv.next3, null
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-unknown-linux-gnu"
diff --git a/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll b/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll
index 7547d83629299..64ef4f951f2b1 100644
--- a/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll
+++ b/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll
@@ -9,7 +9,7 @@
; mul uint %i, 3
-target datalayout = "e-p:32:32-n:32"
+target datalayout = "e-p:32:32-n32"
target triple = "i686-apple-darwin8"
@flags2 = external global [8193 x i8], align 32 ; <[8193 x i8]*> [#uses=1]
diff --git a/test/Transforms/LoopUnroll/2011-08-08-PhiUpdate.ll b/test/Transforms/LoopUnroll/2011-08-08-PhiUpdate.ll
new file mode 100644
index 0000000000000..cd954c80ec37a
--- /dev/null
+++ b/test/Transforms/LoopUnroll/2011-08-08-PhiUpdate.ll
@@ -0,0 +1,103 @@
+; RUN: opt < %s -loop-unroll -S -unroll-count=4 | FileCheck %s
+; Test phi update after partial unroll.
+
+declare i1 @check() nounwind
+
+; CHECK: @test
+; CHECK: if.else:
+; CHECK: if.then.loopexit
+; CHECK: %sub5.lcssa = phi i32 [ %sub{{.*}}, %if.else{{.*}} ], [ %sub{{.*}}, %if.else{{.*}} ], [ %sub{{.*}}, %if.else{{.*}} ], [ %sub{{.*}}, %if.else{{.*}} ]
+; CHECK: if.else.3
+define void @test1(i32 %i, i32 %j) nounwind uwtable ssp {
+entry:
+ %cond1 = call zeroext i1 @check()
+ br i1 %cond1, label %if.then, label %if.else.lr.ph
+
+if.else.lr.ph: ; preds = %entry
+ br label %if.else
+
+if.else: ; preds = %if.else, %if.else.lr.ph
+ %sub = phi i32 [ %i, %if.else.lr.ph ], [ %sub5, %if.else ]
+ %sub5 = sub i32 %sub, %j
+ %cond2 = call zeroext i1 @check()
+ br i1 %cond2, label %if.then, label %if.else
+
+if.then: ; preds = %if.else, %entry
+ %i.tr = phi i32 [ %i, %entry ], [ %sub5, %if.else ]
+ ret void
+
+}
+
+; PR7318: assertion failure after doing a simple loop unroll
+;
+; CHECK: @test2
+; CHECK: bb1.bb2_crit_edge:
+; CHECK: %.lcssa = phi i32 [ %{{[2468]}}, %bb1{{.*}} ], [ %{{[2468]}}, %bb1{{.*}} ], [ %{{[2468]}}, %bb1{{.*}} ], [ %{{[2468]}}, %bb1{{.*}} ]
+; CHECK: bb1.3:
+define i32 @test2(i32* nocapture %p, i32 %n) nounwind readonly {
+entry:
+ %0 = icmp sgt i32 %n, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb.nph, label %bb2
+
+bb.nph: ; preds = %entry
+ %tmp = zext i32 %n to i64 ; <i64> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb.nph, %bb1
+ %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; <i64> [#uses=2]
+ %s.01 = phi i32 [ 0, %bb.nph ], [ %2, %bb1 ] ; <i32> [#uses=1]
+ %scevgep = getelementptr i32* %p, i64 %indvar ; <i32*> [#uses=1]
+ %1 = load i32* %scevgep, align 1 ; <i32> [#uses=1]
+ %2 = add nsw i32 %1, %s.01 ; <i32> [#uses=2]
+ br label %bb1
+
+bb1: ; preds = %bb
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp ne i64 %indvar.next, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb, label %bb1.bb2_crit_edge
+
+bb1.bb2_crit_edge: ; preds = %bb1
+ %.lcssa = phi i32 [ %2, %bb1 ] ; <i32> [#uses=1]
+ br label %bb2
+
+bb2: ; preds = %bb1.bb2_crit_edge, %entry
+ %s.0.lcssa = phi i32 [ %.lcssa, %bb1.bb2_crit_edge ], [ 0, %entry ] ; <i32> [#uses=1]
+ ret i32 %s.0.lcssa
+}
+
+; Check phi update for loop with an early-exit.
+;
+; CHECK: @test3
+; CHECK: return.loopexit:
+; CHECK: %tmp7.i.lcssa = phi i32 [ %tmp7.i{{.*}}, %land.lhs.true{{.*}} ], [ %tmp7.i{{.*}}, %land.lhs.true{{.*}} ], [ %tmp7.i{{.*}}, %land.lhs.true{{.*}} ], [ %tmp7.i{{.*}}, %land.lhs.true{{.*}} ]
+; CHECK: exit.3:
+define i32 @test3() nounwind uwtable ssp align 2 {
+entry:
+ %cond1 = call zeroext i1 @check()
+ br i1 %cond1, label %return, label %if.end
+
+if.end: ; preds = %entry
+ br label %do.body
+
+do.body: ; preds = %do.cond, %if.end
+ %cond2 = call zeroext i1 @check()
+ br i1 %cond2, label %exit, label %do.cond
+
+exit: ; preds = %do.body
+ %tmp7.i = load i32* undef, align 8
+ br i1 undef, label %do.cond, label %land.lhs.true
+
+land.lhs.true: ; preds = %exit
+ br i1 undef, label %return, label %do.cond
+
+do.cond: ; preds = %land.lhs.true, %exit, %do.body
+ %cond3 = call zeroext i1 @check()
+ br i1 %cond3, label %do.end, label %do.body
+
+do.end: ; preds = %do.cond
+ br label %return
+
+return: ; preds = %do.end, %land.lhs.true, %entry
+ %retval.0 = phi i32 [ 0, %do.end ], [ 0, %entry ], [ %tmp7.i, %land.lhs.true ]
+ ret i32 %retval.0
+}
diff --git a/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll b/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll
new file mode 100644
index 0000000000000..59551d5c720c7
--- /dev/null
+++ b/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll
@@ -0,0 +1,41 @@
+; RUN: opt -S < %s -loop-unroll -unroll-count=4 -enable-iv-rewrite=false | FileCheck %s
+;
+; Test induction variable simplify after loop unrolling. It should
+; expose nice opportunities for GVN.
+;
+; CHECK-NOT: while.body also ensures that loop unrolling (with SCEV)
+; removes unrolled loop exits given that 128 is a multiple of 4.
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+
+; PR10534: LoopUnroll not keeping canonical induction variable...
+; CHECK: while.body:
+; CHECK-NOT: while.body.1:
+; CHECK: %shr.1 = lshr i32 %bit_addr.addr.01, 5
+; CHECK: %arrayidx.1 = getelementptr inbounds i32* %bitmap, i32 %shr.1
+; CHECK: %shr.2 = lshr i32 %bit_addr.addr.01, 5
+; CHECK: %arrayidx.2 = getelementptr inbounds i32* %bitmap, i32 %shr.2
+; CHECK: %shr.3 = lshr i32 %bit_addr.addr.01, 5
+; CHECK: %arrayidx.3 = getelementptr inbounds i32* %bitmap, i32 %shr.3
+define void @FlipBit(i32* nocapture %bitmap, i32 %bit_addr, i32 %nbits) nounwind {
+entry:
+ br label %while.body
+
+while.body:
+ %nbits.addr.02 = phi i32 [ 128, %entry ], [ %dec, %while.body ]
+ %bit_addr.addr.01 = phi i32 [ 0, %entry ], [ %inc, %while.body ]
+ %dec = add i32 %nbits.addr.02, -1
+ %shr = lshr i32 %bit_addr.addr.01, 5
+ %rem = and i32 %bit_addr.addr.01, 31
+ %shl = shl i32 1, %rem
+ %arrayidx = getelementptr inbounds i32* %bitmap, i32 %shr
+ %tmp6 = load i32* %arrayidx, align 4
+ %xor = xor i32 %tmp6, %shl
+ store i32 %xor, i32* %arrayidx, align 4
+ %inc = add i32 %bit_addr.addr.01, 1
+ %tobool = icmp eq i32 %dec, 0
+ br i1 %tobool, label %while.end, label %while.body
+
+while.end:
+ ret void
+}
diff --git a/test/Transforms/LoopUnroll/2011-08-09-PhiUpdate.ll b/test/Transforms/LoopUnroll/2011-08-09-PhiUpdate.ll
new file mode 100644
index 0000000000000..c1221f595ac29
--- /dev/null
+++ b/test/Transforms/LoopUnroll/2011-08-09-PhiUpdate.ll
@@ -0,0 +1,62 @@
+; RUN: opt -S < %s -instcombine -inline -jump-threading -loop-unroll -unroll-count=4 | FileCheck %s
+;
+; This is a test case that required a number of setup passes because
+; it depends on block order.
+
+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-macosx10.6.8"
+
+declare i1 @check() nounwind
+declare i32 @getval() nounwind
+
+; Check that the loop exit merges values from all the iterations. This
+; could be a tad fragile, but it's a good test.
+;
+; CHECK: @foo
+; CHECK: return:
+; CHECK: %retval.0 = phi i32 [ %tmp7.i, %land.lhs.true ], [ 0, %do.cond ], [ %tmp7.i.1, %land.lhs.true.1 ], [ 0, %do.cond.1 ], [ %tmp7.i.2, %land.lhs.true.2 ], [ 0, %do.cond.2 ], [ %tmp7.i.3, %land.lhs.true.3 ], [ 0, %do.cond.3 ]
+; CHECK-NOT: @bar
+; CHECK: bar.exit.3
+define i32 @foo() uwtable ssp align 2 {
+entry:
+ br i1 undef, label %return, label %if.end
+
+if.end: ; preds = %entry
+ %call2 = call i32 @getval()
+ br label %do.body
+
+do.body: ; preds = %do.cond, %if.end
+ %call6 = call i32 @bar()
+ %cmp = icmp ne i32 %call6, 0
+ br i1 %cmp, label %land.lhs.true, label %do.cond
+
+land.lhs.true: ; preds = %do.body
+ %call10 = call i32 @getval()
+ %cmp11 = icmp eq i32 0, %call10
+ br i1 %cmp11, label %return, label %do.cond
+
+do.cond: ; preds = %land.lhs.true, %do.body
+ %cmp18 = icmp sle i32 0, %call2
+ br i1 %cmp18, label %do.body, label %return
+
+return: ; preds = %do.cond, %land.lhs.true, %entry
+ %retval.0 = phi i32 [ 0, %entry ], [ %call6, %land.lhs.true ], [ 0, %do.cond ]
+ ret i32 %retval.0
+}
+
+define linkonce_odr i32 @bar() nounwind uwtable ssp align 2 {
+entry:
+ br i1 undef, label %land.lhs.true, label %cond.end
+
+land.lhs.true: ; preds = %entry
+ %cmp4 = call zeroext i1 @check()
+ br i1 %cmp4, label %cond.true, label %cond.end
+
+cond.true: ; preds = %land.lhs.true
+ %tmp7 = call i32 @getval()
+ br label %cond.end
+
+cond.end: ; preds = %cond.true, %land.lhs.true, %entry
+ %cond = phi i32 [ %tmp7, %cond.true ], [ 0, %land.lhs.true ], [ 0, %entry ]
+ ret i32 %cond
+}
diff --git a/test/Transforms/LoopUnroll/2011-10-01-NoopTrunc.ll b/test/Transforms/LoopUnroll/2011-10-01-NoopTrunc.ll
new file mode 100644
index 0000000000000..7fb471ea75092
--- /dev/null
+++ b/test/Transforms/LoopUnroll/2011-10-01-NoopTrunc.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -S -loop-unroll -unroll-threshold=150 | FileCheck %s
+;
+; Verify that trunc i64 to i32 is considered free by loop unrolling
+; heuristics when i32 is a native type.
+; This should result in full unrolling this loop with size=7, TC=19.
+; If the trunc were not free we would have 8*19=152 > 150.
+
+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"
+
+; Check that for.body was unrolled 19 times.
+; CHECK: @test
+; CHECK: %0 = load
+; CHECK: %conv = sext i8 %0 to i32
+; CHECK: %add.1 = add nsw i32 %conv.1, %conv
+; CHECK: %add.18 = add nsw i32 %conv.18, %add.17
+; CHECK: ret i32 %add.18
+define i32 @test(i8* %arr) nounwind uwtable readnone {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %sum.02 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %arrayidx = getelementptr inbounds i8* %arr, i64 %indvars.iv
+ %0 = load i8* %arrayidx, align 1
+ %conv = sext i8 %0 to i32
+ %add = add nsw i32 %conv, %sum.02
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv1 = trunc i64 %indvars.iv.next to i32
+ %exitcond2 = icmp eq i32 %lftr.wideiv1, 19
+ br i1 %exitcond2, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ %add.lcssa = phi i32 [ %add, %for.body ]
+ ret i32 %add.lcssa
+}
diff --git a/test/Transforms/LoopUnroll/pr10813.ll b/test/Transforms/LoopUnroll/pr10813.ll
new file mode 100644
index 0000000000000..7daefc2f788e2
--- /dev/null
+++ b/test/Transforms/LoopUnroll/pr10813.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -loop-unroll -disable-output
+
+define void @"f_fu___REFUf[]REFUf[]Uf"() nounwind {
+allocas:
+ br i1 undef, label %cif_mask_all, label %cif_mixed_test_all
+
+cif_mask_all: ; preds = %allocas
+ unreachable
+
+cif_mixed_test_all: ; preds = %allocas
+ br label %pl_loop.i964
+
+pl_loop.i964: ; preds = %pl_loopend.i973, %cif_mixed_test_all
+ %0 = phi i32 [ %pl_nextlane.i971, %pl_loopend.i973 ], [ 0, %cif_mixed_test_all ]
+ br i1 undef, label %pl_dolane.i970, label %pl_loopend.i973
+
+pl_dolane.i970: ; preds = %pl_loop.i964
+ %storeval.i.i969 = extractelement <4 x i8> <i8 0, i8 1, i8 2, i8 3>, i32 %0
+ store i8 %storeval.i.i969, i8* undef, align 1
+ br label %pl_loopend.i973
+
+pl_loopend.i973: ; preds = %pl_dolane.i970, %pl_loop.i964
+ %pl_nextlane.i971 = add i32 %0, 1
+ %exitcond5 = icmp ne i32 %pl_nextlane.i971, 5
+ br i1 %exitcond5, label %pl_loop.i964, label %__scatter_base_offsets_i8.exit974
+
+__scatter_base_offsets_i8.exit974: ; preds = %pl_loopend.i973
+ unreachable
+}
diff --git a/test/Transforms/LoopUnroll/scevunroll.ll b/test/Transforms/LoopUnroll/scevunroll.ll
new file mode 100644
index 0000000000000..99b3a7d861971
--- /dev/null
+++ b/test/Transforms/LoopUnroll/scevunroll.ll
@@ -0,0 +1,172 @@
+; RUN: opt < %s -S -indvars -loop-unroll -verify-loop-info | FileCheck %s
+;
+; Unit tests for loop unrolling using ScalarEvolution to compute trip counts.
+;
+; Indvars is run first to generate an "old" SCEV result. Some unit
+; tests may check that SCEV is properly invalidated between passes.
+
+; Completely unroll loops without a canonical IV.
+;
+; CHECK: @sansCanonical
+; CHECK-NOT: phi
+; CHECK-NOT: icmp
+; CHECK: ret
+define i32 @sansCanonical(i32* %base) nounwind {
+entry:
+ br label %while.body
+
+while.body:
+ %iv = phi i64 [ 10, %entry ], [ %iv.next, %while.body ]
+ %sum = phi i32 [ 0, %entry ], [ %sum.next, %while.body ]
+ %iv.next = add i64 %iv, -1
+ %adr = getelementptr inbounds i32* %base, i64 %iv.next
+ %tmp = load i32* %adr, align 8
+ %sum.next = add i32 %sum, %tmp
+ %iv.narrow = trunc i64 %iv.next to i32
+ %cmp.i65 = icmp sgt i32 %iv.narrow, 0
+ br i1 %cmp.i65, label %while.body, label %exit
+
+exit:
+ ret i32 %sum
+}
+
+; SCEV unrolling properly handles loops with multiple exits. In this
+; case, the computed trip count based on a canonical IV is *not* for a
+; latch block. Canonical unrolling incorrectly unrolls it, but SCEV
+; unrolling does not.
+;
+; CHECK: @earlyLoopTest
+; CHECK: tail:
+; CHECK-NOT: br
+; CHECK: br i1 %cmp2, label %loop, label %exit2
+define i64 @earlyLoopTest(i64* %base) nounwind {
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %inc, %tail ]
+ %s = phi i64 [ 0, %entry ], [ %s.next, %tail ]
+ %adr = getelementptr i64* %base, i64 %iv
+ %val = load i64* %adr
+ %s.next = add i64 %s, %val
+ %inc = add i64 %iv, 1
+ %cmp = icmp ne i64 %inc, 4
+ br i1 %cmp, label %tail, label %exit1
+
+tail:
+ %cmp2 = icmp ne i64 %val, 0
+ br i1 %cmp2, label %loop, label %exit2
+
+exit1:
+ ret i64 %s
+
+exit2:
+ ret i64 %s.next
+}
+
+; SCEV properly unrolls multi-exit loops.
+;
+; CHECK: @multiExit
+; CHECK: getelementptr i32* %base, i32 10
+; CHECK-NEXT: load i32*
+; CHECK: br i1 false, label %l2.10, label %exit1
+; CHECK: l2.10:
+; CHECK-NOT: br
+; CHECK: ret i32
+define i32 @multiExit(i32* %base) nounwind {
+entry:
+ br label %l1
+l1:
+ %iv1 = phi i32 [ 0, %entry ], [ %inc1, %l2 ]
+ %iv2 = phi i32 [ 0, %entry ], [ %inc2, %l2 ]
+ %inc1 = add i32 %iv1, 1
+ %inc2 = add i32 %iv2, 1
+ %adr = getelementptr i32* %base, i32 %iv1
+ %val = load i32* %adr
+ %cmp1 = icmp slt i32 %iv1, 5
+ br i1 %cmp1, label %l2, label %exit1
+l2:
+ %cmp2 = icmp slt i32 %iv2, 10
+ br i1 %cmp2, label %l1, label %exit2
+exit1:
+ ret i32 1
+exit2:
+ ret i32 %val
+}
+
+
+; SCEV should not unroll a multi-exit loops unless the latch block has
+; a known trip count, regardless of the early exit trip counts. The
+; LoopUnroll utility uses this assumption to optimize the latch
+; block's branch.
+;
+; CHECK: @multiExit
+; CHECK: l3:
+; CHECK-NOT: br
+; CHECK: br i1 %cmp3, label %l1, label %exit3
+define i32 @multiExitIncomplete(i32* %base) nounwind {
+entry:
+ br label %l1
+l1:
+ %iv1 = phi i32 [ 0, %entry ], [ %inc1, %l3 ]
+ %iv2 = phi i32 [ 0, %entry ], [ %inc2, %l3 ]
+ %inc1 = add i32 %iv1, 1
+ %inc2 = add i32 %iv2, 1
+ %adr = getelementptr i32* %base, i32 %iv1
+ %val = load i32* %adr
+ %cmp1 = icmp slt i32 %iv1, 5
+ br i1 %cmp1, label %l2, label %exit1
+l2:
+ %cmp2 = icmp slt i32 %iv2, 10
+ br i1 %cmp2, label %l3, label %exit2
+l3:
+ %cmp3 = icmp ne i32 %val, 0
+ br i1 %cmp3, label %l1, label %exit3
+
+exit1:
+ ret i32 1
+exit2:
+ ret i32 2
+exit3:
+ ret i32 3
+}
+
+; When loop unroll merges a loop exit with one of its parent loop's
+; exits, SCEV must forget its ExitNotTaken info.
+;
+; CHECK: @nestedUnroll
+; CHECK-NOT: br i1
+; CHECK: for.body87:
+define void @nestedUnroll() nounwind {
+entry:
+ br label %for.inc
+
+for.inc:
+ br i1 false, label %for.inc, label %for.body38.preheader
+
+for.body38.preheader:
+ br label %for.body38
+
+for.body38:
+ %i.113 = phi i32 [ %inc76, %for.inc74 ], [ 0, %for.body38.preheader ]
+ %mul48 = mul nsw i32 %i.113, 6
+ br label %for.body43
+
+for.body43:
+ %j.011 = phi i32 [ 0, %for.body38 ], [ %inc72, %for.body43 ]
+ %add49 = add nsw i32 %j.011, %mul48
+ %sh_prom50 = zext i32 %add49 to i64
+ %inc72 = add nsw i32 %j.011, 1
+ br i1 false, label %for.body43, label %for.inc74
+
+for.inc74:
+ %inc76 = add nsw i32 %i.113, 1
+ br i1 false, label %for.body38, label %for.body87.preheader
+
+for.body87.preheader:
+ br label %for.body87
+
+for.body87:
+ br label %for.body87
+}
+
diff --git a/test/Transforms/LoopUnroll/unloop.ll b/test/Transforms/LoopUnroll/unloop.ll
new file mode 100644
index 0000000000000..217c8cea56f7e
--- /dev/null
+++ b/test/Transforms/LoopUnroll/unloop.ll
@@ -0,0 +1,429 @@
+; RUN: opt < %s -S -loop-unroll -verify-loop-info | FileCheck %s
+;
+; Unit tests for LoopInfo::updateUnloop.
+
+declare i1 @check() nounwind
+
+; Ensure that tail->inner is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @skiplevelexit
+; CHECK: tail:
+; CHECK-NOT: br
+; CHECK: ret void
+define void @skiplevelexit() nounwind {
+entry:
+ br label %outer
+
+outer:
+ br label %inner
+
+inner:
+ %iv = phi i32 [ 0, %outer ], [ %inc, %tail ]
+ %inc = add i32 %iv, 1
+ %wbucond = call zeroext i1 @check()
+ br i1 %wbucond, label %outer.backedge, label %tail
+
+tail:
+ br i1 false, label %inner, label %exit
+
+outer.backedge:
+ br label %outer
+
+exit:
+ ret void
+}
+
+; Remove the middle loop of a triply nested loop tree.
+; Ensure that only the middle loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopNested
+; Outer loop control.
+; CHECK: while.body:
+; CHECK: br i1 %cmp3, label %if.then, label %if.end
+; Inner loop control.
+; CHECK: while.end14.i:
+; CHECK: br i1 %call15.i, label %if.end.i, label %exit
+; Middle loop control should no longer reach %while.cond.
+; Now it is the outer loop backedge.
+; CHECK: exit:
+; CHECK: br label %while.cond.outer
+define void @unloopNested() {
+entry:
+ br label %while.cond.outer
+
+while.cond.outer:
+ br label %while.cond
+
+while.cond:
+ %cmp = call zeroext i1 @check()
+ br i1 %cmp, label %while.body, label %while.end
+
+while.body:
+ %cmp3 = call zeroext i1 @check()
+ br i1 %cmp3, label %if.then, label %if.end
+
+if.then:
+ br label %return
+
+if.end:
+ %cmp.i48 = call zeroext i1 @check()
+ br i1 %cmp.i48, label %if.then.i, label %if.else20.i
+
+if.then.i:
+ %cmp8.i = call zeroext i1 @check()
+ br i1 %cmp8.i, label %merge, label %if.else.i
+
+if.else.i:
+ br label %merge
+
+if.else20.i:
+ %cmp25.i = call zeroext i1 @check()
+ br i1 %cmp25.i, label %merge, label %if.else28.i
+
+if.else28.i:
+ br label %merge
+
+merge:
+ br label %while.cond2.i
+
+while.cond2.i:
+ %cmp.i = call zeroext i1 @check()
+ br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i
+
+while.cond2.backedge.i:
+ br label %while.cond2.i
+
+while.end.i:
+ %cmp1114.i = call zeroext i1 @check()
+ br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i
+
+while.body12.lr.ph.i:
+ br label %while.end14.i
+
+while.end14.i:
+ %call15.i = call zeroext i1 @check()
+ br i1 %call15.i, label %if.end.i, label %exit
+
+if.end.i:
+ br label %while.cond2.backedge.i
+
+exit:
+ br i1 false, label %while.cond, label %if.else
+
+if.else:
+ br label %while.cond.outer
+
+while.end:
+ br label %return
+
+return:
+ ret void
+}
+
+; Remove the middle loop of a deeply nested loop tree.
+; Ensure that only the middle loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopDeepNested
+; Inner-inner loop control.
+; CHECK: while.cond.us.i:
+; CHECK: br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
+; CHECK: if.then.us.i:
+; CHECK: br label %while.cond.us.i
+; Inner loop tail.
+; CHECK: if.else.i:
+; CHECK: br label %while.cond.outer.i
+; Middle loop control (removed).
+; CHECK: valid_data.exit:
+; CHECK-NOT: br
+; CHECK: %cmp = call zeroext i1 @check()
+; Outer loop control.
+; CHECK: copy_data.exit:
+; CHECK: br i1 %cmp38, label %if.then39, label %while.cond.outer
+; Outer-outer loop tail.
+; CHECK: while.cond.outer.outer.backedge:
+; CHECK: br label %while.cond.outer.outer
+define void @unloopDeepNested() nounwind {
+for.cond8.preheader.i:
+ %cmp113.i = call zeroext i1 @check()
+ br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i
+
+for.body13.lr.ph.i:
+ br label %make_data.exit
+
+make_data.exit:
+ br label %while.cond.outer.outer
+
+while.cond.outer.outer:
+ br label %while.cond.outer
+
+while.cond.outer:
+ br label %while.cond
+
+while.cond:
+ br label %while.cond.outer.i
+
+while.cond.outer.i:
+ %tmp192.ph.i = call zeroext i1 @check()
+ br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit
+
+while.cond.outer.split.us.i:
+ br label %while.cond.us.i
+
+while.cond.us.i:
+ %cmp.us.i = call zeroext i1 @check()
+ br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
+
+while.body.us.i:
+ %cmp7.us.i = call zeroext i1 @check()
+ br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i
+
+if.then.us.i:
+ br label %while.cond.us.i
+
+if.else.i:
+ br label %while.cond.outer.i
+
+next_data.exit:
+ %tmp192.ph.i.lcssa28 = call zeroext i1 @check()
+ br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body
+
+while.body.loopexit:
+ br label %while.body
+
+while.body:
+ br label %while.cond.i
+
+while.cond.i:
+ %cmp.i = call zeroext i1 @check()
+ br i1 %cmp.i, label %valid_data.exit, label %while.body.i
+
+while.body.i:
+ %cmp7.i = call zeroext i1 @check()
+ br i1 %cmp7.i, label %valid_data.exit, label %if.end.i
+
+if.end.i:
+ br label %while.cond.i
+
+valid_data.exit:
+ br i1 true, label %if.then, label %while.cond
+
+if.then:
+ %cmp = call zeroext i1 @check()
+ br i1 %cmp, label %if.then12, label %if.end
+
+if.then12:
+ br label %if.end
+
+if.end:
+ %tobool3.i = call zeroext i1 @check()
+ br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i
+
+while.body.lr.ph.i:
+ br label %copy_data.exit
+
+copy_data.exit:
+ %cmp38 = call zeroext i1 @check()
+ br i1 %cmp38, label %if.then39, label %while.cond.outer
+
+if.then39:
+ %cmp5.i = call zeroext i1 @check()
+ br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread
+
+for.cond8.preheader.i8.thread:
+ br label %while.cond.outer.outer.backedge
+
+while.cond.outer.outer.backedge:
+ br label %while.cond.outer.outer
+
+while.end:
+ ret void
+}
+
+; Remove a nested loop with irreducible control flow.
+; Ensure that only the middle loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopIrreducible
+; Irreducible loop.
+; CHECK: for.inc117:
+; CHECK: br label %for.cond103t
+; Nested loop (removed).
+; CHECK: for.inc159:
+; CHECK: br label %for.inc163
+define void @unloopIrreducible() nounwind {
+
+entry:
+ br label %for.body
+
+for.body:
+ %cmp2113 = call zeroext i1 @check()
+ br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163
+
+for.body22.lr.ph:
+ br label %for.body22
+
+for.body22:
+ br label %for.body33
+
+for.body33:
+ br label %for.end
+
+for.end:
+ %cmp424 = call zeroext i1 @check()
+ br i1 %cmp424, label %for.body43.lr.ph, label %for.end93
+
+for.body43.lr.ph:
+ br label %for.end93
+
+for.end93:
+ %cmp96 = call zeroext i1 @check()
+ br i1 %cmp96, label %if.then97, label %for.cond103
+
+if.then97:
+ br label %for.cond103t
+
+for.cond103t:
+ br label %for.cond103
+
+for.cond103:
+ %cmp105 = call zeroext i1 @check()
+ br i1 %cmp105, label %for.body106, label %for.end120
+
+for.body106:
+ %cmp108 = call zeroext i1 @check()
+ br i1 %cmp108, label %if.then109, label %for.inc117
+
+if.then109:
+ br label %for.inc117
+
+for.inc117:
+ br label %for.cond103t
+
+for.end120:
+ br label %for.inc159
+
+for.inc159:
+ br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge
+
+for.cond15.for.inc163_crit_edge:
+ br label %for.inc163
+
+for.inc163:
+ %cmp12 = call zeroext i1 @check()
+ br i1 %cmp12, label %for.body, label %for.end166
+
+for.end166:
+ ret void
+
+}
+
+; Remove a loop whose exit branches into a sibling loop.
+; Ensure that only the loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopCriticalEdge
+; CHECK: while.cond.outer.i.loopexit.split:
+; CHECK: br label %while.body
+; CHECK: while.body:
+; CHECK: br label %for.end78
+define void @unloopCriticalEdge() nounwind {
+entry:
+ br label %for.cond31
+
+for.cond31:
+ br i1 undef, label %for.body35, label %for.end94
+
+for.body35:
+ br label %while.cond.i.preheader
+
+while.cond.i.preheader:
+ br i1 undef, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split
+
+while.cond.i.preheader.split:
+ br label %while.cond.i
+
+while.cond.i:
+ br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit
+
+while.cond.outer.i.loopexit:
+ br label %while.cond.outer.i.loopexit.split
+
+while.cond.outer.i.loopexit.split:
+ br i1 false, label %while.cond.i.preheader, label %Func2.exit
+
+Func2.exit:
+ br label %while.body
+
+while.body:
+ br i1 false, label %while.body, label %while.end
+
+while.end:
+ br label %for.end78
+
+for.end78:
+ br i1 undef, label %Proc2.exit, label %for.cond.i.preheader
+
+for.cond.i.preheader:
+ br label %for.cond.i
+
+for.cond.i:
+ br label %for.cond.i
+
+Proc2.exit:
+ br label %for.cond31
+
+for.end94:
+ ret void
+}
+
+; Test UnloopUpdater::removeBlocksFromAncestors.
+;
+; Check that the loop backedge is removed from the middle loop 1699,
+; but not the inner loop 1676.
+; CHECK: while.body1694:
+; CHECK: br label %while.cond1676
+; CHECK: while.end1699:
+; CHECK: br label %sw.default1711
+define void @removeSubloopBlocks() nounwind {
+entry:
+ br label %tryagain.outer
+
+tryagain.outer: ; preds = %sw.bb304, %entry
+ br label %tryagain
+
+tryagain: ; preds = %while.end1699, %tryagain.outer
+ br i1 undef, label %sw.bb1669, label %sw.bb304
+
+sw.bb304: ; preds = %tryagain
+ br i1 undef, label %return, label %tryagain.outer
+
+sw.bb1669: ; preds = %tryagain
+ br i1 undef, label %sw.default1711, label %while.cond1676
+
+while.cond1676: ; preds = %while.body1694, %sw.bb1669
+ br i1 undef, label %while.end1699, label %while.body1694
+
+while.body1694: ; preds = %while.cond1676
+ br label %while.cond1676
+
+while.end1699: ; preds = %while.cond1676
+ br i1 false, label %tryagain, label %sw.default1711
+
+sw.default1711: ; preds = %while.end1699, %sw.bb1669, %tryagain
+ br label %defchar
+
+defchar: ; preds = %sw.default1711, %sw.bb376
+ br i1 undef, label %if.end2413, label %if.then2368
+
+if.then2368: ; preds = %defchar
+ unreachable
+
+if.end2413: ; preds = %defchar
+ unreachable
+
+return: ; preds = %sw.bb304
+ ret void
+}
diff --git a/test/Transforms/LoopUnswitch/2011-09-26-EHCrash.ll b/test/Transforms/LoopUnswitch/2011-09-26-EHCrash.ll
new file mode 100644
index 0000000000000..0e3103dc6db71
--- /dev/null
+++ b/test/Transforms/LoopUnswitch/2011-09-26-EHCrash.ll
@@ -0,0 +1,67 @@
+; RUN: opt < %s -scalarrepl-ssa -loop-unswitch -disable-output
+; PR11016
+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-macosx10.7.2"
+
+%class.MyContainer.1.3.19.29 = type { [6 x %class.MyMemVarClass.0.2.18.28*] }
+%class.MyMemVarClass.0.2.18.28 = type { i32 }
+
+define void @_ZN11MyContainer1fEi(%class.MyContainer.1.3.19.29* %this, i32 %doit) uwtable ssp align 2 {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %inc1 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
+ %conv = sext i32 %inc1 to i64
+ %cmp = icmp ult i64 %conv, 6
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tobool = icmp ne i32 %doit, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %idxprom = sext i32 %inc1 to i64
+ %array_ = getelementptr inbounds %class.MyContainer.1.3.19.29* %this, i32 0, i32 0
+ %arrayidx = getelementptr inbounds [6 x %class.MyMemVarClass.0.2.18.28*]* %array_, i32 0, i64 %idxprom
+ %tmp4 = load %class.MyMemVarClass.0.2.18.28** %arrayidx, align 8, !tbaa !0
+ %isnull = icmp eq %class.MyMemVarClass.0.2.18.28* %tmp4, null
+ br i1 %isnull, label %for.inc, label %delete.notnull
+
+delete.notnull: ; preds = %if.then
+ invoke void @_ZN13MyMemVarClassD1Ev(%class.MyMemVarClass.0.2.18.28* %tmp4)
+ to label %invoke.cont unwind label %lpad
+
+invoke.cont: ; preds = %delete.notnull
+ %0 = bitcast %class.MyMemVarClass.0.2.18.28* %tmp4 to i8*
+ call void @_ZdlPv(i8* %0) nounwind
+ br label %for.inc
+
+lpad: ; preds = %delete.notnull
+ %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ %2 = extractvalue { i8*, i32 } %1, 0
+ %3 = extractvalue { i8*, i32 } %1, 1
+ %4 = bitcast %class.MyMemVarClass.0.2.18.28* %tmp4 to i8*
+ call void @_ZdlPv(i8* %4) nounwind
+ %lpad.val = insertvalue { i8*, i32 } undef, i8* %2, 0
+ %lpad.val7 = insertvalue { i8*, i32 } %lpad.val, i32 %3, 1
+ resume { i8*, i32 } %lpad.val7
+
+for.inc: ; preds = %invoke.cont, %if.then, %for.body
+ %inc = add nsw i32 %inc1, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+declare void @_ZN13MyMemVarClassD1Ev(%class.MyMemVarClass.0.2.18.28*)
+
+declare i32 @__gxx_personality_v0(...)
+
+declare void @_ZdlPv(i8*) nounwind
+
+!0 = metadata !{metadata !"any pointer", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
diff --git a/test/Transforms/LowerAtomic/atomic-load.ll b/test/Transforms/LowerAtomic/atomic-load.ll
index 5b110d6b7eba4..bc04e88344ef9 100644
--- a/test/Transforms/LowerAtomic/atomic-load.ll
+++ b/test/Transforms/LowerAtomic/atomic-load.ll
@@ -1,13 +1,9 @@
; RUN: opt < %s -loweratomic -S | FileCheck %s
-declare i8 @llvm.atomic.load.add.i8.p0i8(i8* %ptr, i8 %delta)
-declare i8 @llvm.atomic.load.nand.i8.p0i8(i8* %ptr, i8 %delta)
-declare i8 @llvm.atomic.load.min.i8.p0i8(i8* %ptr, i8 %delta)
-
define i8 @add() {
; CHECK: @add
%i = alloca i8
- %j = call i8 @llvm.atomic.load.add.i8.p0i8(i8* %i, i8 42)
+ %j = atomicrmw add i8* %i, i8 42 monotonic
; CHECK: [[INST:%[a-z0-9]+]] = load
; CHECK-NEXT: add
; CHECK-NEXT: store
@@ -18,7 +14,7 @@ define i8 @add() {
define i8 @nand() {
; CHECK: @nand
%i = alloca i8
- %j = call i8 @llvm.atomic.load.nand.i8.p0i8(i8* %i, i8 42)
+ %j = atomicrmw nand i8* %i, i8 42 monotonic
; CHECK: [[INST:%[a-z0-9]+]] = load
; CHECK-NEXT: and
; CHECK-NEXT: xor
@@ -30,7 +26,7 @@ define i8 @nand() {
define i8 @min() {
; CHECK: @min
%i = alloca i8
- %j = call i8 @llvm.atomic.load.min.i8.p0i8(i8* %i, i8 42)
+ %j = atomicrmw min i8* %i, i8 42 monotonic
; CHECK: [[INST:%[a-z0-9]+]] = load
; CHECK-NEXT: icmp
; CHECK-NEXT: select
diff --git a/test/Transforms/LowerAtomic/atomic-swap.ll b/test/Transforms/LowerAtomic/atomic-swap.ll
index 0a59c8595e6a0..5e2f034a5177a 100644
--- a/test/Transforms/LowerAtomic/atomic-swap.ll
+++ b/test/Transforms/LowerAtomic/atomic-swap.ll
@@ -1,12 +1,9 @@
; RUN: opt < %s -loweratomic -S | FileCheck %s
-declare i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* %ptr, i8 %cmp, i8 %val)
-declare i8 @llvm.atomic.swap.i8.p0i8(i8* %ptr, i8 %val)
-
define i8 @cmpswap() {
; CHECK: @cmpswap
%i = alloca i8
- %j = call i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* %i, i8 0, i8 42)
+ %j = cmpxchg i8* %i, i8 0, i8 42 monotonic
; CHECK: [[INST:%[a-z0-9]+]] = load
; CHECK-NEXT: icmp
; CHECK-NEXT: select
@@ -18,7 +15,7 @@ define i8 @cmpswap() {
define i8 @swap() {
; CHECK: @swap
%i = alloca i8
- %j = call i8 @llvm.atomic.swap.i8.p0i8(i8* %i, i8 42)
+ %j = atomicrmw xchg i8* %i, i8 42 monotonic
; CHECK: [[INST:%[a-z0-9]+]] = load
; CHECK-NEXT: store
ret i8 %j
diff --git a/test/Transforms/LowerAtomic/barrier.ll b/test/Transforms/LowerAtomic/barrier.ll
index 218c5ba8d18e8..814d7afb5ff9e 100644
--- a/test/Transforms/LowerAtomic/barrier.ll
+++ b/test/Transforms/LowerAtomic/barrier.ll
@@ -1,10 +1,8 @@
; RUN: opt < %s -loweratomic -S | FileCheck %s
-declare void @llvm.memory.barrier(i1 %ll, i1 %ls, i1 %sl, i1 %ss, i1 %device)
-
define void @barrier() {
; CHECK: @barrier
- call void @llvm.memory.barrier(i1 0, i1 0, i1 0, i1 0, i1 0)
+ fence seq_cst
; CHECK-NEXT: ret
ret void
}
diff --git a/test/Transforms/LowerSetJmp/2003-11-05-DominanceProperties.ll b/test/Transforms/LowerSetJmp/2003-11-05-DominanceProperties.ll
deleted file mode 100644
index 9180c15b18f2b..0000000000000
--- a/test/Transforms/LowerSetJmp/2003-11-05-DominanceProperties.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: opt < %s -lowersetjmp -disable-output
-
- %struct.jmpenv = type { i32, i8 }
-
-declare void @Perl_sv_setpv()
-
-declare i32 @llvm.setjmp(i32*)
-
-define void @perl_call_sv() {
- call void @Perl_sv_setpv( )
- %tmp.335 = getelementptr %struct.jmpenv* null, i64 0, i32 0 ; <i32*> [#uses=1]
- %tmp.336 = call i32 @llvm.setjmp( i32* null ) ; <i32> [#uses=1]
- store i32 %tmp.336, i32* %tmp.335
- ret void
-}
-
diff --git a/test/Transforms/LowerSetJmp/dg.exp b/test/Transforms/LowerSetJmp/dg.exp
deleted file mode 100644
index f2005891a59a8..0000000000000
--- a/test/Transforms/LowerSetJmp/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/test/Transforms/LowerSetJmp/simpletest.ll b/test/Transforms/LowerSetJmp/simpletest.ll
deleted file mode 100644
index dece8405f28dd..0000000000000
--- a/test/Transforms/LowerSetJmp/simpletest.ll
+++ /dev/null
@@ -1,31 +0,0 @@
-; RUN: opt < %s -lowersetjmp -S | grep invoke
-
-@.str_1 = internal constant [13 x i8] c"returned %d\0A\00" ; <[13 x i8]*> [#uses=1]
-
-declare void @llvm.longjmp(i32*, i32)
-
-declare i32 @llvm.setjmp(i32*)
-
-declare void @foo()
-
-define i32 @simpletest() {
- %B = alloca i32 ; <i32*> [#uses=2]
- %Val = call i32 @llvm.setjmp( i32* %B ) ; <i32> [#uses=2]
- %V = icmp ne i32 %Val, 0 ; <i1> [#uses=1]
- br i1 %V, label %LongJumped, label %Normal
-Normal: ; preds = %0
- call void @foo( )
- call void @llvm.longjmp( i32* %B, i32 42 )
- ret i32 0
-LongJumped: ; preds = %0
- ret i32 %Val
-}
-
-declare i32 @printf(i8*, ...)
-
-define i32 @main() {
- %V = call i32 @simpletest( ) ; <i32> [#uses=1]
- call i32 (i8*, ...)* @printf( i8* getelementptr ([13 x i8]* @.str_1, i64 0, i64 0), i32 %V ) ; <i32>:1 [#uses=0]
- ret i32 0
-}
-
diff --git a/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll b/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
index 50683cf8baa0d..52a8375312961 100644
--- a/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
+++ b/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
@@ -42,6 +42,6 @@ return: ; preds = %bb6
ret i32 %retval8
}
-declare i32 @_setjmp(%struct.__jmp_buf_tag*)
+declare i32 @_setjmp(%struct.__jmp_buf_tag*) returns_twice
declare void @g()
diff --git a/test/Transforms/Mem2Reg/atomic.ll b/test/Transforms/Mem2Reg/atomic.ll
new file mode 100644
index 0000000000000..982c41318b105
--- /dev/null
+++ b/test/Transforms/Mem2Reg/atomic.ll
@@ -0,0 +1,12 @@
+; RUN: opt -mem2reg < %s -S | FileCheck %s
+
+; mem2reg is allowed with arbitrary atomic operations (although we only support
+; it for atomic load and store at the moment).
+define i32 @test1(i32 %x) {
+; CHECK: @test1
+; CHECK: ret i32 %x
+ %a = alloca i32
+ store atomic i32 %x, i32* %a seq_cst, align 4
+ %r = load atomic i32* %a seq_cst, align 4
+ ret i32 %r
+}
diff --git a/test/Transforms/Mem2Reg/crash.ll b/test/Transforms/Mem2Reg/crash.ll
index 655549f79402c..59e2c0b3108df 100644
--- a/test/Transforms/Mem2Reg/crash.ll
+++ b/test/Transforms/Mem2Reg/crash.ll
@@ -18,10 +18,13 @@ bb15:
ret i32 %B
lpad86:
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
br label %bb15
}
+declare i32 @__gxx_personality_v0(...)
define i32 @test2() {
diff --git a/test/Transforms/MemCpyOpt/atomic.ll b/test/Transforms/MemCpyOpt/atomic.ll
new file mode 100644
index 0000000000000..f351e6792e225
--- /dev/null
+++ b/test/Transforms/MemCpyOpt/atomic.ll
@@ -0,0 +1,41 @@
+; RUN: opt -basicaa -memcpyopt -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-macosx10.7.0"
+
+@x = global i32 0
+
+declare void @otherf(i32*)
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; memcpyopt should not touch atomic ops
+define void @test1() nounwind uwtable ssp {
+; CHECK: test1
+; CHECK: store atomic
+ %x = alloca [101 x i32], align 16
+ %bc = bitcast [101 x i32]* %x to i8*
+ call void @llvm.memset.p0i8.i64(i8* %bc, i8 0, i64 400, i32 16, i1 false)
+ %gep1 = getelementptr inbounds [101 x i32]* %x, i32 0, i32 100
+ store atomic i32 0, i32* %gep1 unordered, align 4
+ %gep2 = getelementptr inbounds [101 x i32]* %x, i32 0, i32 0
+ call void @otherf(i32* %gep2)
+ ret void
+}
+
+; memcpyopt across unordered store
+define void @test2() nounwind uwtable ssp {
+; CHECK: test2
+; CHECK: call
+; CHECK-NEXT: store atomic
+; CHECK-NEXT: call
+ %old = alloca i32
+ %new = alloca i32
+ call void @otherf(i32* nocapture %old)
+ store atomic i32 0, i32* @x unordered, align 4
+ %v = load i32* %old
+ store i32 %v, i32* %new
+ call void @otherf(i32* nocapture %new)
+ ret void
+}
+
diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll
index a6bbf8674b418..575cf42d4e65b 100644
--- a/test/Transforms/ObjCARC/basic.ll
+++ b/test/Transforms/ObjCARC/basic.ll
@@ -353,13 +353,14 @@ entry:
; CHECK: define void @test10(
; CHECK: @objc_retain(i8* %x)
+; CHECK: @callee
; CHECK: @use_pointer
; CHECK: @objc_release
; CHECK: }
define void @test10(i8* %x) nounwind {
entry:
%0 = call i8* @objc_retain(i8* %x) nounwind
- call void @use_pointer(i8* %x)
+ call void @callee()
call void @use_pointer(i8* %x)
call void @objc_release(i8* %0) nounwind
ret void
@@ -697,6 +698,8 @@ invoke.cont23: ; preds = %if.then12
lpad20: ; preds = %invoke.cont23, %if.then12
%tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ]
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
unreachable
if.end: ; preds = %invoke.cont23
@@ -768,7 +771,7 @@ entry:
define void @test23b(i8* %p) {
entry:
%0 = call i8* @objc_retainBlock(i8* %p) nounwind
- call void @use_pointer(i8* %p)
+ call void @callee()
call void @use_pointer(i8* %p)
call void @objc_release(i8* %p) nounwind
ret void
@@ -1569,6 +1572,107 @@ if.end: ; preds = %entry, %if.then
ret void
}
+; When there are adjacent retain+release pairs, the first one is
+; known unnecessary because the presence of the second one means that
+; the first one won't be deleting the object.
+
+; CHECK: define void @test57(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: call void @objc_release(i8* %x) nounwind
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test57(i8* %x) nounwind {
+entry:
+ call i8* @objc_retain(i8* %x) nounwind
+ call void @use_pointer(i8* %x)
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
+ call i8* @objc_retain(i8* %x) nounwind
+ call void @use_pointer(i8* %x)
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
+ ret void
+}
+
+; An adjacent retain+release pair is sufficient even if it will be
+; removed itself.
+
+; CHECK: define void @test58(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test58(i8* %x) nounwind {
+entry:
+ call i8* @objc_retain(i8* %x) nounwind
+ call void @use_pointer(i8* %x)
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
+ call i8* @objc_retain(i8* %x) nounwind
+ call void @objc_release(i8* %x) nounwind
+ ret void
+}
+
+; Don't delete the second retain+release pair in an adjacent set.
+
+; CHECK: define void @test59(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: call void @use_pointer(i8* %x)
+; CHECK-NEXT: call void @objc_release(i8* %x) nounwind
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test59(i8* %x) nounwind {
+entry:
+ %a = call i8* @objc_retain(i8* %x) nounwind
+ call void @objc_release(i8* %x) nounwind
+ %b = call i8* @objc_retain(i8* %x) nounwind
+ call void @use_pointer(i8* %x)
+ call void @use_pointer(i8* %x)
+ call void @objc_release(i8* %x) nounwind
+ ret void
+}
+
+; Constant pointers to objects don't need reference counting.
+
+@constptr = external constant i8*
+@something = external global i8*
+
+; CHECK: define void @test60(
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test60() {
+ %t = load i8** @constptr
+ %s = load i8** @something
+ call i8* @objc_retain(i8* %s)
+ call void @callee()
+ call void @use_pointer(i8* %t)
+ call void @objc_release(i8* %s)
+ ret void
+}
+
+; Constant pointers to objects don't need to be considered related to other
+; pointers.
+
+; CHECK: define void @test61(
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test61() {
+ %t = load i8** @constptr
+ call i8* @objc_retain(i8* %t)
+ call void @callee()
+ call void @use_pointer(i8* %t)
+ call void @objc_release(i8* %t)
+ ret void
+}
+
declare void @bar(i32 ()*)
; A few real-world testcases.
@@ -1896,3 +2000,5 @@ end: ; preds = %if.end125, %if.end1
}
!0 = metadata !{}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/ObjCARC/cfg-hazards.ll b/test/Transforms/ObjCARC/cfg-hazards.ll
index e3624df57be86..15194237c4c59 100644
--- a/test/Transforms/ObjCARC/cfg-hazards.ll
+++ b/test/Transforms/ObjCARC/cfg-hazards.ll
@@ -7,6 +7,7 @@
declare void @use_pointer(i8*)
declare i8* @objc_retain(i8*)
declare void @objc_release(i8*)
+declare void @callee()
; CHECK: define void @test0(
; CHECK: call i8* @objc_retain(
@@ -18,18 +19,18 @@ declare void @objc_release(i8*)
define void @test0(i8* %digits) {
entry:
%tmp1 = call i8* @objc_retain(i8* %digits) nounwind
- call void @use_pointer(i8* %tmp1)
+ call void @use_pointer(i8* %digits)
br label %for.body
for.body: ; preds = %for.body, %entry
%upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]
- call void @use_pointer(i8* %tmp1)
+ call void @use_pointer(i8* %digits)
%inc = add i64 %upcDigitIndex.01, 1
%cmp = icmp ult i64 %inc, 12
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body
- call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0
+ call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0
ret void
}
@@ -47,14 +48,14 @@ entry:
for.body: ; preds = %for.body, %entry
%upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]
- call void @use_pointer(i8* %tmp1)
- call void @use_pointer(i8* %tmp1)
+ call void @use_pointer(i8* %digits)
+ call void @use_pointer(i8* %digits)
%inc = add i64 %upcDigitIndex.01, 1
%cmp = icmp ult i64 %inc, 12
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body
- call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0
+ call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0
ret void
}
@@ -72,14 +73,324 @@ entry:
for.body: ; preds = %for.body, %entry
%upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]
- call void @use_pointer(i8* %tmp1)
+ call void @use_pointer(i8* %digits)
%inc = add i64 %upcDigitIndex.01, 1
%cmp = icmp ult i64 %inc, 12
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body
- call void @use_pointer(i8* %tmp1)
- call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0
+ call void @use_pointer(i8* %digits)
+ call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete nested retain+release pairs around loops.
+
+; CHECK: define void @test3(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @objc_release(i8* %a)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test3(i8* %a) nounwind {
+entry:
+ %outer = call i8* @objc_retain(i8* %a) nounwind
+ %inner = call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ call void @callee()
+ store i8 0, i8* %a
+ br i1 undef, label %loop, label %exit
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test4(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @objc_release(i8* %a)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test4(i8* %a) nounwind {
+entry:
+ %outer = call i8* @objc_retain(i8* %a) nounwind
+ %inner = call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br label %more
+
+more:
+ call void @callee()
+ call void @callee()
+ store i8 0, i8* %a
+ br i1 undef, label %loop, label %exit
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test5(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: call void @callee()
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @use_pointer(i8* %a)
+; CHECK-NEXT: call void @objc_release(i8* %a)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test5(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ call void @callee()
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @use_pointer(i8* %a)
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test6(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @use_pointer(i8* %a)
+; CHECK-NEXT: call void @objc_release(i8* %a)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test6(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ call void @callee()
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @use_pointer(i8* %a)
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test7(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: call void @callee()
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @objc_release(i8* %a)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test7(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ call void @callee()
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ call void @use_pointer(i8* %a)
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test8(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @objc_release(i8* %a)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test8(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ call void @callee()
+ call void @use_pointer(i8* %a)
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test9(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test9(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ call void @use_pointer(i8* %a)
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test10(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test10(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ call void @callee()
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; CHECK: define void @test11(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test11(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ br label %more
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Don't delete anything if they're not balanced.
+
+; CHECK: define void @test12(i8* %a) nounwind {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %outer = tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: %inner = tail call i8* @objc_retain(i8* %a) nounwind
+; CHECK-NEXT: br label %loop
+; CHECK-NOT: @objc_
+; CHECK: exit:
+; CHECK-NEXT: call void @objc_release(i8* %a) nounwind
+; CHECK-NEXT: call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test12(i8* %a) nounwind {
+entry:
+ %outer = tail call i8* @objc_retain(i8* %a) nounwind
+ %inner = tail call i8* @objc_retain(i8* %a) nounwind
+ br label %loop
+
+loop:
+ br i1 undef, label %true, label %more
+
+true:
+ ret void
+
+more:
+ br i1 undef, label %exit, label %loop
+
+exit:
+ call void @objc_release(i8* %a) nounwind
+ call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
ret void
}
diff --git a/test/Transforms/ObjCARC/contract-storestrong.ll b/test/Transforms/ObjCARC/contract-storestrong.ll
index 50ed260eb0865..25c93f411c8db 100644
--- a/test/Transforms/ObjCARC/contract-storestrong.ll
+++ b/test/Transforms/ObjCARC/contract-storestrong.ll
@@ -25,7 +25,7 @@ entry:
; CHECK: define void @test1(i8* %p) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) nounwind
-; CHECK-NEXT: %tmp = volatile load i8** @x, align 8
+; CHECK-NEXT: %tmp = load volatile i8** @x, align 8
; CHECK-NEXT: store i8* %0, i8** @x, align 8
; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind
; CHECK-NEXT: ret void
@@ -45,7 +45,7 @@ entry:
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) nounwind
; CHECK-NEXT: %tmp = load i8** @x, align 8
-; CHECK-NEXT: volatile store i8* %0, i8** @x, align 8
+; CHECK-NEXT: store volatile i8* %0, i8** @x, align 8
; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind
; CHECK-NEXT: ret void
; CHECK-NEXT: }
diff --git a/test/Transforms/ObjCARC/empty-block.ll b/test/Transforms/ObjCARC/empty-block.ll
new file mode 100644
index 0000000000000..ca5541365a4ec
--- /dev/null
+++ b/test/Transforms/ObjCARC/empty-block.ll
@@ -0,0 +1,59 @@
+; RUN: opt -S -objc-arc < %s | FileCheck %s
+; rdar://10210274
+
+%0 = type opaque
+
+declare i8* @objc_retain(i8*)
+
+declare void @objc_release(i8*)
+
+declare i8* @objc_autoreleaseReturnValue(i8*)
+
+; Don't delete the autorelease.
+
+; CHECK: define %0* @test0(
+; CHECK: @objc_retain
+; CHECK: .lr.ph:
+; CHECK-NOT: @objc_r
+; CHECK: @objc_autoreleaseReturnValue
+; CHECK-NOT: @objc_
+; CHECK: }
+define %0* @test0(%0* %buffer) nounwind {
+ %1 = bitcast %0* %buffer to i8*
+ %2 = tail call i8* @objc_retain(i8* %1) nounwind
+ br i1 undef, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %.lr.ph, %0
+ br i1 false, label %.lr.ph, label %._crit_edge
+
+._crit_edge: ; preds = %.lr.ph, %0
+ %3 = tail call i8* @objc_retain(i8* %1) nounwind
+ tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
+ %4 = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind
+ ret %0* %buffer
+}
+
+; Do delete the autorelease, even with the retain in a different block.
+
+; CHECK: define %0* @test1(
+; CHECK-NOT: @objc
+; CHECK: }
+define %0* @test1() nounwind {
+ %buffer = call %0* @foo()
+ %1 = bitcast %0* %buffer to i8*
+ %2 = tail call i8* @objc_retain(i8* %1) nounwind
+ br i1 undef, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %.lr.ph, %0
+ br i1 false, label %.lr.ph, label %._crit_edge
+
+._crit_edge: ; preds = %.lr.ph, %0
+ %3 = tail call i8* @objc_retain(i8* %1) nounwind
+ tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
+ %4 = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind
+ ret %0* %buffer
+}
+
+declare %0* @foo()
+
+!0 = metadata !{}
diff --git a/test/Transforms/ObjCARC/invoke.ll b/test/Transforms/ObjCARC/invoke.ll
index a1b87d230bd26..cf971e458aaa5 100644
--- a/test/Transforms/ObjCARC/invoke.ll
+++ b/test/Transforms/ObjCARC/invoke.ll
@@ -27,6 +27,8 @@ invoke.cont: ; preds = %entry
ret void
lpad: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
ret void
}
@@ -56,6 +58,8 @@ invoke.cont: ; preds = %entry
br label %done
lpad: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
call void @callee()
br label %done
@@ -64,4 +68,6 @@ done:
ret void
}
+declare i32 @__gxx_personality_v0(...)
+
!0 = metadata !{}
diff --git a/test/Transforms/ObjCARC/nested.ll b/test/Transforms/ObjCARC/nested.ll
new file mode 100644
index 0000000000000..9eada8a2ddbaa
--- /dev/null
+++ b/test/Transforms/ObjCARC/nested.ll
@@ -0,0 +1,620 @@
+; RUN: opt -objc-arc -S < %s | FileCheck %s
+
+%struct.__objcFastEnumerationState = type { i64, i8**, i64*, [5 x i64] }
+
+@"\01L_OBJC_METH_VAR_NAME_" = internal global [43 x i8] c"countByEnumeratingWithState:objects:count:\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([43 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
+@g = common global i8* null, align 8
+@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
+
+declare void @callee()
+declare i8* @returner()
+declare i8* @objc_retainAutoreleasedReturnValue(i8*)
+declare i8* @objc_retain(i8*)
+declare void @objc_enumerationMutation(i8*)
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
+declare void @use(i8*)
+declare void @objc_release(i8*)
+
+!0 = metadata !{}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test0(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test0(i8* %a) nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %0 = call i8* @objc_retain(i8* %a) nounwind
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call, %forcoll.loopinit ], [ %call6, %forcoll.refetch ]
+ %tmp7 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp7, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
+ %mutationsptr3 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr3, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ call void @use(i8* %3)
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call6 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp5, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call6, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test2(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test2() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call3, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
+ %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr4, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ call void @use(i8* %3)
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call7, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test4(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test4() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %tmp = load i8** @g, align 8
+ %0 = call i8* @objc_retain(i8* %tmp) nounwind
+ %tmp2 = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp2, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp4 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp4, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call, %forcoll.loopinit ], [ %call8, %forcoll.refetch ]
+ %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
+ %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr5, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ call void @use(i8* %3)
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp7 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call8 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp7, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call8, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test5(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test5() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ call void @callee()
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call3, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
+ %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr4, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ call void @use(i8* %3)
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call7, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test6(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test6() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call3, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
+ %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr4, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ call void @use(i8* %3)
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call7, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @callee()
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test7(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test7() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ call void @callee()
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call3, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
+ %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr4, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ call void @use(i8* %3)
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call7, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @callee()
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test8(
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test8() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %1 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call3, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.next ]
+ %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr4, align 8
+ %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %1)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %stateitems = load i8*** %stateitems.ptr, align 8
+ %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
+ %3 = load i8** %currentitem.ptr, align 8
+ %tobool = icmp eq i8* %3, null
+ br i1 %tobool, label %forcoll.next, label %if.then
+
+if.then:
+ call void @callee()
+ br label %forcoll.next
+
+forcoll.next:
+ %4 = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %4, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %5 = icmp eq i64 %call7, 0
+ br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %1) nounwind
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test9(
+; CHECK: call i8* @objc_retain
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test9() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ %call1 = call i8* @returner()
+ %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) nounwind
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %2 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call4 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp3, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call4, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call4, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ %phitmp, %forcoll.notmutated.forcoll.loopbody_crit_edge ], [ 1, %forcoll.loopbody.outer ]
+ %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr5, align 8
+ %3 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %3, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %2)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %exitcond = icmp eq i64 %forcoll.index, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.notmutated.forcoll.loopbody_crit_edge
+
+forcoll.notmutated.forcoll.loopbody_crit_edge:
+ %phitmp = add i64 %forcoll.index, 1
+ br label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %4 = icmp eq i64 %call7, 0
+ br i1 %4, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %2) nounwind
+ call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Delete a nested retain+release pair.
+
+; CHECK: define void @test10(
+; CHECK: call i8* @objc_retain
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test10() nounwind {
+entry:
+ %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
+ %items.ptr = alloca [16 x i8*], align 8
+ %call = call i8* @returner()
+ %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ %call1 = call i8* @returner()
+ %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) nounwind
+ call void @callee()
+ %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
+ call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
+ %2 = call i8* @objc_retain(i8* %0) nounwind
+ %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call4 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp3, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %iszero = icmp eq i64 %call4, 0
+ br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
+
+forcoll.loopinit:
+ %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
+ %mutationsptr = load i64** %mutationsptr.ptr, align 8
+ %forcoll.initial-mutations = load i64* %mutationsptr, align 8
+ br label %forcoll.loopbody.outer
+
+forcoll.loopbody.outer:
+ %forcoll.count.ph = phi i64 [ %call4, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
+ %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
+ %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
+ br label %forcoll.loopbody
+
+forcoll.loopbody:
+ %forcoll.index = phi i64 [ %phitmp, %forcoll.notmutated.forcoll.loopbody_crit_edge ], [ 1, %forcoll.loopbody.outer ]
+ %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
+ %statemutations = load i64* %mutationsptr5, align 8
+ %3 = icmp eq i64 %statemutations, %forcoll.initial-mutations
+ br i1 %3, label %forcoll.notmutated, label %forcoll.mutated
+
+forcoll.mutated:
+ call void @objc_enumerationMutation(i8* %2)
+ br label %forcoll.notmutated
+
+forcoll.notmutated:
+ %exitcond = icmp eq i64 %forcoll.index, %umax
+ br i1 %exitcond, label %forcoll.refetch, label %forcoll.notmutated.forcoll.loopbody_crit_edge
+
+forcoll.notmutated.forcoll.loopbody_crit_edge:
+ %phitmp = add i64 %forcoll.index, 1
+ br label %forcoll.loopbody
+
+forcoll.refetch:
+ %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
+ %4 = icmp eq i64 %call7, 0
+ br i1 %4, label %forcoll.empty, label %forcoll.loopbody.outer
+
+forcoll.empty:
+ call void @objc_release(i8* %2) nounwind
+ call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
+ call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
+ ret void
+}
diff --git a/test/Transforms/ObjCARC/retain-block-alloca.ll b/test/Transforms/ObjCARC/retain-block-alloca.ll
new file mode 100644
index 0000000000000..468da9147adb4
--- /dev/null
+++ b/test/Transforms/ObjCARC/retain-block-alloca.ll
@@ -0,0 +1,54 @@
+; RUN: opt -S -objc-arc < %s | FileCheck %s
+; rdar://10209613
+
+; CHECK: define void @test
+; CHECK: %3 = call i8* @objc_retainBlock(i8* %2) nounwind
+; CHECK: @objc_msgSend
+; CHECK-NEXT: @objc_release(i8* %3)
+
+%0 = type opaque
+%struct.__block_descriptor = type { i64, i64 }
+
+@_NSConcreteStackBlock = external global i8*
+@__block_descriptor_tmp = external hidden constant { i64, i64, i8*, i8*, i8*, i8* }
+@"\01L_OBJC_SELECTOR_REFERENCES_" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
+
+define void @test(%0* %array) uwtable {
+entry:
+ %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>, align 8
+ %0 = bitcast %0* %array to i8*
+ %1 = tail call i8* @objc_retain(i8* %0) nounwind
+ %block.isa = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block, i64 0, i32 0
+ store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** %block.isa, align 8
+ %block.flags = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block, i64 0, i32 1
+ store i32 1107296256, i32* %block.flags, align 8
+ %block.reserved = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block, i64 0, i32 2
+ store i32 0, i32* %block.reserved, align 4
+ %block.invoke = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block, i64 0, i32 3
+ store i8* bitcast (void (i8*)* @__test_block_invoke_0 to i8*), i8** %block.invoke, align 8
+ %block.descriptor = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block, i64 0, i32 4
+ store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @__block_descriptor_tmp to %struct.__block_descriptor*), %struct.__block_descriptor** %block.descriptor, align 8
+ %block.captured = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block, i64 0, i32 5
+ store %0* %array, %0** %block.captured, align 8
+ %2 = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %block to i8*
+ %3 = call i8* @objc_retainBlock(i8* %2) nounwind
+ %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
+ call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* %0, i8* %tmp2, i8* %3)
+ call void @objc_release(i8* %3) nounwind
+ %strongdestroy = load %0** %block.captured, align 8
+ %4 = bitcast %0* %strongdestroy to i8*
+ call void @objc_release(i8* %4) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+declare i8* @objc_retain(i8*)
+
+declare void @__test_block_invoke_0(i8* nocapture) uwtable
+
+declare i8* @objc_retainBlock(i8*)
+
+declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
+
+declare void @objc_release(i8*)
+
+!0 = metadata !{}
diff --git a/test/Transforms/ObjCARC/retain-block-side-effects.ll b/test/Transforms/ObjCARC/retain-block-side-effects.ll
new file mode 100644
index 0000000000000..e84d48f86912d
--- /dev/null
+++ b/test/Transforms/ObjCARC/retain-block-side-effects.ll
@@ -0,0 +1,39 @@
+; RUN: opt -S -objc-arc-aa -basicaa -gvn < %s | FileCheck %s
+; rdar://10050579
+
+; objc_retainBlock stores into %repeater so the load from after the
+; call isn't forwardable from the store before the call.
+
+; CHECK: %tmp16 = call i8* @objc_retainBlock(i8* %tmp15) nounwind
+; CHECK: %tmp17 = bitcast i8* %tmp16 to void ()*
+; CHECK: %tmp18 = load %struct.__block_byref_repeater** %byref.forwarding, align 8
+; CHECK: %repeater12 = getelementptr inbounds %struct.__block_byref_repeater* %tmp18, i64 0, i32 6
+; CHECK: store void ()* %tmp17, void ()** %repeater12, align 8
+
+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"
+
+%0 = type opaque
+%struct.__block_byref_repeater = type { i8*, %struct.__block_byref_repeater*, i32, i32, i8*, i8*, void ()* }
+%struct.__block_descriptor = type { i64, i64 }
+
+define void @foo() noreturn {
+entry:
+ %repeater = alloca %struct.__block_byref_repeater, align 8
+ %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i8* }>, align 8
+ %byref.forwarding = getelementptr inbounds %struct.__block_byref_repeater* %repeater, i64 0, i32 1
+ %tmp10 = getelementptr inbounds %struct.__block_byref_repeater* %repeater, i64 0, i32 6
+ store void ()* null, void ()** %tmp10, align 8
+ %block.captured11 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i8* }>* %block, i64 0, i32 6
+ %tmp14 = bitcast %struct.__block_byref_repeater* %repeater to i8*
+ store i8* %tmp14, i8** %block.captured11, align 8
+ %tmp15 = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i8* }>* %block to i8*
+ %tmp16 = call i8* @objc_retainBlock(i8* %tmp15) nounwind
+ %tmp17 = bitcast i8* %tmp16 to void ()*
+ %tmp18 = load %struct.__block_byref_repeater** %byref.forwarding, align 8
+ %repeater12 = getelementptr inbounds %struct.__block_byref_repeater* %tmp18, i64 0, i32 6
+ %tmp13 = load void ()** %repeater12, align 8
+ store void ()* %tmp17, void ()** %repeater12, align 8
+ ret void
+}
+
+declare i8* @objc_retainBlock(i8*)
diff --git a/test/Transforms/ObjCARC/retain-not-declared.ll b/test/Transforms/ObjCARC/retain-not-declared.ll
index e1fe1170633c9..41bde017e7770 100644
--- a/test/Transforms/ObjCARC/retain-not-declared.ll
+++ b/test/Transforms/ObjCARC/retain-not-declared.ll
@@ -1,21 +1,23 @@
; RUN: opt -S -objc-arc -objc-arc-contract < %s | FileCheck %s
-; Test that the optimizer can create an objc_retainAutoreleaseReturnValue
-; declaration even if no objc_retain declaration exists.
-; rdar://9401303
-
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"
declare i8* @objc_unretainedObject(i8*)
declare i8* @objc_retainAutoreleasedReturnValue(i8*)
declare i8* @objc_autoreleaseReturnValue(i8*)
+declare i8* @objc_msgSend(i8*, i8*, ...)
+declare void @objc_release(i8*)
-; CHECK: define i8* @foo(i8* %p) {
+; Test that the optimizer can create an objc_retainAutoreleaseReturnValue
+; declaration even if no objc_retain declaration exists.
+; rdar://9401303
+
+; CHECK: define i8* @test0(i8* %p) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %p) nounwind
; CHECK-NEXT: ret i8* %0
; CHECK-NEXT: }
-define i8* @foo(i8* %p) {
+define i8* @test0(i8* %p) {
entry:
%call = tail call i8* @objc_unretainedObject(i8* %p)
%0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
@@ -23,3 +25,43 @@ entry:
ret i8* %1
}
+; Properly create the @objc_retain declaration when it doesn't already exist.
+; rdar://9825114
+
+; CHECK: @test1(
+; CHECK: @objc_retain(
+; CHECK: @objc_retain(
+; CHECK: @objc_release(
+; CHECK: @objc_release(
+; CHECK: }
+define void @test1(i8* %call88) nounwind {
+entry:
+ %tmp1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call88) nounwind
+ %call94 = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*)*)(i8* %tmp1)
+ to label %invoke.cont93 unwind label %lpad91
+
+invoke.cont93: ; preds = %entry
+ %tmp2 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call94) nounwind
+ call void @objc_release(i8* %tmp1) nounwind
+ invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %tmp2)
+ to label %invoke.cont102 unwind label %lpad100
+
+invoke.cont102: ; preds = %invoke.cont93
+ call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ unreachable
+
+lpad91: ; preds = %entry
+ %exn91 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ unreachable
+
+lpad100: ; preds = %invoke.cont93
+ %exn100 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ unreachable
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+!0 = metadata !{}
diff --git a/test/Transforms/ObjCARC/rv.ll b/test/Transforms/ObjCARC/rv.ll
index da53a86b10fde..9353a19f71a44 100644
--- a/test/Transforms/ObjCARC/rv.ll
+++ b/test/Transforms/ObjCARC/rv.ll
@@ -329,3 +329,14 @@ define void @test23(i8* %p) {
call i8* @objc_autoreleaseReturnValue(i8* %p)
ret void
}
+
+; Don't convert autoreleaseRV to autorelease if the result is returned,
+; even through a bitcast.
+
+; CHECK: define {}* @test24(
+; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p)
+define {}* @test24(i8* %p) {
+ %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
+ %s = bitcast i8* %p to {}*
+ ret {}* %s
+}
diff --git a/test/Transforms/PhaseOrdering/2010-03-22-empty-baseclass.ll b/test/Transforms/PhaseOrdering/2010-03-22-empty-baseclass.ll
new file mode 100644
index 0000000000000..8859da8de106b
--- /dev/null
+++ b/test/Transforms/PhaseOrdering/2010-03-22-empty-baseclass.ll
@@ -0,0 +1,162 @@
+; RUN: opt -O2 %s -S -o - | 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-darwin11.1"
+
+%"struct.boost::compressed_pair<empty_t,int>" = type { %"struct.boost::details::compressed_pair_imp<empty_t,int,1>" }
+%"struct.boost::details::compressed_pair_imp<empty_t,int,1>" = type { i32 }
+%struct.empty_base_t = type <{ i8 }>
+%struct.empty_t = type <{ i8 }>
+
+@.str = private constant [25 x i8] c"x.second() was clobbered\00", align 1 ; <[25 x i8]*> [#uses=1]
+
+define i32 @main(i32 %argc, i8** %argv) ssp {
+entry:
+ %argc_addr = alloca i32, align 4 ; <i32*> [#uses=1]
+ %argv_addr = alloca i8**, align 8 ; <i8***> [#uses=1]
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %0 = alloca i32 ; <i32*> [#uses=2]
+ %retval.1 = alloca i8 ; <i8*> [#uses=2]
+ %1 = alloca %struct.empty_base_t ; <%struct.empty_base_t*> [#uses=1]
+ %2 = alloca %struct.empty_base_t* ; <%struct.empty_base_t**> [#uses=1]
+ %x = alloca %"struct.boost::compressed_pair<empty_t,int>" ; <%"struct.boost::compressed_pair<empty_t,int>"*> [#uses=3]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i32 %argc, i32* %argc_addr
+ store i8** %argv, i8*** %argv_addr
+ %3 = call i32* @_ZN5boost15compressed_pairI7empty_tiE6secondEv(%"struct.boost::compressed_pair<empty_t,int>"* %x) ssp ; <i32*> [#uses=1]
+ store i32 -3, i32* %3, align 4
+ %4 = call %struct.empty_base_t* @_ZN5boost15compressed_pairI7empty_tiE5firstEv(%"struct.boost::compressed_pair<empty_t,int>"* %x) ssp ; <%struct.empty_base_t*> [#uses=1]
+ store %struct.empty_base_t* %4, %struct.empty_base_t** %2, align 8
+ call void @_ZN7empty_tC1Ev(%struct.empty_base_t* %1) nounwind
+ %5 = call i32* @_ZN5boost15compressed_pairI7empty_tiE6secondEv(%"struct.boost::compressed_pair<empty_t,int>"* %x) ssp ; <i32*> [#uses=1]
+ %6 = load i32* %5, align 4 ; <i32> [#uses=1]
+ %7 = icmp ne i32 %6, -3 ; <i1> [#uses=1]
+ %8 = zext i1 %7 to i8 ; <i8> [#uses=1]
+ store i8 %8, i8* %retval.1, align 1
+ %9 = load i8* %retval.1, align 1 ; <i8> [#uses=1]
+ %toBool = icmp ne i8 %9, 0 ; <i1> [#uses=1]
+ br i1 %toBool, label %bb, label %bb1
+
+bb: ; preds = %entry
+ %10 = call i32 @puts(i8* getelementptr inbounds ([25 x i8]* @.str, i64 0, i64 0)) ; <i32> [#uses=0]
+ call void @abort() noreturn
+ unreachable
+
+bb1: ; preds = %entry
+ store i32 0, i32* %0, align 4
+ %11 = load i32* %0, align 4 ; <i32> [#uses=1]
+ store i32 %11, i32* %retval, align 4
+ br label %return
+
+; CHECK-NOT: x.second() was clobbered
+; CHECK: ret i32
+return: ; preds = %bb1
+ %retval2 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval2
+}
+
+define linkonce_odr void @_ZN12empty_base_tC2Ev(%struct.empty_base_t* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %struct.empty_base_t*, align 8 ; <%struct.empty_base_t**> [#uses=1]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %struct.empty_base_t* %this, %struct.empty_base_t** %this_addr
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+define linkonce_odr void @_ZN7empty_tC1Ev(%struct.empty_base_t* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %struct.empty_base_t*, align 8 ; <%struct.empty_base_t**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %struct.empty_base_t* %this, %struct.empty_base_t** %this_addr
+ %0 = load %struct.empty_base_t** %this_addr, align 8 ; <%struct.empty_base_t*> [#uses=1]
+ call void @_ZN12empty_base_tC2Ev(%struct.empty_base_t* %0) nounwind
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+define linkonce_odr i32* @_ZN5boost7details19compressed_pair_impI7empty_tiLi1EE6secondEv(%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"*, align 8 ; <%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"**> [#uses=2]
+ %retval = alloca i32* ; <i32**> [#uses=2]
+ %0 = alloca i32* ; <i32**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %this, %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"** %this_addr
+ %1 = load %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"** %this_addr, align 8 ; <%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"*> [#uses=1]
+ %2 = getelementptr inbounds %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %1, i32 0, i32 0 ; <i32*> [#uses=1]
+ store i32* %2, i32** %0, align 8
+ %3 = load i32** %0, align 8 ; <i32*> [#uses=1]
+ store i32* %3, i32** %retval, align 8
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load i32** %retval ; <i32*> [#uses=1]
+ ret i32* %retval1
+}
+
+define linkonce_odr i32* @_ZN5boost15compressed_pairI7empty_tiE6secondEv(%"struct.boost::compressed_pair<empty_t,int>"* %this) ssp align 2 {
+entry:
+ %this_addr = alloca %"struct.boost::compressed_pair<empty_t,int>"*, align 8 ; <%"struct.boost::compressed_pair<empty_t,int>"**> [#uses=2]
+ %retval = alloca i32* ; <i32**> [#uses=2]
+ %0 = alloca i32* ; <i32**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %"struct.boost::compressed_pair<empty_t,int>"* %this, %"struct.boost::compressed_pair<empty_t,int>"** %this_addr
+ %1 = load %"struct.boost::compressed_pair<empty_t,int>"** %this_addr, align 8 ; <%"struct.boost::compressed_pair<empty_t,int>"*> [#uses=1]
+ %2 = getelementptr inbounds %"struct.boost::compressed_pair<empty_t,int>"* %1, i32 0, i32 0 ; <%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"*> [#uses=1]
+ %3 = call i32* @_ZN5boost7details19compressed_pair_impI7empty_tiLi1EE6secondEv(%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %2) nounwind ; <i32*> [#uses=1]
+ store i32* %3, i32** %0, align 8
+ %4 = load i32** %0, align 8 ; <i32*> [#uses=1]
+ store i32* %4, i32** %retval, align 8
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load i32** %retval ; <i32*> [#uses=1]
+ ret i32* %retval1
+}
+
+define linkonce_odr %struct.empty_base_t* @_ZN5boost7details19compressed_pair_impI7empty_tiLi1EE5firstEv(%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %this) nounwind ssp align 2 {
+entry:
+ %this_addr = alloca %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"*, align 8 ; <%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"**> [#uses=2]
+ %retval = alloca %struct.empty_base_t* ; <%struct.empty_base_t**> [#uses=2]
+ %0 = alloca %struct.empty_base_t* ; <%struct.empty_base_t**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %this, %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"** %this_addr
+ %1 = load %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"** %this_addr, align 8 ; <%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"*> [#uses=1]
+ %2 = bitcast %"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %1 to %struct.empty_base_t* ; <%struct.empty_base_t*> [#uses=1]
+ store %struct.empty_base_t* %2, %struct.empty_base_t** %0, align 8
+ %3 = load %struct.empty_base_t** %0, align 8 ; <%struct.empty_base_t*> [#uses=1]
+ store %struct.empty_base_t* %3, %struct.empty_base_t** %retval, align 8
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load %struct.empty_base_t** %retval ; <%struct.empty_base_t*> [#uses=1]
+ ret %struct.empty_base_t* %retval1
+}
+
+define linkonce_odr %struct.empty_base_t* @_ZN5boost15compressed_pairI7empty_tiE5firstEv(%"struct.boost::compressed_pair<empty_t,int>"* %this) ssp align 2 {
+entry:
+ %this_addr = alloca %"struct.boost::compressed_pair<empty_t,int>"*, align 8 ; <%"struct.boost::compressed_pair<empty_t,int>"**> [#uses=2]
+ %retval = alloca %struct.empty_base_t* ; <%struct.empty_base_t**> [#uses=2]
+ %0 = alloca %struct.empty_base_t* ; <%struct.empty_base_t**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %"struct.boost::compressed_pair<empty_t,int>"* %this, %"struct.boost::compressed_pair<empty_t,int>"** %this_addr
+ %1 = load %"struct.boost::compressed_pair<empty_t,int>"** %this_addr, align 8 ; <%"struct.boost::compressed_pair<empty_t,int>"*> [#uses=1]
+ %2 = getelementptr inbounds %"struct.boost::compressed_pair<empty_t,int>"* %1, i32 0, i32 0 ; <%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"*> [#uses=1]
+ %3 = call %struct.empty_base_t* @_ZN5boost7details19compressed_pair_impI7empty_tiLi1EE5firstEv(%"struct.boost::details::compressed_pair_imp<empty_t,int,1>"* %2) nounwind ; <%struct.empty_base_t*> [#uses=1]
+ store %struct.empty_base_t* %3, %struct.empty_base_t** %0, align 8
+ %4 = load %struct.empty_base_t** %0, align 8 ; <%struct.empty_base_t*> [#uses=1]
+ store %struct.empty_base_t* %4, %struct.empty_base_t** %retval, align 8
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load %struct.empty_base_t** %retval ; <%struct.empty_base_t*> [#uses=1]
+ ret %struct.empty_base_t* %retval1
+}
+
+declare i32 @puts(i8*)
+
+declare void @abort() noreturn
diff --git a/test/Transforms/PruneEH/2003-09-14-ExternalCall.ll b/test/Transforms/PruneEH/2003-09-14-ExternalCall.ll
index 679eafd593630..64aba4610167e 100644
--- a/test/Transforms/PruneEH/2003-09-14-ExternalCall.ll
+++ b/test/Transforms/PruneEH/2003-09-14-ExternalCall.ll
@@ -6,6 +6,9 @@ define void @foo() {
invoke void @External( )
to label %Cont unwind label %Cont
Cont: ; preds = %0, %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret void
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll b/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll
index 9876375ae88a7..fb1926eca25bc 100644
--- a/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll
+++ b/test/Transforms/SCCP/2003-08-26-InvokeHandling.ll
@@ -8,11 +8,16 @@ Entry:
br i1 %cond, label %Inv, label %Cont
Inv: ; preds = %Entry
invoke void @foo( )
- to label %Ok unwind label %Cont
+ to label %Ok unwind label %LPad
Ok: ; preds = %Inv
br label %Cont
+LPad:
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
+ br label %Cont
Cont: ; preds = %Ok, %Inv, %Entry
- %X = phi i32 [ 0, %Entry ], [ 1, %Ok ], [ 0, %Inv ] ; <i32> [#uses=1]
+ %X = phi i32 [ 0, %Entry ], [ 1, %Ok ], [ 0, %LPad ] ; <i32> [#uses=1]
ret i32 %X
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll b/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll
index 5d2c78ef874c0..e7eb101c147aa 100644
--- a/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll
+++ b/test/Transforms/SCCP/2004-11-16-DeadInvoke.ll
@@ -6,8 +6,13 @@ define void @caller() {
br i1 true, label %T, label %F
F: ; preds = %0
%X = invoke i32 @foo( )
- to label %T unwind label %T ; <i32> [#uses=0]
-T: ; preds = %F, %F, %0
+ to label %T unwind label %LP ; <i32> [#uses=0]
+LP:
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
+ br label %T
+T:
ret void
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll b/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll
index b84fe6db2f21d..a5a42f1b40719 100644
--- a/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll
+++ b/test/Transforms/SCCP/2007-05-16-InvokeCrash.ll
@@ -31,7 +31,9 @@ bb149: ; preds = %bb114
bb177: ; preds = %bb149
unreachable
cleanup: ; preds = %bb149, %bb114, %bb67
- unwind
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ resume { i8*, i32 } %val
}
declare double @sin(double)
@@ -39,3 +41,5 @@ declare double @sin(double)
declare double @log(double)
declare double @sqrt(double)
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll b/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
index d23ee2b23d763..7546bf5cc7272 100644
--- a/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
+++ b/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
@@ -7,6 +7,8 @@ define i32 @main() {
to label %UnifiedReturnBlock unwind label %lpad
lpad:
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
unreachable
UnifiedReturnBlock:
diff --git a/test/Transforms/SCCP/atomic-load-store.ll b/test/Transforms/SCCP/atomic-load-store.ll
new file mode 100644
index 0000000000000..09061f0a6fd51
--- /dev/null
+++ b/test/Transforms/SCCP/atomic-load-store.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -ipsccp -S | FileCheck %s
+
+; This transformation is safe for atomic loads and stores; check that it works.
+
+@G = internal global i32 17
+@C = internal constant i32 222
+
+define i32 @test1() {
+ %V = load atomic i32* @G seq_cst, align 4
+ %C = icmp eq i32 %V, 17
+ br i1 %C, label %T, label %F
+T:
+ store atomic i32 17, i32* @G seq_cst, align 4
+ ret i32 %V
+F:
+ store atomic i32 123, i32* @G seq_cst, align 4
+ ret i32 0
+}
+; CHECK: define i32 @test1
+; CHECK-NOT: store
+; CHECK: ret i32 17
+
+define i32 @test2() {
+ %V = load atomic i32* @C seq_cst, align 4
+ ret i32 %V
+}
+
+; CHECK: define i32 @test2
+; CHECK-NOT: load
+; CHECK: ret i32 222
diff --git a/test/Transforms/SCCP/ipsccp-basic.ll b/test/Transforms/SCCP/ipsccp-basic.ll
index b9e3f42fdbded..8340f0c1e1273 100644
--- a/test/Transforms/SCCP/ipsccp-basic.ll
+++ b/test/Transforms/SCCP/ipsccp-basic.ll
@@ -90,6 +90,8 @@ A:
%c = call i64 @test4c(i64 %b)
ret i64 %c
B:
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
ret i64 0
}
; CHECK: define i64 @test4b()
@@ -121,6 +123,8 @@ A:
%c = call i64 @test5c({i64,i64} %a)
ret i64 %c
B:
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
ret i64 0
}
@@ -204,3 +208,22 @@ entry:
ret void
}
+declare i32 @__gxx_personality_v0(...)
+
+;;======================== test10
+
+define i32 @test10a() nounwind {
+entry:
+ %call = call i32 @test10b(i32 undef)
+ ret i32 %call
+; CHECK: define i32 @test10a
+; CHECK: ret i32 0
+}
+
+define internal i32 @test10b(i32 %x) nounwind {
+entry:
+ %r = and i32 %x, 1
+ ret i32 %r
+; CHECK: define internal i32 @test10b
+; CHECK: ret i32 undef
+}
diff --git a/test/Transforms/SCCP/switch.ll b/test/Transforms/SCCP/switch.ll
new file mode 100644
index 0000000000000..9f934237e6199
--- /dev/null
+++ b/test/Transforms/SCCP/switch.ll
@@ -0,0 +1,13 @@
+; RUN: opt -S -sccp < %s | FileCheck %s
+
+; Make sure we always consider the default edge executable for a switch
+; with no cases.
+declare void @foo()
+define void @test1() {
+; CHECK: define void @test1
+; CHECK: call void @foo()
+ switch i32 undef, label %d []
+d:
+ call void @foo()
+ ret void
+}
diff --git a/test/Transforms/SCCP/undef-resolve.ll b/test/Transforms/SCCP/undef-resolve.ll
index bed561c8e4f24..a3dddb799a6a0 100644
--- a/test/Transforms/SCCP/undef-resolve.ll
+++ b/test/Transforms/SCCP/undef-resolve.ll
@@ -104,3 +104,69 @@ bb1.us-lcssa: ; preds = %control
bb1: ; preds = %bb1.us-lcssa, %bb1.us-lcssa.us
ret i32 0
}
+
+; Make sure SCCP honors the xor "idiom"
+; rdar://9956541
+define i32 @test3() {
+ %t = xor i32 undef, undef
+ ret i32 %t
+; CHECK: @test3
+; CHECK: ret i32 0
+}
+
+; Be conservative with FP ops
+define double @test4(double %x) {
+ %t = fadd double %x, undef
+ ret double %t
+; CHECK: @test4
+; CHECK: fadd double %x, undef
+}
+
+; Make sure casts produce a possible value
+define i32 @test5() {
+ %t = sext i8 undef to i32
+ ret i32 %t
+; CHECK: @test5
+; CHECK: ret i32 0
+}
+
+; Make sure ashr produces a possible value
+define i32 @test6() {
+ %t = ashr i32 undef, 31
+ ret i32 %t
+; CHECK: @test6
+; CHECK: ret i32 -1
+}
+
+; Make sure lshr produces a possible value
+define i32 @test7() {
+ %t = lshr i32 undef, 31
+ ret i32 %t
+; CHECK: @test7
+; CHECK: ret i32 0
+}
+
+; icmp eq with undef simplifies to undef
+define i1 @test8() {
+ %t = icmp eq i32 undef, -1
+ ret i1 %t
+; CHECK: @test8
+; CHECK: ret i1 undef
+}
+
+; Make sure we don't conclude that relational comparisons simplify to undef
+define i1 @test9() {
+ %t = icmp ugt i32 undef, -1
+ ret i1 %t
+; CHECK: @test9
+; CHECK: icmp ugt
+}
+
+; Make sure we handle extractvalue
+define i64 @test10() {
+entry:
+ %e = extractvalue { i64, i64 } undef, 1
+ ret i64 %e
+; CHECK: @test10
+; CHECK: ret i64 undef
+}
diff --git a/test/Transforms/ScalarRepl/2003-10-29-ArrayProblem.ll b/test/Transforms/ScalarRepl/2003-10-29-ArrayProblem.ll
index d75498716df01..00e43a79043d0 100644
--- a/test/Transforms/ScalarRepl/2003-10-29-ArrayProblem.ll
+++ b/test/Transforms/ScalarRepl/2003-10-29-ArrayProblem.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -scalarrepl -S | grep {alloca %T}
+; RUN: opt < %s -scalarrepl -S | grep {alloca %%T}
%T = type { [80 x i8], i32, i32 }
declare i32 @.callback_1(i8*)
diff --git a/test/Transforms/ScalarRepl/2011-09-22-PHISpeculateInvoke.ll b/test/Transforms/ScalarRepl/2011-09-22-PHISpeculateInvoke.ll
new file mode 100644
index 0000000000000..f98f3e8fc458f
--- /dev/null
+++ b/test/Transforms/ScalarRepl/2011-09-22-PHISpeculateInvoke.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -scalarrepl -S | FileCheck %s
+; PR10987
+
+; Make sure scalarrepl doesn't move a load across an invoke which could
+; modify the loaded value.
+; (The PHI could theoretically be transformed by splitting the critical
+; edge, but scalarrepl doesn't modify the CFG, at least at the moment.)
+
+declare void @extern_fn(i32*)
+declare i32 @extern_fn2(i32)
+declare i32 @__gcc_personality_v0(i32, i64, i8*, i8*)
+
+define void @odd_fn(i1) noinline {
+ %retptr1 = alloca i32
+ %retptr2 = alloca i32
+ br i1 %0, label %then, label %else
+
+then: ; preds = %2
+ invoke void @extern_fn(i32* %retptr1)
+ to label %join unwind label %unwind
+
+else: ; preds = %2
+ store i32 3, i32* %retptr2
+ br label %join
+
+join: ; preds = %then, %else
+ %storemerge.in = phi i32* [ %retptr2, %else ], [ %retptr1, %then ]
+ %storemerge = load i32* %storemerge.in
+ %x3 = call i32 @extern_fn2(i32 %storemerge)
+ ret void
+
+unwind: ; preds = %then
+ %info = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gcc_personality_v0
+ cleanup
+ call void @extern_fn(i32* null)
+ unreachable
+}
+
+; CHECK: define void @odd_fn
+; CHECK: %storemerge.in = phi i32* [ %retptr2, %else ], [ %retptr1, %then ]
diff --git a/test/Transforms/ScalarRepl/2011-10-11-VectorMemset.ll b/test/Transforms/ScalarRepl/2011-10-11-VectorMemset.ll
new file mode 100644
index 0000000000000..9e3123149297d
--- /dev/null
+++ b/test/Transforms/ScalarRepl/2011-10-11-VectorMemset.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -S -scalarrepl | 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-darwin11.0.1"
+
+; CHECK: test
+; CHECK-NOT: alloca
+
+define void @test() nounwind {
+entry:
+ %a156286 = alloca [4 x <4 x float>], align 16
+ br i1 undef, label %cif_done, label %for_test158.preheader
+
+for_test158.preheader: ; preds = %entry
+ %a156286305 = bitcast [4 x <4 x float>]* %a156286 to i8*
+ call void @llvm.memset.p0i8.i64(i8* %a156286305, i8 -1, i64 64, i32 16, i1 false)
+ unreachable
+
+cif_done: ; preds = %entry
+ ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
diff --git a/test/Transforms/ScalarRepl/lifetime.ll b/test/Transforms/ScalarRepl/lifetime.ll
new file mode 100644
index 0000000000000..3f558a1c3737c
--- /dev/null
+++ b/test/Transforms/ScalarRepl/lifetime.ll
@@ -0,0 +1,139 @@
+; RUN: opt -scalarrepl -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-unknown-linux-gnu"
+
+declare void @llvm.lifetime.start(i64, i8*)
+declare void @llvm.lifetime.end(i64, i8*)
+
+%t1 = type {i32, i32, i32}
+
+define void @test1() {
+; CHECK: @test1
+ %A = alloca %t1
+ %A1 = getelementptr %t1* %A, i32 0, i32 0
+ %A2 = getelementptr %t1* %A, i32 0, i32 1
+ %A3 = getelementptr %t1* %A, i32 0, i32 2
+ %B = bitcast i32* %A1 to i8*
+ store i32 0, i32* %A1
+ call void @llvm.lifetime.start(i64 -1, i8* %B)
+ ret void
+; CHECK-NEXT: ret void
+}
+
+define void @test2() {
+; CHECK: @test2
+ %A = alloca %t1
+ %A1 = getelementptr %t1* %A, i32 0, i32 0
+ %A2 = getelementptr %t1* %A, i32 0, i32 1
+ %A3 = getelementptr %t1* %A, i32 0, i32 2
+ %B = bitcast i32* %A2 to i8*
+ store i32 0, i32* %A2
+ call void @llvm.lifetime.start(i64 -1, i8* %B)
+ %C = load i32* %A2
+ ret void
+; CHECK: ret void
+}
+
+define void @test3() {
+; CHECK: @test3
+ %A = alloca %t1
+ %A1 = getelementptr %t1* %A, i32 0, i32 0
+ %A2 = getelementptr %t1* %A, i32 0, i32 1
+ %A3 = getelementptr %t1* %A, i32 0, i32 2
+ %B = bitcast i32* %A2 to i8*
+ store i32 0, i32* %A2
+ call void @llvm.lifetime.start(i64 6, i8* %B)
+ %C = load i32* %A2
+ ret void
+; CHECK-NEXT: ret void
+}
+
+define void @test4() {
+; CHECK: @test4
+ %A = alloca %t1
+ %A1 = getelementptr %t1* %A, i32 0, i32 0
+ %A2 = getelementptr %t1* %A, i32 0, i32 1
+ %A3 = getelementptr %t1* %A, i32 0, i32 2
+ %B = bitcast i32* %A2 to i8*
+ store i32 0, i32* %A2
+ call void @llvm.lifetime.start(i64 1, i8* %B)
+ %C = load i32* %A2
+ ret void
+; CHECK-NEXT: ret void
+}
+
+%t2 = type {i32, [4 x i8], i32}
+
+define void @test5() {
+; CHECK: @test5
+ %A = alloca %t2
+; CHECK: alloca{{.*}}i8
+; CHECK: alloca{{.*}}i8
+; CHECK: alloca{{.*}}i8
+
+ %A21 = getelementptr %t2* %A, i32 0, i32 1, i32 0
+ %A22 = getelementptr %t2* %A, i32 0, i32 1, i32 1
+ %A23 = getelementptr %t2* %A, i32 0, i32 1, i32 2
+ %A24 = getelementptr %t2* %A, i32 0, i32 1, i32 3
+; CHECK-NOT: store i8 1
+ store i8 1, i8* %A21
+ store i8 2, i8* %A22
+ store i8 3, i8* %A23
+ store i8 4, i8* %A24
+
+ %A1 = getelementptr %t2* %A, i32 0, i32 0
+ %A2 = getelementptr %t2* %A, i32 0, i32 1, i32 1
+ %A3 = getelementptr %t2* %A, i32 0, i32 2
+ store i8 0, i8* %A2
+ call void @llvm.lifetime.start(i64 5, i8* %A2)
+; CHECK: llvm.lifetime{{.*}}i64 1
+; CHECK: llvm.lifetime{{.*}}i64 1
+; CHECK: llvm.lifetime{{.*}}i64 1
+ %C = load i8* %A2
+ ret void
+}
+
+%t3 = type {[4 x i16], [4 x i8]}
+
+define void @test6() {
+; CHECK: @test6
+ %A = alloca %t3
+; CHECK: alloca i8
+; CHECK: alloca i8
+; CHECK: alloca i8
+
+ %A11 = getelementptr %t3* %A, i32 0, i32 0, i32 0
+ %A12 = getelementptr %t3* %A, i32 0, i32 0, i32 1
+ %A13 = getelementptr %t3* %A, i32 0, i32 0, i32 2
+ %A14 = getelementptr %t3* %A, i32 0, i32 0, i32 3
+ store i16 11, i16* %A11
+ store i16 12, i16* %A12
+ store i16 13, i16* %A13
+ store i16 14, i16* %A14
+; CHECK-NOT: store i16 11
+; CHECK-NOT: store i16 12
+; CHECK-NOT: store i16 13
+; CHECK-NOT: store i16 14
+
+ %A21 = getelementptr %t3* %A, i32 0, i32 1, i32 0
+ %A22 = getelementptr %t3* %A, i32 0, i32 1, i32 1
+ %A23 = getelementptr %t3* %A, i32 0, i32 1, i32 2
+ %A24 = getelementptr %t3* %A, i32 0, i32 1, i32 3
+ store i8 21, i8* %A21
+ store i8 22, i8* %A22
+ store i8 23, i8* %A23
+ store i8 24, i8* %A24
+; CHECK: store i8 21
+; CHECK: store i8 22
+; CHECK: store i8 23
+; CHECK-NOT: store i8 24
+
+ %B = bitcast i16* %A13 to i8*
+ call void @llvm.lifetime.start(i64 7, i8* %B)
+; CHECK: lifetime.start{{.*}}i64 1
+; CHECK: lifetime.start{{.*}}i64 1
+; CHECK: lifetime.start{{.*}}i64 1
+
+ ret void
+}
diff --git a/test/Transforms/ScalarRepl/vector_promote.ll b/test/Transforms/ScalarRepl/vector_promote.ll
index c51ef109c0b28..5c82ae4d196db 100644
--- a/test/Transforms/ScalarRepl/vector_promote.ll
+++ b/test/Transforms/ScalarRepl/vector_promote.ll
@@ -86,7 +86,6 @@ define i32 @test5(float %X) { ;; should turn into bitcast.
; CHECK-NEXT: ret i32
}
-
define i64 @test6(<2 x float> %X) {
%X_addr = alloca <2 x float>
store <2 x float> %X, <2 x float>* %X_addr
@@ -98,168 +97,17 @@ define i64 @test6(<2 x float> %X) {
; CHECK: ret i64
}
-define float @test7(<4 x float> %x) {
- %a = alloca <4 x float>
- store <4 x float> %x, <4 x float>* %a
- %p = bitcast <4 x float>* %a to <2 x float>*
- %b = load <2 x float>* %p
- %q = getelementptr <4 x float>* %a, i32 0, i32 2
- %c = load float* %q
- ret float %c
-; CHECK: @test7
-; CHECK-NOT: alloca
-; CHECK: bitcast <4 x float> %x to <2 x double>
-; CHECK-NEXT: extractelement <2 x double>
-; CHECK-NEXT: bitcast double %tmp4 to <2 x float>
-; CHECK-NEXT: extractelement <4 x float>
-}
-
-define void @test8(<4 x float> %x, <2 x float> %y) {
- %a = alloca <4 x float>
- store <4 x float> %x, <4 x float>* %a
- %p = bitcast <4 x float>* %a to <2 x float>*
- store <2 x float> %y, <2 x float>* %p
- ret void
-; CHECK: @test8
-; CHECK-NOT: alloca
-; CHECK: bitcast <4 x float> %x to <2 x double>
-; CHECK-NEXT: bitcast <2 x float> %y to double
-; CHECK-NEXT: insertelement <2 x double>
-; CHECK-NEXT: bitcast <2 x double> %tmp2 to <4 x float>
-}
+%struct.test7 = type { [6 x i32] }
-define i256 @test9(<4 x i256> %x) {
- %a = alloca <4 x i256>
- store <4 x i256> %x, <4 x i256>* %a
- %p = bitcast <4 x i256>* %a to <2 x i256>*
- %b = load <2 x i256>* %p
- %q = getelementptr <4 x i256>* %a, i32 0, i32 2
- %c = load i256* %q
- ret i256 %c
-; CHECK: @test9
-; CHECK-NOT: alloca
-; CHECK: bitcast <4 x i256> %x to <2 x i512>
-; CHECK-NEXT: extractelement <2 x i512>
-; CHECK-NEXT: bitcast i512 %tmp4 to <2 x i256>
-; CHECK-NEXT: extractelement <4 x i256>
-}
-
-define void @test10(<4 x i256> %x, <2 x i256> %y) {
- %a = alloca <4 x i256>
- store <4 x i256> %x, <4 x i256>* %a
- %p = bitcast <4 x i256>* %a to <2 x i256>*
- store <2 x i256> %y, <2 x i256>* %p
- ret void
-; CHECK: @test10
-; CHECK-NOT: alloca
-; CHECK: bitcast <4 x i256> %x to <2 x i512>
-; CHECK-NEXT: bitcast <2 x i256> %y to i512
-; CHECK-NEXT: insertelement <2 x i512>
-; CHECK-NEXT: bitcast <2 x i512> %tmp2 to <4 x i256>
-}
-
-%union.v = type { <2 x i64> }
-
-define void @test11(<2 x i64> %x) {
- %a = alloca %union.v
- %p = getelementptr inbounds %union.v* %a, i32 0, i32 0
- store <2 x i64> %x, <2 x i64>* %p, align 16
- %q = getelementptr inbounds %union.v* %a, i32 0, i32 0
- %r = bitcast <2 x i64>* %q to <4 x float>*
- %b = load <4 x float>* %r, align 16
- ret void
-; CHECK: @test11
-; CHECK-NOT: alloca
-}
-
-define void @test12() {
-entry:
- %a = alloca <64 x i8>, align 64
- store <64 x i8> undef, <64 x i8>* %a, align 64
- %p = bitcast <64 x i8>* %a to <16 x i8>*
- %0 = load <16 x i8>* %p, align 64
- store <16 x i8> undef, <16 x i8>* %p, align 64
- %q = bitcast <16 x i8>* %p to <64 x i8>*
- %1 = load <64 x i8>* %q, align 64
- ret void
-; CHECK: @test12
-; CHECK-NOT: alloca
-; CHECK: extractelement <4 x i128>
-; CHECK: insertelement <4 x i128>
-}
-
-define float @test13(<4 x float> %x, <2 x i32> %y) {
- %a = alloca <4 x float>
- store <4 x float> %x, <4 x float>* %a
- %p = bitcast <4 x float>* %a to <2 x float>*
- %b = load <2 x float>* %p
- %q = getelementptr <4 x float>* %a, i32 0, i32 2
- %c = load float* %q
- %r = bitcast <4 x float>* %a to <2 x i32>*
- store <2 x i32> %y, <2 x i32>* %r
- ret float %c
-; CHECK: @test13
-; CHECK-NOT: alloca
-; CHECK: bitcast <4 x float> %x to i128
-}
-
-define <3 x float> @test14(<3 x float> %x) {
+define void @test7() {
entry:
- %x.addr = alloca <3 x float>, align 16
- %r = alloca <3 x i32>, align 16
- %extractVec = shufflevector <3 x float> %x, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
- %storetmp = bitcast <3 x float>* %x.addr to <4 x float>*
- store <4 x float> %extractVec, <4 x float>* %storetmp, align 16
- %tmp = load <3 x float>* %x.addr, align 16
- %cmp = fcmp une <3 x float> %tmp, zeroinitializer
- %sext = sext <3 x i1> %cmp to <3 x i32>
- %and = and <3 x i32> <i32 1065353216, i32 1065353216, i32 1065353216>, %sext
- %extractVec1 = shufflevector <3 x i32> %and, <3 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
- %storetmp2 = bitcast <3 x i32>* %r to <4 x i32>*
- store <4 x i32> %extractVec1, <4 x i32>* %storetmp2, align 16
- %tmp3 = load <3 x i32>* %r, align 16
- %0 = bitcast <3 x i32> %tmp3 to <3 x float>
- %tmp4 = load <3 x float>* %x.addr, align 16
- ret <3 x float> %tmp4
-; CHECK: @test14
-; CHECK-NOT: alloca
-; CHECK: shufflevector <4 x i32> %extractVec1, <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2>
-}
-
-define void @test15(<3 x i64>* sret %agg.result, <3 x i64> %x, <3 x i64> %min) {
-entry:
- %x.addr = alloca <3 x i64>, align 32
- %min.addr = alloca <3 x i64>, align 32
- %extractVec = shufflevector <3 x i64> %x, <3 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
- %storetmp = bitcast <3 x i64>* %x.addr to <4 x i64>*
- store <4 x i64> %extractVec, <4 x i64>* %storetmp, align 32
- %extractVec1 = shufflevector <3 x i64> %min, <3 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
- %storetmp2 = bitcast <3 x i64>* %min.addr to <4 x i64>*
- store <4 x i64> %extractVec1, <4 x i64>* %storetmp2, align 32
- %tmp = load <3 x i64>* %x.addr
- %tmp5 = extractelement <3 x i64> %tmp, i32 0
- %tmp11 = insertelement <3 x i64> %tmp, i64 %tmp5, i32 0
- store <3 x i64> %tmp11, <3 x i64>* %x.addr
- %tmp30 = load <3 x i64>* %x.addr, align 32
- store <3 x i64> %tmp30, <3 x i64>* %agg.result
+ %memtmp = alloca %struct.test7, align 16
+ %0 = bitcast %struct.test7* %memtmp to <4 x i32>*
+ store <4 x i32> zeroinitializer, <4 x i32>* %0, align 16
+ %1 = getelementptr inbounds %struct.test7* %memtmp, i64 0, i32 0, i64 5
+ store i32 0, i32* %1, align 4
ret void
-; CHECK: @test15
-; CHECK-NOT: alloca
-; CHECK: shufflevector <4 x i64> %tmpV2, <4 x i64> undef, <3 x i32> <i32 0, i32 1, i32 2>
-}
-
-define <4 x float> @test16(<4 x float> %x, i64 %y0, i64 %y1) {
-entry:
- %tmp8 = bitcast <4 x float> undef to <2 x double>
- %tmp9 = bitcast i64 %y0 to double
- %tmp10 = insertelement <2 x double> %tmp8, double %tmp9, i32 0
- %tmp11 = bitcast <2 x double> %tmp10 to <4 x float>
- %tmp3 = bitcast <4 x float> %tmp11 to <2 x double>
- %tmp4 = bitcast i64 %y1 to double
- %tmp5 = insertelement <2 x double> %tmp3, double %tmp4, i32 1
- %tmp6 = bitcast <2 x double> %tmp5 to <4 x float>
- ret <4 x float> %tmp6
-; CHECK: @test16
+; CHECK: @test7
; CHECK-NOT: alloca
-; CHECK: bitcast <4 x float> %tmp11 to <2 x double>
+; CHECK: and i192
}
diff --git a/test/Transforms/ScalarRepl/vectors-with-mismatched-elements.ll b/test/Transforms/ScalarRepl/vectors-with-mismatched-elements.ll
new file mode 100644
index 0000000000000..c3fbdf5f86322
--- /dev/null
+++ b/test/Transforms/ScalarRepl/vectors-with-mismatched-elements.ll
@@ -0,0 +1,27 @@
+; RUN: opt -scalarrepl -S < %s | FileCheck %s
+; rdar://9786827
+
+; SROA should be able to handle the mixed types and eliminate the allocas here.
+
+; TODO: Currently it does this by falling back to integer "bags of bits".
+; With enough cleverness, it should be possible to convert between <3 x i32>
+; and <2 x i64> by using a combination of a bitcast and a shuffle.
+
+; CHECK: {
+; CHECK-NOT: alloca
+; CHECK: }
+
+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-darwin11.0.0"
+
+define <2 x i64> @foo() nounwind {
+entry:
+ %retval = alloca <3 x i32>, align 16
+ %z = alloca <4 x i32>, align 16
+ %tmp = load <4 x i32>* %z
+ %tmp1 = shufflevector <4 x i32> %tmp, <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2>
+ store <3 x i32> %tmp1, <3 x i32>* %retval
+ %0 = bitcast <3 x i32>* %retval to <2 x i64>*
+ %1 = load <2 x i64>* %0, align 1
+ ret <2 x i64> %1
+}
diff --git a/test/Transforms/ScalarRepl/volatile.ll b/test/Transforms/ScalarRepl/volatile.ll
index 3ff322e065cbb..ab276b043e3ae 100644
--- a/test/Transforms/ScalarRepl/volatile.ll
+++ b/test/Transforms/ScalarRepl/volatile.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -scalarrepl -S | grep {volatile load}
-; RUN: opt < %s -scalarrepl -S | grep {volatile store}
+; RUN: opt < %s -scalarrepl -S | grep {load volatile}
+; RUN: opt < %s -scalarrepl -S | grep {store volatile}
define i32 @voltest(i32 %T) {
%A = alloca {i32, i32}
diff --git a/test/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll b/test/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll
index c019931c07e75..7551e8fb747c7 100644
--- a/test/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll
+++ b/test/Transforms/SimplifyCFG/2003-08-05-InvokeCrash.ll
@@ -8,6 +8,9 @@ define i32 @test() {
Ret: ; preds = %0
ret i32 %A
Ret2: ; preds = %0
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
ret i32 undef
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll b/test/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll
index 15cd7730449ee..bc61a75561d36 100644
--- a/test/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll
+++ b/test/Transforms/SimplifyCFG/2003-08-05-MishandleInvoke.ll
@@ -6,7 +6,10 @@ define i32 @test() {
invoke i32 @test( )
to label %Ret unwind label %Ret ; <i32>:1 [#uses=0]
Ret: ; preds = %0, %0
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
%A = add i32 0, 1 ; <i32> [#uses=1]
ret i32 %A
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2005-10-02-InvokeSimplify.ll b/test/Transforms/SimplifyCFG/2005-10-02-InvokeSimplify.ll
index 778aa3b1f7b43..2ecdc95259cc7 100644
--- a/test/Transforms/SimplifyCFG/2005-10-02-InvokeSimplify.ll
+++ b/test/Transforms/SimplifyCFG/2005-10-02-InvokeSimplify.ll
@@ -4,6 +4,8 @@ define i1 @foo() {
%X = invoke i1 @foo( )
to label %N unwind label %F ; <i1> [#uses=1]
F: ; preds = %0
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
ret i1 false
N: ; preds = %0
br i1 %X, label %A, label %B
@@ -13,3 +15,4 @@ B: ; preds = %N
ret i1 true
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll b/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll
index dba41c9b111fd..27d9d8f674181 100644
--- a/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll
+++ b/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll
@@ -275,12 +275,16 @@ invcont153: ; preds = %invcont151
invoke void @_ZN12QFontMetricsD1Ev( %struct.QFontMetrics* %tmp.upgrd.2 )
to label %cleanup171 unwind label %cleanup173
cleanup168: ; preds = %invcont151, %invcont148, %invcont146
+ %val168 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN12QFontMetricsD1Ev( %struct.QFontMetrics* %tmp.upgrd.2 )
to label %cleanup173 unwind label %cleanup173
cleanup171: ; preds = %invcont153
invoke void @_ZN5QFontD1Ev( %struct.QFont* %tmp.upgrd.3 )
to label %finally170 unwind label %cleanup192
cleanup173: ; preds = %cleanup168, %cleanup168, %invcont153, %invcont144
+ %val173 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN5QFontD1Ev( %struct.QFont* %tmp.upgrd.3 )
to label %cleanup192 unwind label %cleanup192
finally170: ; preds = %cleanup171
@@ -300,12 +304,16 @@ cleanup185: ; preds = %invcont181
invoke void @_ZN5QFontD1Ev( %struct.QFont* %font )
to label %cleanup190 unwind label %cleanup192
cleanup187: ; preds = %invcont181, %invcont179, %invcont177
+ %val187 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN5QFontD1Ev( %struct.QFont* %font )
to label %cleanup192 unwind label %cleanup192
cleanup190: ; preds = %cleanup185
invoke void @_ZN16QTextFrameFormatD1Ev( %struct.QTextBlockFormat* %fmt )
to label %cond_next194 unwind label %cleanup329
cleanup192: ; preds = %cleanup187, %cleanup187, %cleanup185, %finally170, %cleanup173, %cleanup173, %cleanup171, %invcont141, %invcont124, %invcont122, %invcont120, %invcont118, %invcont117, %invcont114, %invcont111
+ %val192 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN16QTextFrameFormatD1Ev( %struct.QTextBlockFormat* %fmt )
to label %cleanup329 unwind label %cleanup329
cond_next194: ; preds = %cleanup190, %invcont83
@@ -450,8 +458,10 @@ cleanup328: ; preds = %invcont
call void @_ZN8QPainterD1Ev( %struct.QPainter* %p )
ret void
cleanup329: ; preds = %cond_true319, %cond_true302, %cond_next293, %cond_true277, %cond_true266, %cond_next258, %cond_next244, %cond_next225, %cond_true220, %invcont210, %cond_next208, %cond_false204, %cond_true200, %cond_next194, %cleanup192, %cleanup192, %cleanup190, %invcont106, %invcont104, %invcont103, %invcont100, %invcont98, %invcont94, %cond_false, %invcont83, %invcont79, %invcont57, %invcont51, %invcont45, %cond_next42, %invcont37, %cond_true35, %invcont29, %invcont25, %cond_true24, %cond_next, %entry
+ %val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
call void @_ZN8QPainterD1Ev( %struct.QPainter* %p )
- unwind
+ resume { i8*, i32 } %val
}
declare void @_ZN6QSizeFC1Edd(%struct.QPointF*, double, double)
@@ -553,3 +563,5 @@ declare i32 @_ZNK8QPrinter12printerStateEv(%struct.QPrinter*)
declare i1 @_ZN8QPrinter7newPageEv(%struct.QPrinter*)
declare void @_ZN8QPainterD1Ev(%struct.QPainter*)
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll b/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
index 33167bd5c661d..568e61c6ac6de 100644
--- a/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
+++ b/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
@@ -15,7 +15,7 @@ bb2:
ret i32 42
bb6:
- unwind
+ ret i32 927
}
define i32 @test2(i32 %tmp21, i32 %tmp24, i1 %tmp34) {
@@ -26,6 +26,6 @@ bb5: ; preds = %bb4
bb6:
ret i32 42
bb7:
- unwind
+ ret i32 927
}
diff --git a/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll b/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll
index f99cbe1c8b83d..abf4455d780ba 100644
--- a/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll
+++ b/test/Transforms/SimplifyCFG/2009-06-15-InvokeCrash.ll
@@ -277,12 +277,16 @@ invcont153: ; preds = %invcont151
invoke void @_ZN12QFontMetricsD1Ev( %struct.QFontMetrics* %tmp.upgrd.2 )
to label %cleanup171 unwind label %cleanup173
cleanup168: ; preds = %invcont151, %invcont148, %invcont146
+ %val168 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN12QFontMetricsD1Ev( %struct.QFontMetrics* %tmp.upgrd.2 )
to label %cleanup173 unwind label %cleanup173
cleanup171: ; preds = %invcont153
invoke void @_ZN5QFontD1Ev( %struct.QFont* %tmp.upgrd.3 )
to label %finally170 unwind label %cleanup192
cleanup173: ; preds = %cleanup168, %cleanup168, %invcont153, %invcont144
+ %val173 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN5QFontD1Ev( %struct.QFont* %tmp.upgrd.3 )
to label %cleanup192 unwind label %cleanup192
finally170: ; preds = %cleanup171
@@ -302,12 +306,16 @@ cleanup185: ; preds = %invcont181
invoke void @_ZN5QFontD1Ev( %struct.QFont* %font )
to label %cleanup190 unwind label %cleanup192
cleanup187: ; preds = %invcont181, %invcont179, %invcont177
+ %val187 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN5QFontD1Ev( %struct.QFont* %font )
to label %cleanup192 unwind label %cleanup192
cleanup190: ; preds = %cleanup185
invoke void @_ZN16QTextFrameFormatD1Ev( %struct.QTextBlockFormat* %fmt )
to label %cond_next194 unwind label %cleanup329
cleanup192: ; preds = %cleanup187, %cleanup187, %cleanup185, %finally170, %cleanup173, %cleanup173, %cleanup171, %invcont141, %invcont124, %invcont122, %invcont120, %invcont118, %invcont117, %invcont114, %invcont111
+ %val192 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
invoke void @_ZN16QTextFrameFormatD1Ev( %struct.QTextBlockFormat* %fmt )
to label %cleanup329 unwind label %cleanup329
cond_next194: ; preds = %cleanup190, %invcont83
@@ -452,8 +460,10 @@ cleanup328: ; preds = %invcont
call void @_ZN8QPainterD1Ev( %struct.QPainter* %p )
ret void
cleanup329: ; preds = %cond_true319, %cond_true302, %cond_next293, %cond_true277, %cond_true266, %cond_next258, %cond_next244, %cond_next225, %cond_true220, %invcont210, %cond_next208, %cond_false204, %cond_true200, %cond_next194, %cleanup192, %cleanup192, %cleanup190, %invcont106, %invcont104, %invcont103, %invcont100, %invcont98, %invcont94, %cond_false, %invcont83, %invcont79, %invcont57, %invcont51, %invcont45, %cond_next42, %invcont37, %cond_true35, %invcont29, %invcont25, %cond_true24, %cond_next, %entry
+ %val329 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
call void @_ZN8QPainterD1Ev( %struct.QPainter* %p )
- unwind
+ resume { i8*, i32 } %val329
}
declare void @_ZN6QSizeFC1Edd(%struct.QPointF*, double, double)
@@ -555,3 +565,5 @@ declare i32 @_ZNK8QPrinter12printerStateEv(%struct.QPrinter*)
declare i1 @_ZN8QPrinter7newPageEv(%struct.QPrinter*)
declare void @_ZN8QPainterD1Ev(%struct.QPainter*)
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2010-03-30-InvokeCrash.ll b/test/Transforms/SimplifyCFG/2010-03-30-InvokeCrash.ll
index ced89cf4c2b31..7bffa1a8e0e2f 100644
--- a/test/Transforms/SimplifyCFG/2010-03-30-InvokeCrash.ll
+++ b/test/Transforms/SimplifyCFG/2010-03-30-InvokeCrash.ll
@@ -14,5 +14,9 @@ r: ; preds = %entry
ret void
u: ; preds = %entry
- unwind
+ %val = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %val
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll b/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll
new file mode 100644
index 0000000000000..7558419a2ebda
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+; CHECK-NOT: invoke
+; CHECK-NOT: landingpad
+
+declare void @bar()
+
+define i32 @foo() {
+entry:
+ invoke void @bar()
+ to label %return unwind label %lpad
+
+return:
+ ret i32 0
+
+lpad:
+ %lp = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ cleanup
+ resume { i8*, i32 } %lp
+}
+
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
diff --git a/test/Transforms/SimplifyCFG/BrUnwind.ll b/test/Transforms/SimplifyCFG/BrUnwind.ll
index b19a27dea048d..7ab8faa2cea98 100644
--- a/test/Transforms/SimplifyCFG/BrUnwind.ll
+++ b/test/Transforms/SimplifyCFG/BrUnwind.ll
@@ -10,6 +10,6 @@ B: ; preds = %0
call void @test( i1 %C )
br label %X
X: ; preds = %B, %A
- unwind
+ ret void
}
diff --git a/test/Transforms/SimplifyCFG/invoke_unwind.ll b/test/Transforms/SimplifyCFG/invoke_unwind.ll
index 73faa952fba93..ed7ff8287f20d 100644
--- a/test/Transforms/SimplifyCFG/invoke_unwind.ll
+++ b/test/Transforms/SimplifyCFG/invoke_unwind.ll
@@ -12,21 +12,9 @@ define i32 @test1() {
to label %1 unwind label %Rethrow
ret i32 0
Rethrow:
- unwind
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
+ resume { i8*, i32 } %exn
}
-
-; Verify that simplifycfg isn't duplicating 'unwind' instructions. Doing this
-; is bad because it discourages commoning.
-define i32 @test2(i1 %c) {
-; CHECK: @test2
-; CHECK: T:
-; CHECK-NEXT: call void @bar()
-; CHECK-NEXT: br label %F
- br i1 %c, label %T, label %F
-T:
- call void @bar()
- br label %F
-F:
- unwind
-}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll b/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll
new file mode 100644
index 0000000000000..65d888ea01e10
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll
@@ -0,0 +1,87 @@
+; RUN: opt -simplifycfg -S < %s | FileCheck %s
+
+declare void @bar() nounwind
+
+define i32 @test1(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
+entry:
+ %tobool = icmp eq i32 %b, 0
+ br i1 %tobool, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.else: ; preds = %entry
+ %tobool3 = icmp eq i32 %d, 0
+ br i1 %tobool3, label %if.end7, label %if.then4
+
+if.then4: ; preds = %if.else
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.end7: ; preds = %if.else, %if.then4, %if.then
+ %x.0 = phi i32* [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
+ %tmp9 = load i32* %x.0
+ ret i32 %tmp9
+
+; CHECK: @test1
+; CHECK: if.else:
+; CHECK: br label %if.end7
+
+; CHECK: phi i32* [ %a, %if.then ], [ %c, %if.else ]
+}
+
+define i32 @test2(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
+entry:
+ %tobool = icmp eq i32 %b, 0
+ br i1 %tobool, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.else: ; preds = %entry
+ %tobool3 = icmp eq i32 %d, 0
+ br i1 %tobool3, label %if.end7, label %if.then4
+
+if.then4: ; preds = %if.else
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.end7: ; preds = %if.else, %if.then4, %if.then
+ %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
+ %tmp9 = load i32* %x.0
+ ret i32 %tmp9
+; CHECK: @test2
+; CHECK: if.else:
+; CHECK: unreachable
+
+; CHECK-NOT: phi
+}
+
+define i32 @test3(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
+entry:
+ %tobool = icmp eq i32 %b, 0
+ br i1 %tobool, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.else: ; preds = %entry
+ %tobool3 = icmp eq i32 %d, 0
+ br i1 %tobool3, label %if.end7, label %if.then4
+
+if.then4: ; preds = %if.else
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.end7: ; preds = %if.else, %if.then4, %if.then
+ %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
+ tail call void @bar() nounwind
+ %tmp9 = load i32* %x.0
+ ret i32 %tmp9
+; CHECK: @test3
+; CHECK: if.end7:
+; CHECK: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
+}
diff --git a/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll b/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
index 7bca5f5afa0d6..10d6981af0e67 100644
--- a/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
+++ b/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll
@@ -11,14 +11,14 @@ entry:
br i1 %0, label %bb, label %return
bb: ; preds = %entry
- %1 = volatile load i32* null
+ %1 = load volatile i32* null
unreachable
br label %return
return: ; preds = %entry
ret void
; CHECK: @test1
-; CHECK: volatile load
+; CHECK: load volatile
}
; rdar://7958343
@@ -35,10 +35,53 @@ entry:
; PR7369
define void @test3() nounwind {
entry:
- volatile store i32 4, i32* null
+ store volatile i32 4, i32* null
ret void
; CHECK: @test3
-; CHECK: volatile store i32 4, i32* null
+; CHECK: store volatile i32 4, i32* null
; CHECK: ret
}
+
+; Check store before unreachable.
+define void @test4(i1 %C, i32* %P) {
+; CHECK: @test4
+; CHECK: entry:
+; CHECK-NEXT: br i1 %C
+entry:
+ br i1 %C, label %T, label %F
+T:
+ store volatile i32 0, i32* %P
+ unreachable
+F:
+ ret void
+}
+
+; Check cmpxchg before unreachable.
+define void @test5(i1 %C, i32* %P) {
+; CHECK: @test5
+; CHECK: entry:
+; CHECK-NEXT: br i1 %C
+entry:
+ br i1 %C, label %T, label %F
+T:
+ cmpxchg volatile i32* %P, i32 0, i32 1 seq_cst
+ unreachable
+F:
+ ret void
+}
+
+; Check atomicrmw before unreachable.
+define void @test6(i1 %C, i32* %P) {
+; CHECK: @test6
+; CHECK: entry:
+; CHECK-NEXT: br i1 %C
+entry:
+ br i1 %C, label %T, label %F
+T:
+ atomicrmw volatile xchg i32* %P, i32 0 seq_cst
+ unreachable
+F:
+ ret void
+}
+
diff --git a/test/Transforms/SimplifyLibCalls/StrCmp.ll b/test/Transforms/SimplifyLibCalls/StrCmp.ll
index 73596351a8ccf..60854d76c97ae 100644
--- a/test/Transforms/SimplifyLibCalls/StrCmp.ll
+++ b/test/Transforms/SimplifyLibCalls/StrCmp.ll
@@ -1,28 +1,65 @@
; Test that the StrCmpOptimizer works correctly
-; RUN: opt < %s -simplify-libcalls -S | \
-; RUN: not grep {call.*strcmp}
+; RUN: opt < %s -simplify-libcalls -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"
@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1]
@hell = constant [5 x i8] c"hell\00" ; <[5 x i8]*> [#uses=1]
+@bell = constant [5 x i8] c"bell\00" ; <[5 x i8]*> [#uses=1]
@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1]
declare i32 @strcmp(i8*, i8*)
-declare i32 @puts(i8*)
-
-define i32 @main() {
- %hello_p = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=5]
- %hell_p = getelementptr [5 x i8]* @hell, i32 0, i32 0 ; <i8*> [#uses=1]
- %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=4]
- %temp1 = call i32 @strcmp( i8* %hello_p, i8* %hello_p ) ; <i32> [#uses=1]
- %temp2 = call i32 @strcmp( i8* %null_p, i8* %null_p ) ; <i32> [#uses=1]
- %temp3 = call i32 @strcmp( i8* %hello_p, i8* %null_p ) ; <i32> [#uses=1]
- %temp4 = call i32 @strcmp( i8* %null_p, i8* %hello_p ) ; <i32> [#uses=1]
- %temp5 = call i32 @strcmp( i8* %hell_p, i8* %hello_p ) ; <i32> [#uses=1]
- %rslt1 = add i32 %temp1, %temp2 ; <i32> [#uses=1]
- %rslt2 = add i32 %rslt1, %temp3 ; <i32> [#uses=1]
- %rslt3 = add i32 %rslt2, %temp4 ; <i32> [#uses=1]
- %rslt4 = add i32 %rslt3, %temp5 ; <i32> [#uses=1]
- ret i32 %rslt4
+; strcmp("", x) -> -*x
+define i32 @test1(i8* %str) {
+ %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i8* %str)
+ ret i32 %temp1
+ ; CHECK: @test1
+ ; CHECK: %strcmpload = load i8* %str
+ ; CHECK: %1 = zext i8 %strcmpload to i32
+ ; CHECK: %temp1 = sub i32 0, %1
+ ; CHECK: ret i32 %temp1
+}
+
+; strcmp(x, "") -> *x
+define i32 @test2(i8* %str) {
+ %temp1 = call i32 @strcmp(i8* %str, i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0))
+ ret i32 %temp1
+ ; CHECK: @test2
+ ; CHECK: %strcmpload = load i8* %str
+ ; CHECK: %temp1 = zext i8 %strcmpload to i32
+ ; CHECK: ret i32 %temp1
}
+; strcmp(x, y) -> cnst
+define i32 @test3() {
+ %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0))
+ ret i32 %temp1
+ ; CHECK: @test3
+ ; CHECK: ret i32 -1
+}
+define i32 @test4() {
+ %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0))
+ ret i32 %temp1
+ ; CHECK: @test4
+ ; CHECK: ret i32 1
+}
+
+; strcmp(x, y) -> memcmp(x, y, <known length>)
+; (This transform is rather difficult to trigger in a useful manner)
+define i32 @test5(i1 %b) {
+ %sel = select i1 %b, i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8]* @bell, i32 0, i32 0)
+ %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %sel)
+ ret i32 %temp1
+ ; CHECK: @test5
+ ; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %sel, i32 5)
+ ; CHECK: ret i32 %memcmp
+}
+
+; strcmp(x,x) -> 0
+define i32 @test6(i8* %str) {
+ %temp1 = call i32 @strcmp(i8* %str, i8* %str)
+ ret i32 %temp1
+ ; CHECK: @test6
+ ; CHECK: ret i32 0
+}
diff --git a/test/Transforms/SimplifyLibCalls/StrNCmp.ll b/test/Transforms/SimplifyLibCalls/StrNCmp.ll
index 8b536a5486997..0b2a501a3c8a7 100644
--- a/test/Transforms/SimplifyLibCalls/StrNCmp.ll
+++ b/test/Transforms/SimplifyLibCalls/StrNCmp.ll
@@ -1,35 +1,78 @@
-; Test that the StrNCmpOptimizer works correctly
-; RUN: opt < %s -simplify-libcalls -S | \
-; RUN: not grep {call.*strncmp}
+; Test that the StrCmpOptimizer works correctly
+; RUN: opt < %s -simplify-libcalls -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-n8:16:32"
-target triple = "i386-apple-darwin9.0"
+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"
@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1]
@hell = constant [5 x i8] c"hell\00" ; <[5 x i8]*> [#uses=1]
+@bell = constant [5 x i8] c"bell\00" ; <[5 x i8]*> [#uses=1]
@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1]
declare i32 @strncmp(i8*, i8*, i32)
-declare i32 @puts(i8*)
-
-define i32 @main() {
- %hello_p = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=5]
- %hell_p = getelementptr [5 x i8]* @hell, i32 0, i32 0 ; <i8*> [#uses=1]
- %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=4]
- %temp1 = call i32 @strncmp( i8* %hello_p, i8* %hello_p, i32 5 ) ; <i32> [#uses=1]
- %temp2 = call i32 @strncmp( i8* %null_p, i8* %null_p, i32 0 ) ; <i32> [#uses=1]
- %temp3 = call i32 @strncmp( i8* %hello_p, i8* %null_p, i32 0 ) ; <i32> [#uses=1]
- %temp4 = call i32 @strncmp( i8* %null_p, i8* %hello_p, i32 0 ) ; <i32> [#uses=1]
- %temp5 = call i32 @strncmp( i8* %hell_p, i8* %hello_p, i32 4 ) ; <i32> [#uses=1]
- %rslt1 = add i32 %temp1, %temp2 ; <i32> [#uses=1]
- %rslt2 = add i32 %rslt1, %temp3 ; <i32> [#uses=1]
- %rslt3 = add i32 %rslt2, %temp4 ; <i32> [#uses=1]
- %rslt4 = add i32 %rslt3, %temp5 ; <i32> [#uses=1]
- ret i32 %rslt4
-}
-
-define i32 @test1(i8* %P, i8* %Q) {
- %cmp = call i32 @strncmp(i8* %P, i8* %Q, i32 1)
- ret i32 %cmp
+; strcmp("", x) -> -*x
+define i32 @test1(i8* %str) {
+ %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i8* %str, i32 10)
+ ret i32 %temp1
+ ; CHECK: @test1
+ ; CHECK: %strcmpload = load i8* %str
+ ; CHECK: %1 = zext i8 %strcmpload to i32
+ ; CHECK: %temp1 = sub i32 0, %1
+ ; CHECK: ret i32 %temp1
+}
+
+; strcmp(x, "") -> *x
+define i32 @test2(i8* %str) {
+ %temp1 = call i32 @strncmp(i8* %str, i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i32 10)
+ ret i32 %temp1
+ ; CHECK: @test2
+ ; CHECK: %strcmpload = load i8* %str
+ ; CHECK: %temp1 = zext i8 %strcmpload to i32
+ ; CHECK: ret i32 %temp1
+}
+
+; strncmp(x, y, n) -> cnst
+define i32 @test3() {
+ %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i32 10)
+ ret i32 %temp1
+ ; CHECK: @test3
+ ; CHECK: ret i32 -1
+}
+define i32 @test4() {
+ %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i32 10)
+ ret i32 %temp1
+ ; CHECK: @test4
+ ; CHECK: ret i32 1
+}
+define i32 @test5() {
+ %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i32 4)
+ ret i32 %temp1
+ ; CHECK: @test5
+ ; CHECK: ret i32 0
+}
+
+; strncmp(x,y,1) -> memcmp(x,y,1)
+define i32 @test6(i8* %str1, i8* %str2) {
+ %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1)
+ ret i32 %temp1
+ ; CHECK: @test6
+ ; CHECK: load i8*
+ ; CHECK: load i8*
+ ; CHECK: sub i32
+}
+
+; strncmp(x,y,0) -> 0
+define i32 @test7(i8* %str1, i8* %str2) {
+ %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 0)
+ ret i32 %temp1
+ ; CHECK: @test7
+ ; CHECK: ret i32 0
+}
+
+; strncmp(x,x,n) -> 0
+define i32 @test8(i8* %str, i32 %n) {
+ %temp1 = call i32 @strncmp(i8* %str, i8* %str, i32 %n)
+ ret i32 %temp1
+ ; CHECK: @test8
+ ; CHECK: ret i32 0
}
diff --git a/test/Transforms/SimplifyLibCalls/memcmp.ll b/test/Transforms/SimplifyLibCalls/memcmp.ll
index ee99501bc0d83..6ca4dc97a194e 100644
--- a/test/Transforms/SimplifyLibCalls/memcmp.ll
+++ b/test/Transforms/SimplifyLibCalls/memcmp.ll
@@ -10,26 +10,26 @@ declare i32 @memcmp(i8*, i8*, i32)
define void @test(i8* %P, i8* %Q, i32 %N, i32* %IP, i1* %BP) {
%A = call i32 @memcmp( i8* %P, i8* %P, i32 %N ) ; <i32> [#uses=1]
; CHECK-NOT: call {{.*}} memcmp
-; CHECK: volatile store
- volatile store i32 %A, i32* %IP
+; CHECK: store volatile
+ store volatile i32 %A, i32* %IP
%B = call i32 @memcmp( i8* %P, i8* %Q, i32 0 ) ; <i32> [#uses=1]
; CHECK-NOT: call {{.*}} memcmp
-; CHECK: volatile store
- volatile store i32 %B, i32* %IP
+; CHECK: store volatile
+ store volatile i32 %B, i32* %IP
%C = call i32 @memcmp( i8* %P, i8* %Q, i32 1 ) ; <i32> [#uses=1]
; CHECK: load
; CHECK: zext
; CHECK: load
; CHECK: zext
; CHECK: sub
-; CHECK: volatile store
- volatile store i32 %C, i32* %IP
- %F = call i32 @memcmp(i8* getelementptr ([4 x i8]* @hel, i32 0, i32 0),
- i8* getelementptr ([8 x i8]* @hello_u, i32 0, i32 0),
- i32 3)
+; CHECK: store volatile
+ store volatile i32 %C, i32* %IP
+ %F = call i32 @memcmp(i8* getelementptr ([4 x i8]* @hel, i32 0, i32 0),
+ i8* getelementptr ([8 x i8]* @hello_u, i32 0, i32 0),
+ i32 3)
; CHECK-NOT: call {{.*}} memcmp
-; CHECK: volatile store
- volatile store i32 %F, i32* %IP
+; CHECK: store volatile
+ store volatile i32 %F, i32* %IP
ret void
}
diff --git a/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll b/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll
index 669b414531af0..0480fdda8916b 100644
--- a/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll
+++ b/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll
@@ -7,9 +7,9 @@
; CHECK: define float @foo(float %x) nounwind {
; CHECK: %sqrtf = call float @sqrtf(float %x) nounwind readonly
; CHECK: %fabsf = call float @fabsf(float %sqrtf) nounwind readonly
-; CHECK: %tmp = fcmp oeq float %x, 0xFFF0000000000000
-; CHECK: %tmp1 = select i1 %tmp, float 0x7FF0000000000000, float %fabsf
-; CHECK: ret float %tmp1
+; CHECK: %1 = fcmp oeq float %x, 0xFFF0000000000000
+; CHECK: %retval = select i1 %1, float 0x7FF0000000000000, float %fabsf
+; CHECK: ret float %retval
define float @foo(float %x) nounwind {
%retval = call float @powf(float %x, float 0.5)
@@ -19,9 +19,9 @@ define float @foo(float %x) nounwind {
; CHECK: define double @doo(double %x) nounwind {
; CHECK: %sqrt = call double @sqrt(double %x) nounwind readonly
; CHECK: %fabs = call double @fabs(double %sqrt) nounwind readonly
-; CHECK: %tmp = fcmp oeq double %x, 0xFFF0000000000000
-; CHECK: %tmp1 = select i1 %tmp, double 0x7FF0000000000000, double %fabs
-; CHECK: ret double %tmp1
+; CHECK: %1 = fcmp oeq double %x, 0xFFF0000000000000
+; CHECK: %retval = select i1 %1, double 0x7FF0000000000000, double %fabs
+; CHECK: ret double %retval
; CHECK: }
define double @doo(double %x) nounwind {
diff --git a/test/Transforms/Sink/basic.ll b/test/Transforms/Sink/basic.ll
index 54b7f1369de47..23433728c13a6 100644
--- a/test/Transforms/Sink/basic.ll
+++ b/test/Transforms/Sink/basic.ll
@@ -20,3 +20,19 @@ true:
false:
ret i32 0
}
+
+; But don't sink volatile loads...
+
+; CHECK: @foo2
+; CHECK: load volatile
+; CHECK-NEXT: store i32
+
+define i32 @foo2(i1 %z) {
+ %l = load volatile i32* @A
+ store i32 0, i32* @B
+ br i1 %z, label %true, label %false
+true:
+ ret i32 %l
+false:
+ ret i32 0
+}
diff --git a/test/Transforms/StripSymbols/block-address.ll b/test/Transforms/StripSymbols/block-address.ll
new file mode 100644
index 0000000000000..d22c6b1b157c9
--- /dev/null
+++ b/test/Transforms/StripSymbols/block-address.ll
@@ -0,0 +1,23 @@
+; RUN: opt %s -strip -S | FileCheck %s
+; PR10286
+
+@main_addrs = constant [2 x i8*] [i8* blockaddress(@f, %FOO), i8* blockaddress(@f, %BAR)]
+; CHECK: @main_addrs = constant [2 x i8*] [i8* blockaddress(@f, %2), i8* blockaddress(@f, %3)]
+
+declare void @foo() nounwind
+declare void @bar() nounwind
+
+define void @f(i8* %indirect.goto.dest) nounwind uwtable ssp {
+entry:
+ indirectbr i8* %indirect.goto.dest, [label %FOO, label %BAR]
+
+ ; CHECK: indirectbr i8* %0, [label %2, label %3]
+
+FOO:
+ call void @foo()
+ ret void
+
+BAR:
+ call void @bar()
+ ret void
+}
diff --git a/test/Transforms/TailCallElim/dont_reorder_load.ll b/test/Transforms/TailCallElim/dont_reorder_load.ll
index cc273c3ca53db..899e115966887 100644
--- a/test/Transforms/TailCallElim/dont_reorder_load.ll
+++ b/test/Transforms/TailCallElim/dont_reorder_load.ll
@@ -16,7 +16,7 @@ entry:
br i1 %tmp2, label %if, label %else
if: ; preds = %entry
- unwind
+ ret i32 37
else: ; preds = %entry
%tmp7 = add i32 %start_arg, 1 ; <i32> [#uses=1]
diff --git a/test/Transforms/TailCallElim/reorder_load.ll b/test/Transforms/TailCallElim/reorder_load.ll
index 7f8af7ea14765..7f5c36e4a207b 100644
--- a/test/Transforms/TailCallElim/reorder_load.ll
+++ b/test/Transforms/TailCallElim/reorder_load.ll
@@ -43,7 +43,7 @@ else: ; preds = %entry
br i1 %nullcheck, label %unwind, label %recurse
unwind: ; preds = %else
- unwind
+ unreachable
recurse: ; preds = %else
%tmp7 = add i32 %start_arg, 1 ; <i32> [#uses=1]
@@ -89,7 +89,7 @@ else: ; preds = %entry
br i1 %nullcheck, label %unwind, label %recurse
unwind: ; preds = %else
- unwind
+ unreachable
recurse: ; preds = %else
%tmp7 = add i32 %start_arg, 1 ; <i32> [#uses=1]
diff --git a/test/Transforms/TailCallElim/setjmp.ll b/test/Transforms/TailCallElim/setjmp.ll
index 7b7fe568259e4..7ef9cb360f53c 100644
--- a/test/Transforms/TailCallElim/setjmp.ll
+++ b/test/Transforms/TailCallElim/setjmp.ll
@@ -1,10 +1,14 @@
; RUN: opt < %s -tailcallelim -S | FileCheck %s
-; Test that we don't tail call in a functions that calls setjmp.
+; Test that we don't tail call in a functions that calls returns_twice
+; functions.
+declare void @bar()
+
+; CHECK: foo1
; CHECK-NOT: tail call void @bar()
-define void @foo(i32* %x) {
+define void @foo1(i32* %x) {
bb:
%tmp75 = tail call i32 @setjmp(i32* %x)
call void @bar()
@@ -13,4 +17,13 @@ bb:
declare i32 @setjmp(i32*)
-declare void @bar()
+; CHECK: foo2
+; CHECK-NOT: tail call void @bar()
+
+define void @foo2(i32* %x) {
+bb:
+ %tmp75 = tail call i32 @zed2(i32* %x)
+ call void @bar()
+ ret void
+}
+declare i32 @zed2(i32*) returns_twice
diff --git a/test/Transforms/TailDup/2003-06-24-Simpleloop.ll b/test/Transforms/TailDup/2003-06-24-Simpleloop.ll
deleted file mode 100644
index d7e45af5eceb7..0000000000000
--- a/test/Transforms/TailDup/2003-06-24-Simpleloop.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-define void @motion_result7() {
-entry:
- br label %endif
-endif: ; preds = %no_exit, %entry
- %i.1 = phi i32 [ %inc, %no_exit ], [ 0, %entry ] ; <i32> [#uses=1]
- %inc = add i32 %i.1, 1 ; <i32> [#uses=1]
- br i1 false, label %no_exit, label %UnifiedExitNode
-no_exit: ; preds = %endif
- br i1 false, label %UnifiedExitNode, label %endif
-UnifiedExitNode: ; preds = %no_exit, %endif
- ret void
-}
-
diff --git a/test/Transforms/TailDup/2003-07-22-InfiniteLoop.ll b/test/Transforms/TailDup/2003-07-22-InfiniteLoop.ll
deleted file mode 100644
index 90f49909e5c10..0000000000000
--- a/test/Transforms/TailDup/2003-07-22-InfiniteLoop.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-define i32 @sum() {
-entry:
- br label %loopentry
-loopentry: ; preds = %loopentry, %entry
- %i.0 = phi i32 [ 1, %entry ], [ %tmp.3, %loopentry ] ; <i32> [#uses=1]
- %tmp.3 = add i32 %i.0, 1 ; <i32> [#uses=1]
- br label %loopentry
-}
-
diff --git a/test/Transforms/TailDup/2003-08-23-InvalidatedPointers.ll b/test/Transforms/TailDup/2003-08-23-InvalidatedPointers.ll
deleted file mode 100644
index efe9eaed7ebdd..0000000000000
--- a/test/Transforms/TailDup/2003-08-23-InvalidatedPointers.ll
+++ /dev/null
@@ -1,29 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-define i32 @sell_haggle() {
-entry:
- br i1 false, label %then.5, label %UnifiedExitNode
-then.5: ; preds = %entry
- br i1 false, label %loopentry.1.preheader, label %else.1
-else.1: ; preds = %then.5
- br label %loopentry.1.preheader
-loopentry.1.preheader: ; preds = %else.1, %then.5
- %final_ask.0 = phi i32 [ 0, %else.1 ], [ 0, %then.5 ] ; <i32> [#uses=2]
- br label %loopentry.1
-loopentry.1: ; preds = %endif.17, %loopentry.1.preheader
- switch i32 0, label %UnifiedExitNode [
- i32 2, label %UnifiedExitNode
- i32 1, label %endif.16
- ]
-endif.16: ; preds = %loopentry.1
- br i1 false, label %then.17, label %UnifiedExitNode
-then.17: ; preds = %endif.16
- br i1 false, label %then.18, label %endif.17
-then.18: ; preds = %then.17
- br i1 false, label %endif.17, label %UnifiedExitNode
-endif.17: ; preds = %then.18, %then.17
- %cur_ask.3 = phi i32 [ %final_ask.0, %then.17 ], [ %final_ask.0, %then.18 ] ; <i32> [#uses=0]
- br i1 false, label %loopentry.1, label %UnifiedExitNode
-UnifiedExitNode: ; preds = %endif.17, %then.18, %endif.16, %loopentry.1, %loopentry.1, %entry
- ret i32 0
-}
diff --git a/test/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll b/test/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll
deleted file mode 100644
index dc6492353b7ed..0000000000000
--- a/test/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll
+++ /dev/null
@@ -1,17 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-define i32 @foo() {
-entry:
- br label %return.i
-after_ret.i: ; No predecessors!
- br label %return.i
-return.i: ; preds = %after_ret.i, %entry
- %tmp.3 = ptrtoint i32* null to i32 ; <i32> [#uses=1]
- br label %return.i1
-after_ret.i1: ; No predecessors!
- br label %return.i1
-return.i1: ; preds = %after_ret.i1, %return.i
- %tmp.8 = sub i32 %tmp.3, 0 ; <i32> [#uses=0]
- ret i32 0
-}
-
diff --git a/test/Transforms/TailDup/2004-04-01-DemoteRegToStack.ll b/test/Transforms/TailDup/2004-04-01-DemoteRegToStack.ll
deleted file mode 100644
index c1e5f738a7d98..0000000000000
--- a/test/Transforms/TailDup/2004-04-01-DemoteRegToStack.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-define void @interpret() {
-entry:
- br label %retry
-retry: ; preds = %endif.4, %entry
- %tmp.8 = call i32 @interp( ) ; <i32> [#uses=3]
- switch i32 0, label %endif.4 [
- i32 -25, label %return
- i32 -16, label %return
- ]
-endif.4: ; preds = %retry
- br i1 false, label %return, label %retry
-return: ; preds = %endif.4, %retry, %retry
- %result.0 = phi i32 [ %tmp.8, %retry ], [ %tmp.8, %retry ], [ %tmp.8, %endif.4 ] ; <i32> [#uses=0]
- ret void
-}
-
-declare i32 @interp()
-
diff --git a/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll b/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll
deleted file mode 100644
index 3e4f0b78748c4..0000000000000
--- a/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll
+++ /dev/null
@@ -1,26 +0,0 @@
-; RUN: opt < %s -tailduplicate | llc
-; PR2323
-
-define i32 @func_27(i32 %p_28) nounwind {
-entry:
- %tmp125 = trunc i32 %p_28 to i8 ; <i8> [#uses=1]
- %tmp5.i = icmp eq i8 %tmp125, 0 ; <i1> [#uses=1]
- br i1 %tmp5.i, label %bb8.i, label %bb.i
-
-bb.i: ; preds = %entry
- br label %bb39.i
-
-bb8.i: ; preds = %entry
- br label %bb11.i
-
-bb11.i: ; preds = %bb39.i, %bb8.i
- %tmp126 = trunc i32 %p_28 to i8 ; <i8> [#uses=1]
- br label %bb39.i
-
-bb39.i: ; preds = %bb11.i, %bb.i
- %tmp127 = trunc i32 %p_28 to i8 ; <i8> [#uses=1]
- br label %bb11.i
-
-func_29.exit: ; No predecessors!
- ret i32 undef
-}
diff --git a/test/Transforms/TailDup/2009-07-31-phicrash.ll b/test/Transforms/TailDup/2009-07-31-phicrash.ll
deleted file mode 100644
index ad1a0404761a6..0000000000000
--- a/test/Transforms/TailDup/2009-07-31-phicrash.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-; PR4662
-
-define void @a() {
-BB:
- br label %BB6
-
-BB6:
- %tmp9 = phi i64 [ 0, %BB ], [ 5, %BB34 ]
- br label %BB34
-
-BB34:
- br label %BB6
-}
diff --git a/test/Transforms/TailDup/MergeTest.ll b/test/Transforms/TailDup/MergeTest.ll
deleted file mode 100644
index 2224283d8eec6..0000000000000
--- a/test/Transforms/TailDup/MergeTest.ll
+++ /dev/null
@@ -1,27 +0,0 @@
-; RUN: opt < %s -tailduplicate -taildup-threshold=2 -S | grep add | not grep uses=1
-
-define i32 @test1(i1 %C, i32 %A, i32* %P) {
-entry:
- br i1 %C, label %L1, label %L2
-L1: ; preds = %entry
- store i32 1, i32* %P
- br label %L2
-L2: ; preds = %L1, %entry
- %X = add i32 %A, 17 ; <i32> [#uses=1]
- ret i32 %X
-}
-
-define i32 @test2(i1 %C, i32 %A, i32* %P) {
-entry:
- br i1 %C, label %L1, label %L2
-L1: ; preds = %entry
- store i32 1, i32* %P
- br label %L3
-L2: ; preds = %entry
- store i32 7, i32* %P
- br label %L3
-L3: ; preds = %L2, %L1
- %X = add i32 %A, 17 ; <i32> [#uses=1]
- ret i32 %X
-}
-
diff --git a/test/Transforms/TailDup/PHIUpdateTest.ll b/test/Transforms/TailDup/PHIUpdateTest.ll
deleted file mode 100644
index 38d8ebfcce565..0000000000000
--- a/test/Transforms/TailDup/PHIUpdateTest.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; This test checks to make sure phi nodes are updated properly
-;
-; RUN: opt < %s -tailduplicate -disable-output
-
-define i32 @test(i1 %c, i32 %X, i32 %Y) {
- br label %L
-L: ; preds = %F, %0
- %A = add i32 %X, %Y ; <i32> [#uses=1]
- br i1 %c, label %T, label %F
-F: ; preds = %L
- br i1 %c, label %L, label %T
-T: ; preds = %F, %L
- %V = phi i32 [ %A, %L ], [ 0, %F ] ; <i32> [#uses=1]
- ret i32 %V
-}
-
diff --git a/test/Transforms/TailDup/X86/if-tail-dup.ll b/test/Transforms/TailDup/X86/if-tail-dup.ll
deleted file mode 100644
index 2e4f5be38d1d2..0000000000000
--- a/test/Transforms/TailDup/X86/if-tail-dup.ll
+++ /dev/null
@@ -1,49 +0,0 @@
-; RUN: opt < %s -tailduplicate | \
-; RUN: llc -march=x86 -o %t
-; RUN: grep {\\\<je\\\>} %t
-; RUN: not grep jmp %t
-; END.
-; This should have no unconditional jumps in it. The C source is:
-
-;void foo(int c, int* P) {
-; if (c & 1) P[0] = 1;
-; if (c & 2) P[1] = 1;
-; if (c & 4) P[2] = 1;
-; if (c & 8) P[3] = 1;
-;}
-
-define void @foo(i32 %c, i32* %P) {
-entry:
- %tmp1 = and i32 %c, 1 ; <i32> [#uses=1]
- %tmp1.upgrd.1 = icmp eq i32 %tmp1, 0 ; <i1> [#uses=1]
- br i1 %tmp1.upgrd.1, label %cond_next, label %cond_true
-cond_true: ; preds = %entry
- store i32 1, i32* %P
- br label %cond_next
-cond_next: ; preds = %cond_true, %entry
- %tmp5 = and i32 %c, 2 ; <i32> [#uses=1]
- %tmp5.upgrd.2 = icmp eq i32 %tmp5, 0 ; <i1> [#uses=1]
- br i1 %tmp5.upgrd.2, label %cond_next10, label %cond_true6
-cond_true6: ; preds = %cond_next
- %tmp8 = getelementptr i32* %P, i32 1 ; <i32*> [#uses=1]
- store i32 1, i32* %tmp8
- br label %cond_next10
-cond_next10: ; preds = %cond_true6, %cond_next
- %tmp13 = and i32 %c, 4 ; <i32> [#uses=1]
- %tmp13.upgrd.3 = icmp eq i32 %tmp13, 0 ; <i1> [#uses=1]
- br i1 %tmp13.upgrd.3, label %cond_next18, label %cond_true14
-cond_true14: ; preds = %cond_next10
- %tmp16 = getelementptr i32* %P, i32 2 ; <i32*> [#uses=1]
- store i32 1, i32* %tmp16
- br label %cond_next18
-cond_next18: ; preds = %cond_true14, %cond_next10
- %tmp21 = and i32 %c, 8 ; <i32> [#uses=1]
- %tmp21.upgrd.4 = icmp eq i32 %tmp21, 0 ; <i1> [#uses=1]
- br i1 %tmp21.upgrd.4, label %return, label %cond_true22
-cond_true22: ; preds = %cond_next18
- %tmp24 = getelementptr i32* %P, i32 3 ; <i32*> [#uses=1]
- store i32 1, i32* %tmp24
- ret void
-return: ; preds = %cond_next18
- ret void
-}
diff --git a/test/Transforms/TailDup/basictest.ll b/test/Transforms/TailDup/basictest.ll
deleted file mode 100644
index 94f5d87ad2bbc..0000000000000
--- a/test/Transforms/TailDup/basictest.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-declare void @__main()
-
-define i32 @main() {
-entry:
- call void @__main( )
- br label %loopentry
-loopentry: ; preds = %no_exit, %entry
- %i.0 = phi i32 [ %inc, %no_exit ], [ 0, %entry ] ; <i32> [#uses=3]
- %tmp.1 = icmp sle i32 %i.0, 99 ; <i1> [#uses=1]
- br i1 %tmp.1, label %no_exit, label %return
-no_exit: ; preds = %loopentry
- %tmp.51 = call i32 @main( ) ; <i32> [#uses=0]
- %inc = add i32 %i.0, 1 ; <i32> [#uses=1]
- br label %loopentry
-return: ; preds = %loopentry
- ret i32 %i.0
-}
-
diff --git a/test/Transforms/TailDup/basictest2.ll b/test/Transforms/TailDup/basictest2.ll
deleted file mode 100644
index 81a996adfee23..0000000000000
--- a/test/Transforms/TailDup/basictest2.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -tailduplicate -disable-output
-
-define void @ab() {
-entry:
- br label %loopentry.5
-loopentry.5: ; preds = %no_exit.5, %entry
- %poscnt.1 = phi i64 [ 0, %entry ], [ %tmp.289, %no_exit.5 ] ; <i64> [#uses=1]
- %tmp.289 = ashr i64 %poscnt.1, 1 ; <i64> [#uses=1]
- br i1 false, label %no_exit.5, label %loopexit.5
-no_exit.5: ; preds = %loopentry.5
- br label %loopentry.5
-loopexit.5: ; preds = %loopentry.5
- ret void
-}
-