summaryrefslogtreecommitdiffstats
path: root/test/Transforms
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-04-14 13:54:10 +0000
committerdim <dim@FreeBSD.org>2012-04-14 13:54:10 +0000
commit1fc08f5e9ef733ef1ce6f363fecedc2260e78974 (patch)
tree19c69a04768629f2d440944b71cbe90adae0b615 /test/Transforms
parent07637c87f826cdf411f0673595e9bc92ebd793f2 (diff)
downloadFreeBSD-src-1fc08f5e9ef733ef1ce6f363fecedc2260e78974.zip
FreeBSD-src-1fc08f5e9ef733ef1ce6f363fecedc2260e78974.tar.gz
Vendor import of llvm trunk r154661:
http://llvm.org/svn/llvm-project/llvm/trunk@r154661
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/ADCE/dg.exp3
-rw-r--r--test/Transforms/ADCE/lit.local.cfg1
-rw-r--r--test/Transforms/ArgumentPromotion/dg.exp3
-rw-r--r--test/Transforms/ArgumentPromotion/lit.local.cfg1
-rw-r--r--test/Transforms/BBVectorize/cycle.ll112
-rw-r--r--test/Transforms/BBVectorize/func-alias.ll244
-rw-r--r--test/Transforms/BBVectorize/ld1.ll41
-rw-r--r--test/Transforms/BBVectorize/lit.local.cfg1
-rw-r--r--test/Transforms/BBVectorize/loop1.ll93
-rw-r--r--test/Transforms/BBVectorize/mem-op-depth.ll22
-rw-r--r--test/Transforms/BBVectorize/req-depth.ll17
-rw-r--r--test/Transforms/BBVectorize/search-limit.ll46
-rw-r--r--test/Transforms/BBVectorize/simple-int.ll103
-rw-r--r--test/Transforms/BBVectorize/simple-ldstr.ll110
-rw-r--r--test/Transforms/BBVectorize/simple.ll152
-rw-r--r--test/Transforms/BlockPlacement/dg.exp3
-rw-r--r--test/Transforms/BlockPlacement/lit.local.cfg1
-rw-r--r--test/Transforms/CodeExtractor/dg.exp3
-rw-r--r--test/Transforms/CodeExtractor/lit.local.cfg1
-rw-r--r--test/Transforms/CodeGenPrepare/dg.exp3
-rw-r--r--test/Transforms/CodeGenPrepare/lit.local.cfg1
-rw-r--r--test/Transforms/ConstProp/2007-11-23-cttz.ll4
-rw-r--r--test/Transforms/ConstProp/basictest.ll11
-rw-r--r--test/Transforms/ConstProp/bswap.ll18
-rw-r--r--test/Transforms/ConstProp/calls.ll88
-rw-r--r--test/Transforms/ConstProp/dg.exp3
-rw-r--r--test/Transforms/ConstProp/lit.local.cfg1
-rw-r--r--test/Transforms/ConstantMerge/dg.exp3
-rw-r--r--test/Transforms/ConstantMerge/linker-private.ll23
-rw-r--r--test/Transforms/ConstantMerge/lit.local.cfg1
-rw-r--r--test/Transforms/CorrelatedValuePropagation/basic.ll101
-rw-r--r--test/Transforms/CorrelatedValuePropagation/dg.exp3
-rw-r--r--test/Transforms/CorrelatedValuePropagation/lit.local.cfg1
-rw-r--r--test/Transforms/CorrelatedValuePropagation/range.ll43
-rw-r--r--test/Transforms/DeadArgElim/deadexternal.ll4
-rw-r--r--test/Transforms/DeadArgElim/dg.exp3
-rw-r--r--test/Transforms/DeadArgElim/lit.local.cfg1
-rw-r--r--test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll95
-rw-r--r--test/Transforms/DeadStoreElimination/dg.exp3
-rw-r--r--test/Transforms/DeadStoreElimination/dominate.ll25
-rw-r--r--test/Transforms/DeadStoreElimination/free.ll36
-rw-r--r--test/Transforms/DeadStoreElimination/lit.local.cfg1
-rw-r--r--test/Transforms/DeadStoreElimination/pr11390.ll38
-rw-r--r--test/Transforms/DeadStoreElimination/simple.ll7
-rw-r--r--test/Transforms/EarlyCSE/basic.ll10
-rw-r--r--test/Transforms/EarlyCSE/dg.exp3
-rw-r--r--test/Transforms/EarlyCSE/instsimplify-dom.ll19
-rw-r--r--test/Transforms/EarlyCSE/lit.local.cfg1
-rw-r--r--test/Transforms/FunctionAttrs/2008-09-13-VolatileRead.ll2
-rw-r--r--test/Transforms/FunctionAttrs/2010-10-30-volatile.ll2
-rw-r--r--test/Transforms/FunctionAttrs/dg.exp3
-rw-r--r--test/Transforms/FunctionAttrs/lit.local.cfg1
-rw-r--r--test/Transforms/FunctionAttrs/nocapture.ll (renamed from test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll)77
-rw-r--r--test/Transforms/GVN/commute.ll23
-rw-r--r--test/Transforms/GVN/condprop.ll157
-rw-r--r--test/Transforms/GVN/dg.exp3
-rw-r--r--test/Transforms/GVN/lit.local.cfg1
-rw-r--r--test/Transforms/GVN/pre-compare.ll68
-rw-r--r--test/Transforms/GVN/rle.ll34
-rw-r--r--test/Transforms/GlobalDCE/2009-09-03-MDNode.ll264
-rw-r--r--test/Transforms/GlobalDCE/dg.exp3
-rw-r--r--test/Transforms/GlobalDCE/lit.local.cfg1
-rw-r--r--test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll2
-rw-r--r--test/Transforms/GlobalOpt/2008-02-16-NestAttr.ll57
-rw-r--r--test/Transforms/GlobalOpt/atomic.ll10
-rw-r--r--test/Transforms/GlobalOpt/constantfold-initializers.ll43
-rw-r--r--test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll19
-rw-r--r--test/Transforms/GlobalOpt/cxx-dtor.ll6
-rw-r--r--test/Transforms/GlobalOpt/deadfunction.ll27
-rw-r--r--test/Transforms/GlobalOpt/dg.exp3
-rw-r--r--test/Transforms/GlobalOpt/invariant.ll59
-rw-r--r--test/Transforms/GlobalOpt/invoke.ll27
-rw-r--r--test/Transforms/GlobalOpt/lit.local.cfg1
-rw-r--r--test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll11
-rw-r--r--test/Transforms/IPConstantProp/dangling-block-address.ll2
-rw-r--r--test/Transforms/IPConstantProp/dg.exp3
-rw-r--r--test/Transforms/IPConstantProp/lit.local.cfg1
-rw-r--r--test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll4
-rw-r--r--test/Transforms/IndVarSimplify/2011-10-27-lftrnull.ll59
-rw-r--r--test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll140
-rw-r--r--test/Transforms/IndVarSimplify/2011-11-15-multiexit.ll40
-rw-r--r--test/Transforms/IndVarSimplify/2011-11-17-selfphi.ll29
-rw-r--r--test/Transforms/IndVarSimplify/ada-loops.ll1
-rw-r--r--test/Transforms/IndVarSimplify/avoid-i0.ll2
-rw-r--r--test/Transforms/IndVarSimplify/complex-scev.ll31
-rw-r--r--test/Transforms/IndVarSimplify/dg.exp3
-rw-r--r--test/Transforms/IndVarSimplify/elim-extend.ll2
-rw-r--r--test/Transforms/IndVarSimplify/gep-with-mul-base.ll68
-rw-r--r--test/Transforms/IndVarSimplify/iv-fold.ll2
-rw-r--r--test/Transforms/IndVarSimplify/iv-zext.ll1
-rw-r--r--test/Transforms/IndVarSimplify/lftr-reuse.ll2
-rw-r--r--test/Transforms/IndVarSimplify/lit.local.cfg1
-rw-r--r--test/Transforms/IndVarSimplify/loop_evaluate10.ll8
-rw-r--r--test/Transforms/IndVarSimplify/loop_evaluate9.ll7
-rw-r--r--test/Transforms/IndVarSimplify/no-iv-rewrite.ll6
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep-nested.ll76
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep-remainder.ll20
-rw-r--r--test/Transforms/IndVarSimplify/preserve-gep.ll39
-rw-r--r--test/Transforms/IndVarSimplify/preserve-signed-wrap.ll1
-rw-r--r--test/Transforms/IndVarSimplify/sink-alloca.ll47
-rw-r--r--test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll1
-rw-r--r--test/Transforms/Inline/2007-06-06-NoInline.ll46
-rw-r--r--test/Transforms/Inline/2008-09-02-AlwaysInline.ll10
-rw-r--r--test/Transforms/Inline/2008-10-30-AlwaysInline.ll14
-rw-r--r--test/Transforms/Inline/2008-11-04-AlwaysInline.ll7
-rw-r--r--test/Transforms/Inline/alloca-bonus.ll155
-rw-r--r--test/Transforms/Inline/always-inline.ll125
-rw-r--r--test/Transforms/Inline/always_inline_dyn_alloca.ll15
-rw-r--r--test/Transforms/Inline/blockaddress.ll27
-rw-r--r--test/Transforms/Inline/dg.exp3
-rw-r--r--test/Transforms/Inline/dynamic_alloca_test.ll52
-rw-r--r--test/Transforms/Inline/inline-invoke-tail.ll8
-rw-r--r--test/Transforms/Inline/inline_cleanup.ll158
-rw-r--r--test/Transforms/Inline/inline_constprop.ll114
-rw-r--r--test/Transforms/Inline/inline_returns_twice.ll41
-rw-r--r--test/Transforms/Inline/lit.local.cfg1
-rw-r--r--test/Transforms/Inline/noinline-recursive-fn.ll43
-rw-r--r--test/Transforms/Inline/ptr-diff.ll58
-rw-r--r--test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll2
-rw-r--r--test/Transforms/InstCombine/2007-09-11-Trampoline.ll24
-rw-r--r--test/Transforms/InstCombine/2007-10-28-stacksave.ll2
-rw-r--r--test/Transforms/InstCombine/2008-01-14-DoubleNest.ll24
-rw-r--r--test/Transforms/InstCombine/2008-04-28-VolatileStore.ll2
-rw-r--r--test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll6
-rw-r--r--test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll4
-rw-r--r--test/Transforms/InstCombine/2008-06-24-StackRestore.ll4
-rw-r--r--test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll6
-rw-r--r--test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll12
-rw-r--r--test/Transforms/InstCombine/2012-02-13-FCmp.ll35
-rw-r--r--test/Transforms/InstCombine/2012-02-28-ICmp.ll19
-rw-r--r--test/Transforms/InstCombine/2012-03-10-InstCombine.ll35
-rw-r--r--test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll12
-rw-r--r--test/Transforms/InstCombine/LandingPadClauses.ll52
-rw-r--r--test/Transforms/InstCombine/align-external.ll13
-rw-r--r--test/Transforms/InstCombine/alloca.ll44
-rw-r--r--test/Transforms/InstCombine/apint-shl-trunc.ll15
-rw-r--r--test/Transforms/InstCombine/bitcount.ll8
-rw-r--r--test/Transforms/InstCombine/constant-fold-gep.ll6
-rw-r--r--test/Transforms/InstCombine/crash.ll15
-rw-r--r--test/Transforms/InstCombine/dg.exp3
-rw-r--r--test/Transforms/InstCombine/extractvalue.ll6
-rw-r--r--test/Transforms/InstCombine/fold-sqrt-sqrtf.ll17
-rw-r--r--test/Transforms/InstCombine/icmp.ll84
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll46
-rw-r--r--test/Transforms/InstCombine/lit.local.cfg1
-rw-r--r--test/Transforms/InstCombine/mul.ll80
-rw-r--r--test/Transforms/InstCombine/overflow.ll22
-rw-r--r--test/Transforms/InstCombine/pr12251.ll15
-rw-r--r--test/Transforms/InstCombine/select.ll20
-rw-r--r--test/Transforms/InstCombine/sext.ll8
-rw-r--r--test/Transforms/InstCombine/shift.ll72
-rw-r--r--test/Transforms/InstCombine/sign-test-and-or.ll100
-rw-r--r--test/Transforms/InstCombine/sub-xor.ll37
-rw-r--r--test/Transforms/InstCombine/sub.ll26
-rw-r--r--test/Transforms/InstCombine/vec_shuffle.ll46
-rw-r--r--test/Transforms/InstCombine/vector_gep1.ll37
-rw-r--r--test/Transforms/InstCombine/volatile_store.ll4
-rw-r--r--test/Transforms/InstSimplify/2011-10-27-BinOpCrash.ll12
-rw-r--r--test/Transforms/InstSimplify/2011-11-23-MaskedBitsCrash.ll17
-rw-r--r--test/Transforms/InstSimplify/AndOrXor.ll22
-rw-r--r--test/Transforms/InstSimplify/compare.ll275
-rw-r--r--test/Transforms/InstSimplify/dg.exp3
-rw-r--r--test/Transforms/InstSimplify/lit.local.cfg1
-rw-r--r--test/Transforms/InstSimplify/phi.ll22
-rw-r--r--test/Transforms/InstSimplify/ptr_diff.ll48
-rw-r--r--test/Transforms/InstSimplify/reassociate.ll9
-rw-r--r--test/Transforms/InstSimplify/undef.ll28
-rw-r--r--test/Transforms/InstSimplify/vector_gep.ll8
-rw-r--r--test/Transforms/Internalize/dg.exp3
-rw-r--r--test/Transforms/Internalize/lit.local.cfg1
-rw-r--r--test/Transforms/JumpThreading/2011-04-14-InfLoop.ll2
-rw-r--r--test/Transforms/JumpThreading/crash.ll2
-rw-r--r--test/Transforms/JumpThreading/dg.exp3
-rw-r--r--test/Transforms/JumpThreading/lit.local.cfg1
-rw-r--r--test/Transforms/JumpThreading/no-irreducible-loops.ll4
-rw-r--r--test/Transforms/JumpThreading/thread-loads.ll48
-rw-r--r--test/Transforms/LCSSA/dg.exp3
-rw-r--r--test/Transforms/LCSSA/lit.local.cfg1
-rw-r--r--test/Transforms/LICM/2007-05-22-VolatileSink.ll4
-rw-r--r--test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll2
-rw-r--r--test/Transforms/LICM/crash.ll2
-rw-r--r--test/Transforms/LICM/dg.exp3
-rw-r--r--test/Transforms/LICM/hoist-invariant-load.ll39
-rw-r--r--test/Transforms/LICM/lit.local.cfg1
-rw-r--r--test/Transforms/LICM/scalar_promote.ll4
-rw-r--r--test/Transforms/LICM/speculate.ll167
-rw-r--r--test/Transforms/LoopDeletion/dg.exp3
-rw-r--r--test/Transforms/LoopDeletion/lit.local.cfg1
-rw-r--r--test/Transforms/LoopIdiom/dg.exp3
-rw-r--r--test/Transforms/LoopIdiom/lit.local.cfg1
-rw-r--r--test/Transforms/LoopRotate/alloca.ll33
-rw-r--r--test/Transforms/LoopRotate/dbgvalue.ll48
-rw-r--r--test/Transforms/LoopRotate/dg.exp3
-rw-r--r--test/Transforms/LoopRotate/lit.local.cfg1
-rw-r--r--test/Transforms/LoopRotate/simplifylatch.ll39
-rw-r--r--test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll45
-rw-r--r--test/Transforms/LoopSimplify/2012-03-20-indirectbr.ll41
-rw-r--r--test/Transforms/LoopSimplify/dg.exp3
-rw-r--r--test/Transforms/LoopSimplify/lit.local.cfg1
-rw-r--r--test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/2011-12-19-PostincQuadratic.ll39
-rw-r--r--test/Transforms/LoopStrengthReduce/2012-01-02-nopreheader.ll88
-rw-r--r--test/Transforms/LoopStrengthReduce/2012-01-16-nopreheader.ll113
-rw-r--r--test/Transforms/LoopStrengthReduce/2012-03-15-nopreheader.ll155
-rw-r--r--test/Transforms/LoopStrengthReduce/2012-03-26-constexpr.ll49
-rw-r--r--test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll292
-rw-r--r--test/Transforms/LoopStrengthReduce/ARM/lit.local.cfg6
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/2011-11-29-postincphi.ll36
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/2011-12-04-loserreg.ll96
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll92
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/dg.exp5
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll300
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/ivchain-stress-X86.ll96
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/lit.local.cfg6
-rw-r--r--test/Transforms/LoopStrengthReduce/addrec-gep.ll (renamed from test/Transforms/IndVarSimplify/addrec-gep.ll)12
-rw-r--r--test/Transforms/LoopStrengthReduce/dg.exp3
-rw-r--r--test/Transforms/LoopStrengthReduce/dominate-assert.ll70
-rw-r--r--test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/ivchain.ll43
-rw-r--r--test/Transforms/LoopStrengthReduce/lit.local.cfg1
-rw-r--r--test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll10
-rw-r--r--test/Transforms/LoopStrengthReduce/pr12018.ll38
-rw-r--r--test/Transforms/LoopStrengthReduce/pr12048.ll38
-rw-r--r--test/Transforms/LoopStrengthReduce/pr3399.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/preserve-gep-loop-variant.ll (renamed from test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll)2
-rw-r--r--test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll2
-rw-r--r--test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll40
-rw-r--r--test/Transforms/LoopUnroll/dg.exp3
-rw-r--r--test/Transforms/LoopUnroll/lit.local.cfg1
-rw-r--r--test/Transforms/LoopUnroll/partial-unroll-optsize.ll35
-rw-r--r--test/Transforms/LoopUnroll/pr11361.ll42
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop.ll109
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop1.ll30
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop2.ll31
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop3.ll44
-rw-r--r--test/Transforms/LoopUnroll/unloop.ll41
-rw-r--r--test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll91
-rw-r--r--test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll84
-rw-r--r--test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll138
-rw-r--r--test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll41
-rw-r--r--test/Transforms/LoopUnswitch/dg.exp3
-rw-r--r--test/Transforms/LoopUnswitch/lit.local.cfg1
-rw-r--r--test/Transforms/LowerAtomic/dg.exp3
-rw-r--r--test/Transforms/LowerAtomic/lit.local.cfg1
-rw-r--r--test/Transforms/LowerExpectIntrinsic/dg.exp3
-rw-r--r--test/Transforms/LowerExpectIntrinsic/lit.local.cfg1
-rw-r--r--test/Transforms/LowerInvoke/dg.exp3
-rw-r--r--test/Transforms/LowerInvoke/lit.local.cfg1
-rw-r--r--test/Transforms/LowerSwitch/dg.exp3
-rw-r--r--test/Transforms/LowerSwitch/lit.local.cfg1
-rw-r--r--test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll8
-rw-r--r--test/Transforms/Mem2Reg/dg.exp3
-rw-r--r--test/Transforms/Mem2Reg/lit.local.cfg1
-rw-r--r--test/Transforms/MemCpyOpt/dg.exp3
-rw-r--r--test/Transforms/MemCpyOpt/form-memset.ll30
-rw-r--r--test/Transforms/MemCpyOpt/lit.local.cfg1
-rw-r--r--test/Transforms/MemCpyOpt/memcpy.ll20
-rw-r--r--test/Transforms/MergeFunc/2011-02-08-RemoveEqual.ll20
-rw-r--r--test/Transforms/MergeFunc/dg.exp3
-rw-r--r--test/Transforms/MergeFunc/lit.local.cfg1
-rw-r--r--test/Transforms/ObjCARC/apelim.ll53
-rw-r--r--test/Transforms/ObjCARC/basic.ll216
-rw-r--r--test/Transforms/ObjCARC/contract-storestrong-ivar.ll2
-rw-r--r--test/Transforms/ObjCARC/contract-storestrong.ll6
-rw-r--r--test/Transforms/ObjCARC/contract.ll18
-rw-r--r--test/Transforms/ObjCARC/dg.exp3
-rw-r--r--test/Transforms/ObjCARC/invoke.ll145
-rw-r--r--test/Transforms/ObjCARC/lit.local.cfg1
-rw-r--r--test/Transforms/ObjCARC/nested.ll141
-rw-r--r--test/Transforms/ObjCARC/no-objc-arc-exceptions.ll122
-rw-r--r--test/Transforms/ObjCARC/pointer-types.ll31
-rw-r--r--test/Transforms/ObjCARC/pr12270.ll21
-rw-r--r--test/Transforms/ObjCARC/retain-block-alloca.ll46
-rw-r--r--test/Transforms/ObjCARC/retain-block-load.ll51
-rw-r--r--test/Transforms/ObjCARC/retain-block.ll138
-rw-r--r--test/Transforms/ObjCARC/retain-not-declared.ll2
-rw-r--r--test/Transforms/PhaseOrdering/dg.exp3
-rw-r--r--test/Transforms/PhaseOrdering/lit.local.cfg1
-rw-r--r--test/Transforms/PruneEH/dg.exp3
-rw-r--r--test/Transforms/PruneEH/lit.local.cfg1
-rw-r--r--test/Transforms/Reassociate/dg.exp3
-rw-r--r--test/Transforms/Reassociate/lit.local.cfg1
-rw-r--r--test/Transforms/SCCP/2008-05-23-UndefCallFold.ll4
-rw-r--r--test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll4
-rw-r--r--test/Transforms/SCCP/dg.exp3
-rw-r--r--test/Transforms/SCCP/lit.local.cfg1
-rw-r--r--test/Transforms/SCCP/phitest.ll20
-rw-r--r--test/Transforms/ScalarRepl/2009-03-05-Aggre2Scalar-dbg.ll184
-rw-r--r--test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll19
-rw-r--r--test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll26
-rw-r--r--test/Transforms/ScalarRepl/debuginfo.ll107
-rw-r--r--test/Transforms/ScalarRepl/dg.exp3
-rw-r--r--test/Transforms/ScalarRepl/lit.local.cfg1
-rw-r--r--test/Transforms/ScalarRepl/negative-memset.ll20
-rw-r--r--test/Transforms/ScalarRepl/phi-cycle.ll77
-rw-r--r--test/Transforms/ScalarRepl/volatile.ll4
-rw-r--r--test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll12
-rw-r--r--test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll6
-rw-r--r--test/Transforms/SimplifyCFG/SpeculativeExec.ll31
-rw-r--r--test/Transforms/SimplifyCFG/branch-branch-dbginfo.ll70
-rw-r--r--test/Transforms/SimplifyCFG/branch-fold.ll16
-rw-r--r--test/Transforms/SimplifyCFG/branch_fold_dbg.ll122
-rw-r--r--test/Transforms/SimplifyCFG/dg.exp3
-rw-r--r--test/Transforms/SimplifyCFG/hoist-common-code.dbg.ll33
-rw-r--r--test/Transforms/SimplifyCFG/lit.local.cfg1
-rw-r--r--test/Transforms/SimplifyCFG/multiple-phis.ll39
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights.ll88
-rw-r--r--test/Transforms/SimplifyCFG/select-gep.ll4
-rw-r--r--test/Transforms/SimplifyCFG/switch-masked-bits.ll4
-rw-r--r--test/Transforms/SimplifyCFG/switch-on-const-select.ll2
-rw-r--r--test/Transforms/SimplifyCFG/switch_formation.dbg.ll50
-rw-r--r--test/Transforms/SimplifyCFG/switch_switch_fold_dbginfo.ll116
-rw-r--r--test/Transforms/SimplifyCFG/two-entry-phi-return.dbg.ll28
-rw-r--r--test/Transforms/SimplifyCFG/unreachable-blocks.ll28
-rw-r--r--test/Transforms/SimplifyLibCalls/PR7357.ll2
-rw-r--r--test/Transforms/SimplifyLibCalls/Printf.ll5
-rw-r--r--test/Transforms/SimplifyLibCalls/StrLen.ll6
-rw-r--r--test/Transforms/SimplifyLibCalls/cos.ll14
-rw-r--r--test/Transforms/SimplifyLibCalls/dg.exp3
-rw-r--r--test/Transforms/SimplifyLibCalls/fwrite.ll13
-rw-r--r--test/Transforms/SimplifyLibCalls/lit.local.cfg1
-rw-r--r--test/Transforms/SimplifyLibCalls/osx-names.ll30
-rw-r--r--test/Transforms/Sink/basic.ll2
-rw-r--r--test/Transforms/Sink/dg.exp3
-rw-r--r--test/Transforms/Sink/lit.local.cfg1
-rw-r--r--test/Transforms/StripSymbols/dg.exp3
-rw-r--r--test/Transforms/StripSymbols/lit.local.cfg1
-rw-r--r--test/Transforms/TailCallElim/dg.exp3
-rw-r--r--test/Transforms/TailCallElim/dont_reorder_load.ll4
-rw-r--r--test/Transforms/TailCallElim/lit.local.cfg1
-rw-r--r--test/Transforms/TailCallElim/setjmp.ll2
-rw-r--r--test/Transforms/TailDup/X86/dg.exp5
-rw-r--r--test/Transforms/TailDup/X86/lit.local.cfg6
-rw-r--r--test/Transforms/TailDup/dg.exp3
-rw-r--r--test/Transforms/TailDup/lit.local.cfg5
335 files changed, 8613 insertions, 1879 deletions
diff --git a/test/Transforms/ADCE/dg.exp b/test/Transforms/ADCE/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/ADCE/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/ADCE/lit.local.cfg b/test/Transforms/ADCE/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/ADCE/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/ArgumentPromotion/dg.exp b/test/Transforms/ArgumentPromotion/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/ArgumentPromotion/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/ArgumentPromotion/lit.local.cfg b/test/Transforms/ArgumentPromotion/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/ArgumentPromotion/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/BBVectorize/cycle.ll b/test/Transforms/BBVectorize/cycle.ll
new file mode 100644
index 0000000..32a91ce
--- /dev/null
+++ b/test/Transforms/BBVectorize/cycle.ll
@@ -0,0 +1,112 @@
+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"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+
+; This test checks the non-trivial pairing-induced cycle avoidance. Without this cycle avoidance, the algorithm would otherwise
+; want to select the pairs:
+; %div77 = fdiv double %sub74, %mul76.v.r1 <-> %div125 = fdiv double %mul121, %mul76.v.r2 (div125 depends on mul117)
+; %add84 = fadd double %sub83, 2.000000e+00 <-> %add127 = fadd double %mul126, 1.000000e+00 (add127 depends on div77)
+; %mul95 = fmul double %sub45.v.r1, %sub36.v.r1 <-> %mul88 = fmul double %sub36.v.r1, %sub87 (mul88 depends on add84)
+; %mul117 = fmul double %sub39.v.r1, %sub116 <-> %mul97 = fmul double %mul96, %sub39.v.r1 (mul97 depends on mul95)
+; and so a dependency cycle would be created.
+
+declare double @fabs(double) nounwind readnone
+define void @test1(double %a, double %b, double %c, double %add80, double %mul1, double %mul2.v.r1, double %mul73, double %sub, double %sub65, double %F.0, i32 %n.0, double %Bnm3.0, double %Bnm2.0, double %Bnm1.0, double %Anm3.0, double %Anm2.0, double %Anm1.0) {
+entry:
+ br label %go
+go:
+ %conv = sitofp i32 %n.0 to double
+ %add35 = fadd double %conv, %a
+ %sub36 = fadd double %add35, -1.000000e+00
+ %add38 = fadd double %conv, %b
+ %sub39 = fadd double %add38, -1.000000e+00
+ %add41 = fadd double %conv, %c
+ %sub42 = fadd double %add41, -1.000000e+00
+ %sub45 = fadd double %add35, -2.000000e+00
+ %sub48 = fadd double %add38, -2.000000e+00
+ %sub51 = fadd double %add41, -2.000000e+00
+ %mul52 = shl nsw i32 %n.0, 1
+ %sub53 = add nsw i32 %mul52, -1
+ %conv54 = sitofp i32 %sub53 to double
+ %sub56 = add nsw i32 %mul52, -3
+ %conv57 = sitofp i32 %sub56 to double
+ %sub59 = add nsw i32 %mul52, -5
+ %conv60 = sitofp i32 %sub59 to double
+ %mul61 = mul nsw i32 %n.0, %n.0
+ %conv62 = sitofp i32 %mul61 to double
+ %mul63 = fmul double %conv62, 3.000000e+00
+ %mul67 = fmul double %sub65, %conv
+ %add68 = fadd double %mul63, %mul67
+ %add69 = fadd double %add68, 2.000000e+00
+ %sub71 = fsub double %add69, %mul2.v.r1
+ %sub74 = fsub double %sub71, %mul73
+ %mul75 = fmul double %conv57, 2.000000e+00
+ %mul76 = fmul double %mul75, %sub42
+ %div77 = fdiv double %sub74, %mul76
+ %mul82 = fmul double %add80, %conv
+ %sub83 = fsub double %mul63, %mul82
+ %add84 = fadd double %sub83, 2.000000e+00
+ %sub86 = fsub double %add84, %mul2.v.r1
+ %sub87 = fsub double -0.000000e+00, %sub86
+ %mul88 = fmul double %sub36, %sub87
+ %mul89 = fmul double %mul88, %sub39
+ %mul90 = fmul double %conv54, 4.000000e+00
+ %mul91 = fmul double %mul90, %conv57
+ %mul92 = fmul double %mul91, %sub51
+ %mul93 = fmul double %mul92, %sub42
+ %div94 = fdiv double %mul89, %mul93
+ %mul95 = fmul double %sub45, %sub36
+ %mul96 = fmul double %mul95, %sub48
+ %mul97 = fmul double %mul96, %sub39
+ %sub99 = fsub double %conv, %a
+ %sub100 = fadd double %sub99, -2.000000e+00
+ %mul101 = fmul double %mul97, %sub100
+ %sub103 = fsub double %conv, %b
+ %sub104 = fadd double %sub103, -2.000000e+00
+ %mul105 = fmul double %mul101, %sub104
+ %mul106 = fmul double %conv57, 8.000000e+00
+ %mul107 = fmul double %mul106, %conv57
+ %mul108 = fmul double %mul107, %conv60
+ %sub111 = fadd double %add41, -3.000000e+00
+ %mul112 = fmul double %mul108, %sub111
+ %mul113 = fmul double %mul112, %sub51
+ %mul114 = fmul double %mul113, %sub42
+ %div115 = fdiv double %mul105, %mul114
+ %sub116 = fsub double -0.000000e+00, %sub36
+ %mul117 = fmul double %sub39, %sub116
+ %sub119 = fsub double %conv, %c
+ %sub120 = fadd double %sub119, -1.000000e+00
+ %mul121 = fmul double %mul117, %sub120
+ %mul123 = fmul double %mul75, %sub51
+ %mul124 = fmul double %mul123, %sub42
+ %div125 = fdiv double %mul121, %mul124
+ %mul126 = fmul double %div77, %sub
+ %add127 = fadd double %mul126, 1.000000e+00
+ %mul128 = fmul double %add127, %Anm1.0
+ %mul129 = fmul double %div94, %sub
+ %add130 = fadd double %div125, %mul129
+ %mul131 = fmul double %add130, %sub
+ %mul132 = fmul double %mul131, %Anm2.0
+ %add133 = fadd double %mul128, %mul132
+ %mul134 = fmul double %div115, %mul1
+ %mul135 = fmul double %mul134, %Anm3.0
+ %add136 = fadd double %add133, %mul135
+ %mul139 = fmul double %add127, %Bnm1.0
+ %mul143 = fmul double %mul131, %Bnm2.0
+ %add144 = fadd double %mul139, %mul143
+ %mul146 = fmul double %mul134, %Bnm3.0
+ %add147 = fadd double %add144, %mul146
+ %div148 = fdiv double %add136, %add147
+ %sub149 = fsub double %F.0, %div148
+ %div150 = fdiv double %sub149, %F.0
+ %call = tail call double @fabs(double %div150) nounwind readnone
+ %cmp = fcmp olt double %call, 0x3CB0000000000000
+ %cmp152 = icmp sgt i32 %n.0, 20000
+ %or.cond = or i1 %cmp, %cmp152
+ br i1 %or.cond, label %done, label %go
+done:
+ ret void
+; CHECK: @test1
+; CHECK: go:
+; CHECK-NEXT: %conv.v.i0.1 = insertelement <2 x i32> undef, i32 %n.0, i32 0
+; FIXME: When tree pruning is deterministic, include the entire output.
+}
diff --git a/test/Transforms/BBVectorize/func-alias.ll b/test/Transforms/BBVectorize/func-alias.ll
new file mode 100644
index 0000000..9d0cc07
--- /dev/null
+++ b/test/Transforms/BBVectorize/func-alias.ll
@@ -0,0 +1,244 @@
+target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-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"
+; RUN: opt < %s -basicaa -bb-vectorize -bb-vectorize-req-chain-depth=2 -instcombine -gvn -S | FileCheck %s
+; The chain length is set to 2 so that this will do some vectorization; check that the order of the functions is unchanged.
+
+%struct.descriptor_dimension = type { i64, i64, i64 }
+%struct.__st_parameter_common = type { i32, i32, i8*, i32, i32, i8*, i32* }
+%struct.__st_parameter_dt = type { %struct.__st_parameter_common, i64, i64*, i64*, i8*, i8*, i32, i32, i8*, i8*, i32, i32, i8*, [256 x i8], i32*, i64, i8*, i32, i32, i8*, i8*, i32, i32, i8*, i8*, i32, i32, i8*, i8*, i32, [4 x i8] }
+%"struct.array4_real(kind=4)" = type { i8*, i64, i64, [4 x %struct.descriptor_dimension] }
+%"struct.array4_integer(kind=4).73" = type { i8*, i64, i64, [4 x %struct.descriptor_dimension] }
+%struct.array4_unknown = type { i8*, i64, i64, [4 x %struct.descriptor_dimension] }
+
+@.cst4 = external unnamed_addr constant [11 x i8], align 8
+@.cst823 = external unnamed_addr constant [214 x i8], align 64
+@j.4580 = external global i32
+@j1.4581 = external global i32
+@nty1.4590 = external global [2 x i8]
+@nty2.4591 = external global [2 x i8]
+@xr1.4592 = external global float
+@xr2.4593 = external global float
+@yr1.4594 = external global float
+@yr2.4595 = external global float
+
+@__main1_MOD_iave = external unnamed_addr global i32
+@__main1_MOD_igrp = external global i32
+@__main1_MOD_iounit = external global i32
+@__main1_MOD_ityp = external global i32
+@__main1_MOD_mclmsg = external unnamed_addr global %struct.array4_unknown, align 32
+@__main1_MOD_mxdate = external unnamed_addr global %"struct.array4_integer(kind=4).73", align 32
+@__main1_MOD_rmxval = external unnamed_addr global %"struct.array4_real(kind=4)", align 32
+
+declare void @_gfortran_st_write(%struct.__st_parameter_dt*)
+declare void @_gfortran_st_write_done(%struct.__st_parameter_dt*)
+declare void @_gfortran_transfer_character_write(%struct.__st_parameter_dt*, i8*, i32)
+declare void @_gfortran_transfer_integer_write(%struct.__st_parameter_dt*, i8*, i32)
+declare void @_gfortran_transfer_real_write(%struct.__st_parameter_dt*, i8*, i32)
+
+define i1 @"prtmax__<bb 3>_<bb 34>"(%struct.__st_parameter_dt* %memtmp3, i32 %D.4627_188.reload) nounwind {
+; CHECK: prtmax__
+newFuncRoot:
+ br label %"<bb 34>"
+
+codeRepl80.exitStub: ; preds = %"<bb 34>"
+ ret i1 true
+
+"<bb 34>.<bb 25>_crit_edge.exitStub": ; preds = %"<bb 34>"
+ ret i1 false
+
+"<bb 34>": ; preds = %newFuncRoot
+ %tmp128 = getelementptr inbounds %struct.__st_parameter_dt* %memtmp3, i32 0, i32 0
+ %tmp129 = getelementptr inbounds %struct.__st_parameter_common* %tmp128, i32 0, i32 2
+ store i8* getelementptr inbounds ([11 x i8]* @.cst4, i64 0, i64 0), i8** %tmp129, align 8
+ %tmp130 = getelementptr inbounds %struct.__st_parameter_dt* %memtmp3, i32 0, i32 0
+ %tmp131 = getelementptr inbounds %struct.__st_parameter_common* %tmp130, i32 0, i32 3
+ store i32 31495, i32* %tmp131, align 4
+ %tmp132 = getelementptr inbounds %struct.__st_parameter_dt* %memtmp3, i32 0, i32 5
+ store i8* getelementptr inbounds ([214 x i8]* @.cst823, i64 0, i64 0), i8** %tmp132, align 8
+ %tmp133 = getelementptr inbounds %struct.__st_parameter_dt* %memtmp3, i32 0, i32 6
+ store i32 214, i32* %tmp133, align 4
+ %tmp134 = getelementptr inbounds %struct.__st_parameter_dt* %memtmp3, i32 0, i32 0
+ %tmp135 = getelementptr inbounds %struct.__st_parameter_common* %tmp134, i32 0, i32 0
+ store i32 4096, i32* %tmp135, align 4
+ %iounit.8748_288 = load i32* @__main1_MOD_iounit, align 4
+ %tmp136 = getelementptr inbounds %struct.__st_parameter_dt* %memtmp3, i32 0, i32 0
+ %tmp137 = getelementptr inbounds %struct.__st_parameter_common* %tmp136, i32 0, i32 1
+ store i32 %iounit.8748_288, i32* %tmp137, align 4
+ call void @_gfortran_st_write(%struct.__st_parameter_dt* %memtmp3) nounwind
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_integer_write to void (%struct.__st_parameter_dt*, i32*, i32)*)(%struct.__st_parameter_dt* %memtmp3, i32* @j.4580, i32 4) nounwind
+; CHECK: @_gfortran_transfer_integer_write
+ %D.75807_289 = load i8** getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 0), align 8
+ %j.8758_290 = load i32* @j.4580, align 4
+ %D.75760_291 = sext i32 %j.8758_290 to i64
+ %iave.8736_292 = load i32* @__main1_MOD_iave, align 4
+ %D.75620_293 = sext i32 %iave.8736_292 to i64
+ %D.75808_294 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 3, i64 2, i32 0), align 8
+ %D.75809_295 = mul nsw i64 %D.75620_293, %D.75808_294
+ %igrp.8737_296 = load i32* @__main1_MOD_igrp, align 4
+ %D.75635_297 = sext i32 %igrp.8737_296 to i64
+ %D.75810_298 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 3, i64 1, i32 0), align 8
+ %D.75811_299 = mul nsw i64 %D.75635_297, %D.75810_298
+ %D.75812_300 = add nsw i64 %D.75809_295, %D.75811_299
+ %D.75813_301 = add nsw i64 %D.75760_291, %D.75812_300
+ %ityp.8750_302 = load i32* @__main1_MOD_ityp, align 4
+ %D.75704_303 = sext i32 %ityp.8750_302 to i64
+ %D.75814_304 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 3, i64 3, i32 0), align 8
+ %D.75815_305 = mul nsw i64 %D.75704_303, %D.75814_304
+ %D.75816_306 = add nsw i64 %D.75813_301, %D.75815_305
+ %D.75817_307 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 1), align 8
+ %D.75818_308 = add nsw i64 %D.75816_306, %D.75817_307
+ %tmp138 = bitcast i8* %D.75807_289 to [0 x float]*
+ %tmp139 = bitcast [0 x float]* %tmp138 to float*
+ %D.75819_309 = getelementptr inbounds float* %tmp139, i64 %D.75818_308
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32)*)(%struct.__st_parameter_dt* %memtmp3, float* %D.75819_309, i32 4) nounwind
+; CHECK: @_gfortran_transfer_real_write
+ %D.75820_310 = load i8** getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 0), align 8
+ %j.8758_311 = load i32* @j.4580, align 4
+ %D.75760_312 = sext i32 %j.8758_311 to i64
+ %iave.8736_313 = load i32* @__main1_MOD_iave, align 4
+ %D.75620_314 = sext i32 %iave.8736_313 to i64
+ %D.75821_315 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 3, i64 2, i32 0), align 8
+ %D.75822_316 = mul nsw i64 %D.75620_314, %D.75821_315
+ %igrp.8737_317 = load i32* @__main1_MOD_igrp, align 4
+ %D.75635_318 = sext i32 %igrp.8737_317 to i64
+ %D.75823_319 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 3, i64 1, i32 0), align 8
+ %D.75824_320 = mul nsw i64 %D.75635_318, %D.75823_319
+ %D.75825_321 = add nsw i64 %D.75822_316, %D.75824_320
+ %D.75826_322 = add nsw i64 %D.75760_312, %D.75825_321
+ %ityp.8750_323 = load i32* @__main1_MOD_ityp, align 4
+ %D.75704_324 = sext i32 %ityp.8750_323 to i64
+ %D.75827_325 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 3, i64 3, i32 0), align 8
+ %D.75828_326 = mul nsw i64 %D.75704_324, %D.75827_325
+ %D.75829_327 = add nsw i64 %D.75826_322, %D.75828_326
+ %D.75830_328 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 1), align 8
+ %D.75831_329 = add nsw i64 %D.75829_327, %D.75830_328
+ %tmp140 = bitcast i8* %D.75820_310 to [0 x [1 x i8]]*
+ %tmp141 = bitcast [0 x [1 x i8]]* %tmp140 to [1 x i8]*
+ %D.75832_330 = getelementptr inbounds [1 x i8]* %tmp141, i64 %D.75831_329
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_character_write to void (%struct.__st_parameter_dt*, [1 x i8]*, i32)*)(%struct.__st_parameter_dt* %memtmp3, [1 x i8]* %D.75832_330, i32 1) nounwind
+; CHECK: @_gfortran_transfer_character_write
+ %D.75833_331 = load i8** getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 0), align 8
+ %j.8758_332 = load i32* @j.4580, align 4
+ %D.75760_333 = sext i32 %j.8758_332 to i64
+ %iave.8736_334 = load i32* @__main1_MOD_iave, align 4
+ %D.75620_335 = sext i32 %iave.8736_334 to i64
+ %D.75834_336 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 3, i64 2, i32 0), align 8
+ %D.75835_337 = mul nsw i64 %D.75620_335, %D.75834_336
+ %igrp.8737_338 = load i32* @__main1_MOD_igrp, align 4
+ %D.75635_339 = sext i32 %igrp.8737_338 to i64
+ %D.75836_340 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 3, i64 1, i32 0), align 8
+ %D.75837_341 = mul nsw i64 %D.75635_339, %D.75836_340
+ %D.75838_342 = add nsw i64 %D.75835_337, %D.75837_341
+ %D.75839_343 = add nsw i64 %D.75760_333, %D.75838_342
+ %ityp.8750_344 = load i32* @__main1_MOD_ityp, align 4
+ %D.75704_345 = sext i32 %ityp.8750_344 to i64
+ %D.75840_346 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 3, i64 3, i32 0), align 8
+ %D.75841_347 = mul nsw i64 %D.75704_345, %D.75840_346
+ %D.75842_348 = add nsw i64 %D.75839_343, %D.75841_347
+ %D.75843_349 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 1), align 8
+ %D.75844_350 = add nsw i64 %D.75842_348, %D.75843_349
+ %tmp142 = bitcast i8* %D.75833_331 to [0 x i32]*
+ %tmp143 = bitcast [0 x i32]* %tmp142 to i32*
+ %D.75845_351 = getelementptr inbounds i32* %tmp143, i64 %D.75844_350
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_integer_write to void (%struct.__st_parameter_dt*, i32*, i32)*)(%struct.__st_parameter_dt* %memtmp3, i32* %D.75845_351, i32 4) nounwind
+; CHECK: @_gfortran_transfer_integer_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32)*)(%struct.__st_parameter_dt* %memtmp3, float* @xr1.4592, i32 4) nounwind
+; CHECK: @_gfortran_transfer_real_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32)*)(%struct.__st_parameter_dt* %memtmp3, float* @yr1.4594, i32 4) nounwind
+; CHECK: @_gfortran_transfer_real_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_character_write to void (%struct.__st_parameter_dt*, [2 x i8]*, i32)*)(%struct.__st_parameter_dt* %memtmp3, [2 x i8]* @nty1.4590, i32 2) nounwind
+; CHECK: @_gfortran_transfer_character_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_integer_write to void (%struct.__st_parameter_dt*, i32*, i32)*)(%struct.__st_parameter_dt* %memtmp3, i32* @j1.4581, i32 4) nounwind
+; CHECK: @_gfortran_transfer_integer_write
+ %D.75807_352 = load i8** getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 0), align 8
+ %j1.8760_353 = load i32* @j1.4581, align 4
+ %D.75773_354 = sext i32 %j1.8760_353 to i64
+ %iave.8736_355 = load i32* @__main1_MOD_iave, align 4
+ %D.75620_356 = sext i32 %iave.8736_355 to i64
+ %D.75808_357 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 3, i64 2, i32 0), align 8
+ %D.75809_358 = mul nsw i64 %D.75620_356, %D.75808_357
+ %igrp.8737_359 = load i32* @__main1_MOD_igrp, align 4
+ %D.75635_360 = sext i32 %igrp.8737_359 to i64
+ %D.75810_361 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 3, i64 1, i32 0), align 8
+ %D.75811_362 = mul nsw i64 %D.75635_360, %D.75810_361
+ %D.75812_363 = add nsw i64 %D.75809_358, %D.75811_362
+ %D.75846_364 = add nsw i64 %D.75773_354, %D.75812_363
+ %ityp.8750_365 = load i32* @__main1_MOD_ityp, align 4
+ %D.75704_366 = sext i32 %ityp.8750_365 to i64
+ %D.75814_367 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 3, i64 3, i32 0), align 8
+ %D.75815_368 = mul nsw i64 %D.75704_366, %D.75814_367
+ %D.75847_369 = add nsw i64 %D.75846_364, %D.75815_368
+ %D.75817_370 = load i64* getelementptr inbounds (%"struct.array4_real(kind=4)"* @__main1_MOD_rmxval, i64 0, i32 1), align 8
+ %D.75848_371 = add nsw i64 %D.75847_369, %D.75817_370
+ %tmp144 = bitcast i8* %D.75807_352 to [0 x float]*
+ %tmp145 = bitcast [0 x float]* %tmp144 to float*
+ %D.75849_372 = getelementptr inbounds float* %tmp145, i64 %D.75848_371
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32)*)(%struct.__st_parameter_dt* %memtmp3, float* %D.75849_372, i32 4) nounwind
+; CHECK: @_gfortran_transfer_real_write
+ %D.75820_373 = load i8** getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 0), align 8
+ %j1.8760_374 = load i32* @j1.4581, align 4
+ %D.75773_375 = sext i32 %j1.8760_374 to i64
+ %iave.8736_376 = load i32* @__main1_MOD_iave, align 4
+ %D.75620_377 = sext i32 %iave.8736_376 to i64
+ %D.75821_378 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 3, i64 2, i32 0), align 8
+ %D.75822_379 = mul nsw i64 %D.75620_377, %D.75821_378
+ %igrp.8737_380 = load i32* @__main1_MOD_igrp, align 4
+ %D.75635_381 = sext i32 %igrp.8737_380 to i64
+ %D.75823_382 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 3, i64 1, i32 0), align 8
+ %D.75824_383 = mul nsw i64 %D.75635_381, %D.75823_382
+ %D.75825_384 = add nsw i64 %D.75822_379, %D.75824_383
+ %D.75850_385 = add nsw i64 %D.75773_375, %D.75825_384
+ %ityp.8750_386 = load i32* @__main1_MOD_ityp, align 4
+ %D.75704_387 = sext i32 %ityp.8750_386 to i64
+ %D.75827_388 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 3, i64 3, i32 0), align 8
+ %D.75828_389 = mul nsw i64 %D.75704_387, %D.75827_388
+ %D.75851_390 = add nsw i64 %D.75850_385, %D.75828_389
+ %D.75830_391 = load i64* getelementptr inbounds (%struct.array4_unknown* @__main1_MOD_mclmsg, i64 0, i32 1), align 8
+ %D.75852_392 = add nsw i64 %D.75851_390, %D.75830_391
+ %tmp146 = bitcast i8* %D.75820_373 to [0 x [1 x i8]]*
+ %tmp147 = bitcast [0 x [1 x i8]]* %tmp146 to [1 x i8]*
+ %D.75853_393 = getelementptr inbounds [1 x i8]* %tmp147, i64 %D.75852_392
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_character_write to void (%struct.__st_parameter_dt*, [1 x i8]*, i32)*)(%struct.__st_parameter_dt* %memtmp3, [1 x i8]* %D.75853_393, i32 1) nounwind
+; CHECK: @_gfortran_transfer_character_write
+ %D.75833_394 = load i8** getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 0), align 8
+ %j1.8760_395 = load i32* @j1.4581, align 4
+ %D.75773_396 = sext i32 %j1.8760_395 to i64
+ %iave.8736_397 = load i32* @__main1_MOD_iave, align 4
+ %D.75620_398 = sext i32 %iave.8736_397 to i64
+ %D.75834_399 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 3, i64 2, i32 0), align 8
+ %D.75835_400 = mul nsw i64 %D.75620_398, %D.75834_399
+ %igrp.8737_401 = load i32* @__main1_MOD_igrp, align 4
+ %D.75635_402 = sext i32 %igrp.8737_401 to i64
+ %D.75836_403 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 3, i64 1, i32 0), align 8
+ %D.75837_404 = mul nsw i64 %D.75635_402, %D.75836_403
+ %D.75838_405 = add nsw i64 %D.75835_400, %D.75837_404
+ %D.75854_406 = add nsw i64 %D.75773_396, %D.75838_405
+ %ityp.8750_407 = load i32* @__main1_MOD_ityp, align 4
+ %D.75704_408 = sext i32 %ityp.8750_407 to i64
+ %D.75840_409 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 3, i64 3, i32 0), align 8
+ %D.75841_410 = mul nsw i64 %D.75704_408, %D.75840_409
+ %D.75855_411 = add nsw i64 %D.75854_406, %D.75841_410
+ %D.75843_412 = load i64* getelementptr inbounds (%"struct.array4_integer(kind=4).73"* @__main1_MOD_mxdate, i64 0, i32 1), align 8
+ %D.75856_413 = add nsw i64 %D.75855_411, %D.75843_412
+ %tmp148 = bitcast i8* %D.75833_394 to [0 x i32]*
+ %tmp149 = bitcast [0 x i32]* %tmp148 to i32*
+ %D.75857_414 = getelementptr inbounds i32* %tmp149, i64 %D.75856_413
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_integer_write to void (%struct.__st_parameter_dt*, i32*, i32)*)(%struct.__st_parameter_dt* %memtmp3, i32* %D.75857_414, i32 4) nounwind
+; CHECK: @_gfortran_transfer_integer_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32)*)(%struct.__st_parameter_dt* %memtmp3, float* @xr2.4593, i32 4) nounwind
+; CHECK: @_gfortran_transfer_real_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32)*)(%struct.__st_parameter_dt* %memtmp3, float* @yr2.4595, i32 4) nounwind
+; CHECK: @_gfortran_transfer_real_write
+ call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_character_write to void (%struct.__st_parameter_dt*, [2 x i8]*, i32)*)(%struct.__st_parameter_dt* %memtmp3, [2 x i8]* @nty2.4591, i32 2) nounwind
+; CHECK: @_gfortran_transfer_character_write
+ call void @_gfortran_st_write_done(%struct.__st_parameter_dt* %memtmp3) nounwind
+; CHECK: @_gfortran_st_write_done
+ %j.8758_415 = load i32* @j.4580, align 4
+ %D.4634_416 = icmp eq i32 %j.8758_415, %D.4627_188.reload
+ %j.8758_417 = load i32* @j.4580, align 4
+ %j.8770_418 = add nsw i32 %j.8758_417, 1
+ store i32 %j.8770_418, i32* @j.4580, align 4
+ %tmp150 = icmp ne i1 %D.4634_416, false
+ br i1 %tmp150, label %codeRepl80.exitStub, label %"<bb 34>.<bb 25>_crit_edge.exitStub"
+}
+
diff --git a/test/Transforms/BBVectorize/ld1.ll b/test/Transforms/BBVectorize/ld1.ll
new file mode 100644
index 0000000..cea225d
--- /dev/null
+++ b/test/Transforms/BBVectorize/ld1.ll
@@ -0,0 +1,41 @@
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+
+define double @test1(double* %a, double* %b, double* %c) nounwind uwtable readonly {
+entry:
+ %i0 = load double* %a, align 8
+ %i1 = load double* %b, align 8
+ %mul = fmul double %i0, %i1
+ %i2 = load double* %c, align 8
+ %add = fadd double %mul, %i2
+ %arrayidx3 = getelementptr inbounds double* %a, i64 1
+ %i3 = load double* %arrayidx3, align 8
+ %arrayidx4 = getelementptr inbounds double* %b, i64 1
+ %i4 = load double* %arrayidx4, align 8
+ %mul5 = fmul double %i3, %i4
+ %arrayidx6 = getelementptr inbounds double* %c, i64 1
+ %i5 = load double* %arrayidx6, align 8
+ %add7 = fadd double %mul5, %i5
+ %mul9 = fmul double %add, %i1
+ %add11 = fadd double %mul9, %i2
+ %mul13 = fmul double %add7, %i4
+ %add15 = fadd double %mul13, %i5
+ %mul16 = fmul double %add11, %add15
+ ret double %mul16
+; CHECK: @test1
+; CHECK: %i0.v.i0 = bitcast double* %a to <2 x double>*
+; CHECK: %i1.v.i0 = bitcast double* %b to <2 x double>*
+; CHECK: %i2.v.i0 = bitcast double* %c to <2 x double>*
+; CHECK: %i0 = load <2 x double>* %i0.v.i0, align 8
+; CHECK: %i1 = load <2 x double>* %i1.v.i0, align 8
+; CHECK: %mul = fmul <2 x double> %i0, %i1
+; CHECK: %i2 = load <2 x double>* %i2.v.i0, align 8
+; CHECK: %add = fadd <2 x double> %mul, %i2
+; CHECK: %mul9 = fmul <2 x double> %add, %i1
+; CHECK: %add11 = fadd <2 x double> %mul9, %i2
+; CHECK: %add11.v.r1 = extractelement <2 x double> %add11, i32 0
+; CHECK: %add11.v.r2 = extractelement <2 x double> %add11, i32 1
+; CHECK: %mul16 = fmul double %add11.v.r1, %add11.v.r2
+; CHECK: ret double %mul16
+}
+
diff --git a/test/Transforms/BBVectorize/lit.local.cfg b/test/Transforms/BBVectorize/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/BBVectorize/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/BBVectorize/loop1.ll b/test/Transforms/BBVectorize/loop1.ll
new file mode 100644
index 0000000..bebc91a
--- /dev/null
+++ b/test/Transforms/BBVectorize/loop1.ll
@@ -0,0 +1,93 @@
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+; RUN: opt < %s -basicaa -loop-unroll -unroll-threshold=45 -unroll-allow-partial -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s -check-prefix=CHECK-UNRL
+; The second check covers the use of alias analysis (with loop unrolling).
+
+define void @test1(double* noalias %out, double* noalias %in1, double* noalias %in2) nounwind uwtable {
+entry:
+ br label %for.body
+; CHECK: @test1
+; CHECK-UNRL: @test1
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds double* %in1, i64 %indvars.iv
+ %0 = load double* %arrayidx, align 8
+ %arrayidx2 = getelementptr inbounds double* %in2, i64 %indvars.iv
+ %1 = load double* %arrayidx2, align 8
+ %mul = fmul double %0, %0
+ %mul3 = fmul double %0, %1
+ %add = fadd double %mul, %mul3
+ %add4 = fadd double %1, %1
+ %add5 = fadd double %add4, %0
+ %mul6 = fmul double %0, %add5
+ %add7 = fadd double %add, %mul6
+ %mul8 = fmul double %1, %1
+ %add9 = fadd double %0, %0
+ %add10 = fadd double %add9, %0
+ %mul11 = fmul double %mul8, %add10
+ %add12 = fadd double %add7, %mul11
+ %arrayidx14 = getelementptr inbounds double* %out, i64 %indvars.iv
+ store double %add12, double* %arrayidx14, align 8
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, 10
+ br i1 %exitcond, label %for.end, label %for.body
+; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+; CHECK: %arrayidx = getelementptr inbounds double* %in1, i64 %indvars.iv
+; CHECK: %0 = load double* %arrayidx, align 8
+; CHECK: %arrayidx2 = getelementptr inbounds double* %in2, i64 %indvars.iv
+; CHECK: %1 = load double* %arrayidx2, align 8
+; CHECK: %mul = fmul double %0, %0
+; CHECK: %mul3 = fmul double %0, %1
+; CHECK: %add = fadd double %mul, %mul3
+; CHECK: %add4.v.i1.1 = insertelement <2 x double> undef, double %1, i32 0
+; CHECK: %mul8 = fmul double %1, %1
+; CHECK: %add4.v.i1.2 = insertelement <2 x double> %add4.v.i1.1, double %0, i32 1
+; CHECK: %add4 = fadd <2 x double> %add4.v.i1.2, %add4.v.i1.2
+; CHECK: %add5.v.i1.1 = insertelement <2 x double> undef, double %0, i32 0
+; CHECK: %add5.v.i1.2 = insertelement <2 x double> %add5.v.i1.1, double %0, i32 1
+; CHECK: %add5 = fadd <2 x double> %add4, %add5.v.i1.2
+; CHECK: %mul6.v.i0.2 = insertelement <2 x double> %add5.v.i1.1, double %mul8, i32 1
+; CHECK: %mul6 = fmul <2 x double> %mul6.v.i0.2, %add5
+; CHECK: %mul6.v.r1 = extractelement <2 x double> %mul6, i32 0
+; CHECK: %mul6.v.r2 = extractelement <2 x double> %mul6, i32 1
+; CHECK: %add7 = fadd double %add, %mul6.v.r1
+; CHECK: %add12 = fadd double %add7, %mul6.v.r2
+; CHECK: %arrayidx14 = getelementptr inbounds double* %out, i64 %indvars.iv
+; CHECK: store double %add12, double* %arrayidx14, align 8
+; CHECK: %indvars.iv.next = add i64 %indvars.iv, 1
+; CHECK: %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+; CHECK: %exitcond = icmp eq i32 %lftr.wideiv, 10
+; CHECK: br i1 %exitcond, label %for.end, label %for.body
+; CHECK-UNRL: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next.1, %for.body ]
+; CHECK-UNRL: %arrayidx = getelementptr inbounds double* %in1, i64 %indvars.iv
+; CHECK-UNRL: %0 = bitcast double* %arrayidx to <2 x double>*
+; CHECK-UNRL: %arrayidx2 = getelementptr inbounds double* %in2, i64 %indvars.iv
+; CHECK-UNRL: %1 = bitcast double* %arrayidx2 to <2 x double>*
+; CHECK-UNRL: %arrayidx14 = getelementptr inbounds double* %out, i64 %indvars.iv
+; CHECK-UNRL: %2 = load <2 x double>* %0, align 8
+; CHECK-UNRL: %3 = load <2 x double>* %1, align 8
+; CHECK-UNRL: %mul = fmul <2 x double> %2, %2
+; CHECK-UNRL: %mul3 = fmul <2 x double> %2, %3
+; CHECK-UNRL: %add = fadd <2 x double> %mul, %mul3
+; CHECK-UNRL: %add4 = fadd <2 x double> %3, %3
+; CHECK-UNRL: %add5 = fadd <2 x double> %add4, %2
+; CHECK-UNRL: %mul6 = fmul <2 x double> %2, %add5
+; CHECK-UNRL: %add7 = fadd <2 x double> %add, %mul6
+; CHECK-UNRL: %mul8 = fmul <2 x double> %3, %3
+; CHECK-UNRL: %add9 = fadd <2 x double> %2, %2
+; CHECK-UNRL: %add10 = fadd <2 x double> %add9, %2
+; CHECK-UNRL: %mul11 = fmul <2 x double> %mul8, %add10
+; CHECK-UNRL: %add12 = fadd <2 x double> %add7, %mul11
+; CHECK-UNRL: %4 = bitcast double* %arrayidx14 to <2 x double>*
+; CHECK-UNRL: store <2 x double> %add12, <2 x double>* %4, align 8
+; CHECK-UNRL: %indvars.iv.next.1 = add i64 %indvars.iv, 2
+; CHECK-UNRL: %lftr.wideiv.1 = trunc i64 %indvars.iv.next.1 to i32
+; CHECK-UNRL: %exitcond.1 = icmp eq i32 %lftr.wideiv.1, 10
+; CHECK-UNRL: br i1 %exitcond.1, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
diff --git a/test/Transforms/BBVectorize/mem-op-depth.ll b/test/Transforms/BBVectorize/mem-op-depth.ll
new file mode 100644
index 0000000..84f16bd
--- /dev/null
+++ b/test/Transforms/BBVectorize/mem-op-depth.ll
@@ -0,0 +1,22 @@
+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"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=6 -instcombine -gvn -S | FileCheck %s
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define i32 @test1() nounwind {
+; CHECK: @test1
+ %V1 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+ %V2 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 1), align 4
+ %V3= load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 2), align 8
+ %V4 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 3), align 4
+; CHECK: %V1 = load <4 x float>* bitcast ([1024 x float]* @A to <4 x float>*), align 16
+ store float %V1, float* getelementptr inbounds ([1024 x float]* @B, i64 0, i64 0), align 16
+ store float %V2, float* getelementptr inbounds ([1024 x float]* @B, i64 0, i64 1), align 4
+ store float %V3, float* getelementptr inbounds ([1024 x float]* @B, i64 0, i64 2), align 8
+ store float %V4, float* getelementptr inbounds ([1024 x float]* @B, i64 0, i64 3), align 4
+; CHECK-NEXT: store <4 x float> %V1, <4 x float>* bitcast ([1024 x float]* @B to <4 x float>*), align 16
+ ret i32 0
+; CHECK-NEXT: ret i32 0
+}
diff --git a/test/Transforms/BBVectorize/req-depth.ll b/test/Transforms/BBVectorize/req-depth.ll
new file mode 100644
index 0000000..8c9cc3c
--- /dev/null
+++ b/test/Transforms/BBVectorize/req-depth.ll
@@ -0,0 +1,17 @@
+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"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth 3 -S | FileCheck %s -check-prefix=CHECK-RD3
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth 2 -S | FileCheck %s -check-prefix=CHECK-RD2
+
+define double @test1(double %A1, double %A2, double %B1, double %B2) {
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+ %Y1 = fmul double %X1, %A1
+ %Y2 = fmul double %X2, %A2
+ %R = fmul double %Y1, %Y2
+ ret double %R
+; CHECK-RD3: @test1
+; CHECK-RD2: @test1
+; CHECK-RD3-NOT: <2 x double>
+; CHECK-RD2: <2 x double>
+}
+
diff --git a/test/Transforms/BBVectorize/search-limit.ll b/test/Transforms/BBVectorize/search-limit.ll
new file mode 100644
index 0000000..d9945b5
--- /dev/null
+++ b/test/Transforms/BBVectorize/search-limit.ll
@@ -0,0 +1,46 @@
+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"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -bb-vectorize-search-limit=4 -instcombine -gvn -S | FileCheck %s -check-prefix=CHECK-SL4
+
+define double @test1(double %A1, double %A2, double %B1, double %B2) {
+; CHECK: @test1
+; CHECK-SL4: @test1
+; CHECK-SL4-NOT: <2 x double>
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+ %Y1 = fmul double %X1, %A1
+ %Y2 = fmul double %X2, %A2
+; CHECK: %Y1 = fmul <2 x double> %X1, %X1.v.i0.2
+ %Z1 = fadd double %Y1, %B1
+ ; Here we have a dependency chain: the short search limit will not
+ ; see past this chain and so will not see the second part of the
+ ; pair to vectorize.
+ %mul41 = fmul double %Z1, %Y2
+ %sub48 = fsub double %Z1, %mul41
+ %mul62 = fmul double %Z1, %sub48
+ %sub69 = fsub double %Z1, %mul62
+ %mul83 = fmul double %Z1, %sub69
+ %sub90 = fsub double %Z1, %mul83
+ %mul104 = fmul double %Z1, %sub90
+ %sub111 = fsub double %Z1, %mul104
+ %mul125 = fmul double %Z1, %sub111
+ %sub132 = fsub double %Z1, %mul125
+ %mul146 = fmul double %Z1, %sub132
+ %sub153 = fsub double %Z1, %mul146
+ ; end of chain.
+ %Z2 = fadd double %Y2, %B2
+; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
+ %R1 = fdiv double %Z1, %Z2
+ %R = fmul double %R1, %sub153
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R1 = fdiv double %Z1.v.r1, %Z1.v.r2
+ ret double %R
+; CHECK: ret double %R
+}
+
diff --git a/test/Transforms/BBVectorize/simple-int.ll b/test/Transforms/BBVectorize/simple-int.ll
new file mode 100644
index 0000000..6844977
--- /dev/null
+++ b/test/Transforms/BBVectorize/simple-int.ll
@@ -0,0 +1,103 @@
+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"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+
+declare double @llvm.fma.f64(double, double, double)
+declare double @llvm.cos.f64(double)
+declare double @llvm.powi.f64(double, i32)
+
+; Basic depth-3 chain with fma
+define double @test1(double %A1, double %A2, double %B1, double %B2, double %C1, double %C2) {
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+ %Y1 = call double @llvm.fma.f64(double %X1, double %A1, double %C1)
+ %Y2 = call double @llvm.fma.f64(double %X2, double %A2, double %C2)
+ %Z1 = fadd double %Y1, %B1
+ %Z2 = fadd double %Y2, %B2
+ %R = fmul double %Z1, %Z2
+ ret double %R
+; CHECK: @test1
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+; CHECK: %Y1.v.i2.1 = insertelement <2 x double> undef, double %C1, i32 0
+; CHECK: %Y1.v.i2.2 = insertelement <2 x double> %Y1.v.i2.1, double %C2, i32 1
+; CHECK: %Y1 = call <2 x double> @llvm.fma.v2f64(<2 x double> %X1, <2 x double> %X1.v.i0.2, <2 x double> %Y1.v.i2.2)
+; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain with cos
+define double @test2(double %A1, double %A2, double %B1, double %B2) {
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+ %Y1 = call double @llvm.cos.f64(double %X1)
+ %Y2 = call double @llvm.cos.f64(double %X2)
+ %Z1 = fadd double %Y1, %B1
+ %Z2 = fadd double %Y2, %B2
+ %R = fmul double %Z1, %Z2
+ ret double %R
+; CHECK: @test2
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+; CHECK: %Y1 = call <2 x double> @llvm.cos.v2f64(<2 x double> %X1)
+; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain with powi
+define double @test3(double %A1, double %A2, double %B1, double %B2, i32 %P) {
+
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+ %Y1 = call double @llvm.powi.f64(double %X1, i32 %P)
+ %Y2 = call double @llvm.powi.f64(double %X2, i32 %P)
+ %Z1 = fadd double %Y1, %B1
+ %Z2 = fadd double %Y2, %B2
+ %R = fmul double %Z1, %Z2
+ ret double %R
+; CHECK: @test3
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+; CHECK: %Y1 = call <2 x double> @llvm.powi.v2f64(<2 x double> %X1, i32 %P)
+; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain with powi (different powers: should not vectorize)
+define double @test4(double %A1, double %A2, double %B1, double %B2, i32 %P) {
+
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+ %P2 = add i32 %P, 1
+ %Y1 = call double @llvm.powi.f64(double %X1, i32 %P)
+ %Y2 = call double @llvm.powi.f64(double %X2, i32 %P2)
+ %Z1 = fadd double %Y1, %B1
+ %Z2 = fadd double %Y2, %B2
+ %R = fmul double %Z1, %Z2
+ ret double %R
+; CHECK: @test4
+; CHECK-NOT: <2 x double>
+; CHECK: ret double %R
+}
+
+; CHECK: declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone
+; CHECK: declare <2 x double> @llvm.cos.v2f64(<2 x double>) nounwind readonly
+; CHECK: declare <2 x double> @llvm.powi.v2f64(<2 x double>, i32) nounwind readonly
+
diff --git a/test/Transforms/BBVectorize/simple-ldstr.ll b/test/Transforms/BBVectorize/simple-ldstr.ll
new file mode 100644
index 0000000..a5397ee
--- /dev/null
+++ b/test/Transforms/BBVectorize/simple-ldstr.ll
@@ -0,0 +1,110 @@
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -bb-vectorize-aligned-only -instcombine -gvn -S | FileCheck %s -check-prefix=CHECK-AO
+
+; Simple 3-pair chain with loads and stores
+define void @test1(double* %a, double* %b, double* %c) nounwind uwtable readonly {
+entry:
+ %i0 = load double* %a, align 8
+ %i1 = load double* %b, align 8
+ %mul = fmul double %i0, %i1
+ %arrayidx3 = getelementptr inbounds double* %a, i64 1
+ %i3 = load double* %arrayidx3, align 8
+ %arrayidx4 = getelementptr inbounds double* %b, i64 1
+ %i4 = load double* %arrayidx4, align 8
+ %mul5 = fmul double %i3, %i4
+ store double %mul, double* %c, align 8
+ %arrayidx5 = getelementptr inbounds double* %c, i64 1
+ store double %mul5, double* %arrayidx5, align 8
+ ret void
+; CHECK: @test1
+; CHECK: %i0.v.i0 = bitcast double* %a to <2 x double>*
+; CHECK: %i1.v.i0 = bitcast double* %b to <2 x double>*
+; CHECK: %i0 = load <2 x double>* %i0.v.i0, align 8
+; CHECK: %i1 = load <2 x double>* %i1.v.i0, align 8
+; CHECK: %mul = fmul <2 x double> %i0, %i1
+; CHECK: %0 = bitcast double* %c to <2 x double>*
+; CHECK: store <2 x double> %mul, <2 x double>* %0, align 8
+; CHECK: ret void
+; CHECK-AO: @test1
+; CHECK-AO-NOT: <2 x double>
+}
+
+; Simple chain with extending loads and stores
+define void @test2(float* %a, float* %b, double* %c) nounwind uwtable readonly {
+entry:
+ %i0f = load float* %a, align 4
+ %i0 = fpext float %i0f to double
+ %i1f = load float* %b, align 4
+ %i1 = fpext float %i1f to double
+ %mul = fmul double %i0, %i1
+ %arrayidx3 = getelementptr inbounds float* %a, i64 1
+ %i3f = load float* %arrayidx3, align 4
+ %i3 = fpext float %i3f to double
+ %arrayidx4 = getelementptr inbounds float* %b, i64 1
+ %i4f = load float* %arrayidx4, align 4
+ %i4 = fpext float %i4f to double
+ %mul5 = fmul double %i3, %i4
+ store double %mul, double* %c, align 8
+ %arrayidx5 = getelementptr inbounds double* %c, i64 1
+ store double %mul5, double* %arrayidx5, align 8
+ ret void
+; CHECK: @test2
+; CHECK: %i0f.v.i0 = bitcast float* %a to <2 x float>*
+; CHECK: %i1f.v.i0 = bitcast float* %b to <2 x float>*
+; CHECK: %i0f = load <2 x float>* %i0f.v.i0, align 4
+; CHECK: %i0 = fpext <2 x float> %i0f to <2 x double>
+; CHECK: %i1f = load <2 x float>* %i1f.v.i0, align 4
+; CHECK: %i1 = fpext <2 x float> %i1f to <2 x double>
+; CHECK: %mul = fmul <2 x double> %i0, %i1
+; CHECK: %0 = bitcast double* %c to <2 x double>*
+; CHECK: store <2 x double> %mul, <2 x double>* %0, align 8
+; CHECK: ret void
+; CHECK-AO: @test2
+; CHECK-AO-NOT: <2 x double>
+}
+
+; Simple chain with loads and truncating stores
+define void @test3(double* %a, double* %b, float* %c) nounwind uwtable readonly {
+entry:
+ %i0 = load double* %a, align 8
+ %i1 = load double* %b, align 8
+ %mul = fmul double %i0, %i1
+ %mulf = fptrunc double %mul to float
+ %arrayidx3 = getelementptr inbounds double* %a, i64 1
+ %i3 = load double* %arrayidx3, align 8
+ %arrayidx4 = getelementptr inbounds double* %b, i64 1
+ %i4 = load double* %arrayidx4, align 8
+ %mul5 = fmul double %i3, %i4
+ %mul5f = fptrunc double %mul5 to float
+ store float %mulf, float* %c, align 8
+ %arrayidx5 = getelementptr inbounds float* %c, i64 1
+ store float %mul5f, float* %arrayidx5, align 4
+ ret void
+; CHECK: @test3
+; CHECK: %i0.v.i0 = bitcast double* %a to <2 x double>*
+; CHECK: %i1.v.i0 = bitcast double* %b to <2 x double>*
+; CHECK: %i0 = load <2 x double>* %i0.v.i0, align 8
+; CHECK: %i1 = load <2 x double>* %i1.v.i0, align 8
+; CHECK: %mul = fmul <2 x double> %i0, %i1
+; CHECK: %mulf = fptrunc <2 x double> %mul to <2 x float>
+; CHECK: %0 = bitcast float* %c to <2 x float>*
+; CHECK: store <2 x float> %mulf, <2 x float>* %0, align 8
+; CHECK: ret void
+; CHECK-AO: @test3
+; CHECK-AO: %i0 = load double* %a, align 8
+; CHECK-AO: %i1 = load double* %b, align 8
+; CHECK-AO: %mul.v.i1.1 = insertelement <2 x double> undef, double %i1, i32 0
+; CHECK-AO: %mul.v.i0.1 = insertelement <2 x double> undef, double %i0, i32 0
+; CHECK-AO: %arrayidx3 = getelementptr inbounds double* %a, i64 1
+; CHECK-AO: %i3 = load double* %arrayidx3, align 8
+; CHECK-AO: %arrayidx4 = getelementptr inbounds double* %b, i64 1
+; CHECK-AO: %i4 = load double* %arrayidx4, align 8
+; CHECK-AO: %mul.v.i1.2 = insertelement <2 x double> %mul.v.i1.1, double %i4, i32 1
+; CHECK-AO: %mul.v.i0.2 = insertelement <2 x double> %mul.v.i0.1, double %i3, i32 1
+; CHECK-AO: %mul = fmul <2 x double> %mul.v.i0.2, %mul.v.i1.2
+; CHECK-AO: %mulf = fptrunc <2 x double> %mul to <2 x float>
+; CHECK-AO: %0 = bitcast float* %c to <2 x float>*
+; CHECK-AO: store <2 x float> %mulf, <2 x float>* %0, align 8
+; CHECK-AO: ret void
+}
diff --git a/test/Transforms/BBVectorize/simple.ll b/test/Transforms/BBVectorize/simple.ll
new file mode 100644
index 0000000..904d766
--- /dev/null
+++ b/test/Transforms/BBVectorize/simple.ll
@@ -0,0 +1,152 @@
+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"
+; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -instcombine -gvn -S | FileCheck %s
+
+; Basic depth-3 chain
+define double @test1(double %A1, double %A2, double %B1, double %B2) {
+; CHECK: @test1
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+ %Y1 = fmul double %X1, %A1
+ %Y2 = fmul double %X2, %A2
+; CHECK: %Y1 = fmul <2 x double> %X1, %X1.v.i0.2
+ %Z1 = fadd double %Y1, %B1
+ %Z2 = fadd double %Y2, %B2
+; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
+ %R = fmul double %Z1, %Z2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+ ret double %R
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain (last pair permuted)
+define double @test2(double %A1, double %A2, double %B1, double %B2) {
+; CHECK: @test2
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+ %Y1 = fmul double %X1, %A1
+ %Y2 = fmul double %X2, %A2
+; CHECK: %Y1 = fmul <2 x double> %X1, %X1.v.i0.2
+ %Z1 = fadd double %Y2, %B1
+ %Z2 = fadd double %Y1, %B2
+; CHECK: %Z1.v.i0 = shufflevector <2 x double> %Y1, <2 x double> undef, <2 x i32> <i32 1, i32 0>
+; CHECK: %Z1 = fadd <2 x double> %Z1.v.i0, %X1.v.i1.2
+ %R = fmul double %Z1, %Z2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+ ret double %R
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain (last pair first splat)
+define double @test3(double %A1, double %A2, double %B1, double %B2) {
+; CHECK: @test3
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+ %Y1 = fmul double %X1, %A1
+ %Y2 = fmul double %X2, %A2
+; CHECK: %Y1 = fmul <2 x double> %X1, %X1.v.i0.2
+ %Z1 = fadd double %Y2, %B1
+ %Z2 = fadd double %Y2, %B2
+; CHECK: %Z1.v.i0 = shufflevector <2 x double> %Y1, <2 x double> undef, <2 x i32> <i32 1, i32 1>
+; CHECK: %Z1 = fadd <2 x double> %Z1.v.i0, %X1.v.i1.2
+ %R = fmul double %Z1, %Z2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+ ret double %R
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain (last pair second splat)
+define double @test4(double %A1, double %A2, double %B1, double %B2) {
+; CHECK: @test4
+; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
+; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
+; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
+; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
+ %X1 = fsub double %A1, %B1
+ %X2 = fsub double %A2, %B2
+; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
+ %Y1 = fmul double %X1, %A1
+ %Y2 = fmul double %X2, %A2
+; CHECK: %Y1 = fmul <2 x double> %X1, %X1.v.i0.2
+ %Z1 = fadd double %Y1, %B1
+ %Z2 = fadd double %Y1, %B2
+; CHECK: %Z1.v.i0 = shufflevector <2 x double> %Y1, <2 x double> undef, <2 x i32> zeroinitializer
+; CHECK: %Z1 = fadd <2 x double> %Z1.v.i0, %X1.v.i1.2
+ %R = fmul double %Z1, %Z2
+; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
+; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
+; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
+ ret double %R
+; CHECK: ret double %R
+}
+
+; Basic depth-3 chain
+define <2 x float> @test5(<2 x float> %A1, <2 x float> %A2, <2 x float> %B1, <2 x float> %B2) {
+; CHECK: @test5
+; CHECK: %X1.v.i1 = shufflevector <2 x float> %B1, <2 x float> %B2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+; CHECK: %X1.v.i0 = shufflevector <2 x float> %A1, <2 x float> %A2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %X1 = fsub <2 x float> %A1, %B1
+ %X2 = fsub <2 x float> %A2, %B2
+; CHECK: %X1 = fsub <4 x float> %X1.v.i0, %X1.v.i1
+ %Y1 = fmul <2 x float> %X1, %A1
+ %Y2 = fmul <2 x float> %X2, %A2
+; CHECK: %Y1 = fmul <4 x float> %X1, %X1.v.i0
+ %Z1 = fadd <2 x float> %Y1, %B1
+ %Z2 = fadd <2 x float> %Y2, %B2
+; CHECK: %Z1 = fadd <4 x float> %Y1, %X1.v.i1
+ %R = fmul <2 x float> %Z1, %Z2
+; CHECK: %Z1.v.r1 = shufflevector <4 x float> %Z1, <4 x float> undef, <2 x i32> <i32 0, i32 1>
+; CHECK: %Z1.v.r2 = shufflevector <4 x float> %Z1, <4 x float> undef, <2 x i32> <i32 2, i32 3>
+; CHECK: %R = fmul <2 x float> %Z1.v.r1, %Z1.v.r2
+ ret <2 x float> %R
+; CHECK: ret <2 x float> %R
+}
+
+; Basic chain with shuffles
+define <8 x i8> @test6(<8 x i8> %A1, <8 x i8> %A2, <8 x i8> %B1, <8 x i8> %B2) {
+; CHECK: @test6
+; CHECK: %X1.v.i1 = shufflevector <8 x i8> %B1, <8 x i8> %B2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK: %X1.v.i0 = shufflevector <8 x i8> %A1, <8 x i8> %A2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ %X1 = sub <8 x i8> %A1, %B1
+ %X2 = sub <8 x i8> %A2, %B2
+; CHECK: %X1 = sub <16 x i8> %X1.v.i0, %X1.v.i1
+ %Y1 = mul <8 x i8> %X1, %A1
+ %Y2 = mul <8 x i8> %X2, %A2
+; CHECK: %Y1 = mul <16 x i8> %X1, %X1.v.i0
+ %Z1 = add <8 x i8> %Y1, %B1
+ %Z2 = add <8 x i8> %Y2, %B2
+; CHECK: %Z1 = add <16 x i8> %Y1, %X1.v.i1
+ %Q1 = shufflevector <8 x i8> %Z1, <8 x i8> %Z2, <8 x i32> <i32 15, i32 8, i32 6, i32 1, i32 13, i32 10, i32 4, i32 3>
+ %Q2 = shufflevector <8 x i8> %Z2, <8 x i8> %Z2, <8 x i32> <i32 6, i32 7, i32 0, i32 1, i32 2, i32 4, i32 4, i32 1>
+; CHECK: %Z1.v.r2 = shufflevector <16 x i8> %Z1, <16 x i8> undef, <8 x i32> <i32 8, i32 undef, i32 10, i32 undef, i32 undef, i32 13, i32 undef, i32 15>
+; CHECK: %Q1.v.i1 = shufflevector <8 x i8> %Z1.v.r2, <8 x i8> undef, <16 x i32> <i32 0, i32 undef, i32 2, i32 undef, i32 undef, i32 5, i32 undef, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+; CHECK: %Q1 = shufflevector <16 x i8> %Z1, <16 x i8> %Q1.v.i1, <16 x i32> <i32 23, i32 16, i32 6, i32 1, i32 21, i32 18, i32 4, i32 3, i32 14, i32 15, i32 8, i32 9, i32 10, i32 12, i32 12, i32 9>
+ %R = mul <8 x i8> %Q1, %Q2
+; CHECK: %Q1.v.r1 = shufflevector <16 x i8> %Q1, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+; CHECK: %Q1.v.r2 = shufflevector <16 x i8> %Q1, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK: %R = mul <8 x i8> %Q1.v.r1, %Q1.v.r2
+ ret <8 x i8> %R
+; CHECK: ret <8 x i8> %R
+}
+
+
diff --git a/test/Transforms/BlockPlacement/dg.exp b/test/Transforms/BlockPlacement/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/BlockPlacement/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/BlockPlacement/lit.local.cfg b/test/Transforms/BlockPlacement/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/BlockPlacement/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/CodeExtractor/dg.exp b/test/Transforms/CodeExtractor/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/CodeExtractor/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/CodeExtractor/lit.local.cfg b/test/Transforms/CodeExtractor/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/CodeExtractor/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/CodeGenPrepare/dg.exp b/test/Transforms/CodeGenPrepare/dg.exp
deleted file mode 100644
index de42dad..0000000
--- a/test/Transforms/CodeGenPrepare/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]]
diff --git a/test/Transforms/CodeGenPrepare/lit.local.cfg b/test/Transforms/CodeGenPrepare/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/Transforms/CodeGenPrepare/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/test/Transforms/ConstProp/2007-11-23-cttz.ll b/test/Transforms/ConstProp/2007-11-23-cttz.ll
index 37cda30..a28c9b0 100644
--- a/test/Transforms/ConstProp/2007-11-23-cttz.ll
+++ b/test/Transforms/ConstProp/2007-11-23-cttz.ll
@@ -1,8 +1,8 @@
; RUN: opt < %s -constprop -S | grep {ret i13 13}
; PR1816
-declare i13 @llvm.cttz.i13(i13)
+declare i13 @llvm.cttz.i13(i13, i1)
define i13 @test() {
- %X = call i13 @llvm.cttz.i13(i13 0)
+ %X = call i13 @llvm.cttz.i13(i13 0, i1 true)
ret i13 %X
}
diff --git a/test/Transforms/ConstProp/basictest.ll b/test/Transforms/ConstProp/basictest.ll
index d0d0a5b..09e6e7d 100644
--- a/test/Transforms/ConstProp/basictest.ll
+++ b/test/Transforms/ConstProp/basictest.ll
@@ -1,5 +1,8 @@
; RUN: opt < %s -constprop -die -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
; This is a basic sanity check for constant propagation. The add instruction
; should be eliminated.
define i32 @test1(i1 %B) {
@@ -40,3 +43,11 @@ define i1 @TNAN() {
%C = or i1 %A, %B
ret i1 %C
}
+
+define i128 @vector_to_int_cast() {
+ %A = bitcast <4 x i32> <i32 1073741824, i32 1073741824, i32 1073741824, i32 1073741824> to i128
+ ret i128 %A
+; CHECK: @vector_to_int_cast
+; CHECK: ret i128 85070591750041656499021422275829170176
+}
+ \ No newline at end of file
diff --git a/test/Transforms/ConstProp/bswap.ll b/test/Transforms/ConstProp/bswap.ll
index 9fce309..a68fdcd 100644
--- a/test/Transforms/ConstProp/bswap.ll
+++ b/test/Transforms/ConstProp/bswap.ll
@@ -1,6 +1,6 @@
; bswap should be constant folded when it is passed a constant argument
-; RUN: opt < %s -constprop -S | not grep call
+; RUN: opt < %s -constprop -S | FileCheck %s
declare i16 @llvm.bswap.i16(i16)
@@ -8,18 +8,34 @@ declare i32 @llvm.bswap.i32(i32)
declare i64 @llvm.bswap.i64(i64)
+declare i80 @llvm.bswap.i80(i80)
+
+; CHECK: define i16 @W
define i16 @W() {
+ ; CHECK: ret i16 256
%Z = call i16 @llvm.bswap.i16( i16 1 ) ; <i16> [#uses=1]
ret i16 %Z
}
+; CHECK: define i32 @X
define i32 @X() {
+ ; CHECK: ret i32 16777216
%Z = call i32 @llvm.bswap.i32( i32 1 ) ; <i32> [#uses=1]
ret i32 %Z
}
+; CHECK: define i64 @Y
define i64 @Y() {
+ ; CHECK: ret i64 72057594037927936
%Z = call i64 @llvm.bswap.i64( i64 1 ) ; <i64> [#uses=1]
ret i64 %Z
}
+; CHECK: define i80 @Z
+define i80 @Z() {
+ ; CHECK: ret i80 -450681596205739728166896
+ ; 0xA0908070605040302010
+ %Z = call i80 @llvm.bswap.i80( i80 76151636403560493650080 )
+ ; 0x102030405060708090A0
+ ret i80 %Z
+}
diff --git a/test/Transforms/ConstProp/calls.ll b/test/Transforms/ConstProp/calls.ll
index 3b6010a..7a405a5 100644
--- a/test/Transforms/ConstProp/calls.ll
+++ b/test/Transforms/ConstProp/calls.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -constprop -S | FileCheck %s
+; RUN: opt < %s -constprop -disable-simplify-libcalls -S | FileCheck %s --check-prefix=FNOBUILTIN
declare double @cos(double)
@@ -59,3 +60,90 @@ declare i32 @llvm.x86.sse2.cvtsd2si(<2 x double>) nounwind readnone
declare i32 @llvm.x86.sse2.cvttsd2si(<2 x double>) nounwind readnone
declare i64 @llvm.x86.sse2.cvtsd2si64(<2 x double>) nounwind readnone
declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>) nounwind readnone
+
+define double @test_intrinsic_pow() nounwind uwtable ssp {
+entry:
+; CHECK: @test_intrinsic_pow
+; CHECK-NOT: call
+ %0 = call double @llvm.pow.f64(double 1.500000e+00, double 3.000000e+00)
+ ret double %0
+}
+declare double @llvm.pow.f64(double, double) nounwind readonly
+
+; Shouldn't fold because of -fno-builtin
+define double @sin_() nounwind uwtable ssp {
+; FNOBUILTIN: @sin_
+; FNOBUILTIN: %1 = call double @sin(double 3.000000e+00)
+ %1 = call double @sin(double 3.000000e+00)
+ ret double %1
+}
+
+; Shouldn't fold because of -fno-builtin
+define double @sqrt_() nounwind uwtable ssp {
+; FNOBUILTIN: @sqrt_
+; FNOBUILTIN: %1 = call double @sqrt(double 3.000000e+00)
+ %1 = call double @sqrt(double 3.000000e+00)
+ ret double %1
+}
+
+; Shouldn't fold because of -fno-builtin
+define float @sqrtf_() nounwind uwtable ssp {
+; FNOBUILTIN: @sqrtf_
+; FNOBUILTIN: %1 = call float @sqrtf(float 3.000000e+00)
+ %1 = call float @sqrtf(float 3.000000e+00)
+ ret float %1
+}
+declare float @sqrtf(float)
+
+; Shouldn't fold because of -fno-builtin
+define float @sinf_() nounwind uwtable ssp {
+; FNOBUILTIN: @sinf_
+; FNOBUILTIN: %1 = call float @sinf(float 3.000000e+00)
+ %1 = call float @sinf(float 3.000000e+00)
+ ret float %1
+}
+declare float @sinf(float)
+
+; Shouldn't fold because of -fno-builtin
+define double @tan_() nounwind uwtable ssp {
+; FNOBUILTIN: @tan_
+; FNOBUILTIN: %1 = call double @tan(double 3.000000e+00)
+ %1 = call double @tan(double 3.000000e+00)
+ ret double %1
+}
+
+; Shouldn't fold because of -fno-builtin
+define double @tanh_() nounwind uwtable ssp {
+; FNOBUILTIN: @tanh_
+; FNOBUILTIN: %1 = call double @tanh(double 3.000000e+00)
+ %1 = call double @tanh(double 3.000000e+00)
+ ret double %1
+}
+declare double @tanh(double)
+
+; Shouldn't fold because of -fno-builtin
+define double @pow_() nounwind uwtable ssp {
+; FNOBUILTIN: @pow_
+; FNOBUILTIN: %1 = call double @pow(double 3.000000e+00, double 3.000000e+00)
+ %1 = call double @pow(double 3.000000e+00, double 3.000000e+00)
+ ret double %1
+}
+declare double @pow(double, double)
+
+; Shouldn't fold because of -fno-builtin
+define double @fmod_() nounwind uwtable ssp {
+; FNOBUILTIN: @fmod_
+; FNOBUILTIN: %1 = call double @fmod(double 3.000000e+00, double 3.000000e+00)
+ %1 = call double @fmod(double 3.000000e+00, double 3.000000e+00)
+ ret double %1
+}
+declare double @fmod(double, double)
+
+; Shouldn't fold because of -fno-builtin
+define double @atan2_() nounwind uwtable ssp {
+; FNOBUILTIN: @atan2_
+; FNOBUILTIN: %1 = call double @atan2(double 3.000000e+00, double 3.000000e+00)
+ %1 = call double @atan2(double 3.000000e+00, double 3.000000e+00)
+ ret double %1
+}
+declare double @atan2(double, double)
diff --git a/test/Transforms/ConstProp/dg.exp b/test/Transforms/ConstProp/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/ConstProp/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/ConstProp/lit.local.cfg b/test/Transforms/ConstProp/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/ConstProp/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/ConstantMerge/dg.exp b/test/Transforms/ConstantMerge/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/ConstantMerge/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/ConstantMerge/linker-private.ll b/test/Transforms/ConstantMerge/linker-private.ll
new file mode 100644
index 0000000..eba7880
--- /dev/null
+++ b/test/Transforms/ConstantMerge/linker-private.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -constmerge -S | FileCheck %s
+; <rdar://problem/10564621>
+
+%0 = type opaque
+%struct.NSConstantString = type { i32*, i32, i8*, i32 }
+
+; CHECK: @.str3 = linker_private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+
+@isLogVisible = global i8 0, align 1
+@__CFConstantStringClassReference = external global [0 x i32]
+@.str3 = linker_private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+@_unnamed_cfstring_4 = private constant %struct.NSConstantString { i32* getelementptr inbounds ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([1 x i8]* @.str3, i32 0, i32 0), i32 0 }, section "__DATA,__cfstring"
+@null.array = weak_odr constant [1 x i8] zeroinitializer, align 1
+
+define linkonce_odr void @bar() nounwind ssp align 2 {
+entry:
+ %stack = alloca i8*, align 4
+ %call = call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %0* (i8*, i8*, %0*)*)(i8* null, i8* null, %0* bitcast (%struct.NSConstantString* @_unnamed_cfstring_4 to %0*))
+ store i8* getelementptr inbounds ([1 x i8]* @null.array, i32 0, i32 0), i8** %stack, align 4
+ ret void
+}
+
+declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
diff --git a/test/Transforms/ConstantMerge/lit.local.cfg b/test/Transforms/ConstantMerge/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/ConstantMerge/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/CorrelatedValuePropagation/basic.ll b/test/Transforms/CorrelatedValuePropagation/basic.ll
index 270c048..475cd8d 100644
--- a/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ b/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -79,4 +79,103 @@ Impossible:
LessThanOrEqualToTwo:
ret i32 0
-} \ No newline at end of file
+}
+
+define i32 @switch1(i32 %s) {
+; CHECK: @switch1
+entry:
+ %cmp = icmp slt i32 %s, 0
+ br i1 %cmp, label %negative, label %out
+
+negative:
+ switch i32 %s, label %out [
+; CHECK: switch i32 %s, label %out
+ i32 0, label %out
+; CHECK-NOT: i32 0
+ i32 1, label %out
+; CHECK-NOT: i32 1
+ i32 -1, label %next
+; CHECK: i32 -1, label %next
+ i32 -2, label %next
+; CHECK: i32 -2, label %next
+ i32 2, label %out
+; CHECK-NOT: i32 2
+ i32 3, label %out
+; CHECK-NOT: i32 3
+ ]
+
+out:
+ %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
+ ret i32 %p
+
+next:
+ %q = phi i32 [ 0, %negative ], [ 0, %negative ]
+ ret i32 %q
+}
+
+define i32 @switch2(i32 %s) {
+; CHECK: @switch2
+entry:
+ %cmp = icmp sgt i32 %s, 0
+ br i1 %cmp, label %positive, label %out
+
+positive:
+ switch i32 %s, label %out [
+ i32 0, label %out
+ i32 -1, label %next
+ i32 -2, label %next
+ ]
+; CHECK: br label %out
+
+out:
+ %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
+ ret i32 %p
+
+next:
+ %q = phi i32 [ 0, %positive ], [ 0, %positive ]
+ ret i32 %q
+}
+
+define i32 @switch3(i32 %s) {
+; CHECK: @switch3
+entry:
+ %cmp = icmp sgt i32 %s, 0
+ br i1 %cmp, label %positive, label %out
+
+positive:
+ switch i32 %s, label %out [
+ i32 -1, label %out
+ i32 -2, label %next
+ i32 -3, label %next
+ ]
+; CHECK: br label %out
+
+out:
+ %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
+ ret i32 %p
+
+next:
+ %q = phi i32 [ 0, %positive ], [ 0, %positive ]
+ ret i32 %q
+}
+
+define void @switch4(i32 %s) {
+; CHECK: @switch4
+entry:
+ %cmp = icmp eq i32 %s, 0
+ br i1 %cmp, label %zero, label %out
+
+zero:
+ switch i32 %s, label %out [
+ i32 0, label %next
+ i32 1, label %out
+ i32 -1, label %out
+ ]
+; CHECK: br label %next
+
+out:
+ ret void
+
+next:
+ ret void
+}
diff --git a/test/Transforms/CorrelatedValuePropagation/dg.exp b/test/Transforms/CorrelatedValuePropagation/dg.exp
deleted file mode 100644
index de42dad..0000000
--- a/test/Transforms/CorrelatedValuePropagation/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]]
diff --git a/test/Transforms/CorrelatedValuePropagation/lit.local.cfg b/test/Transforms/CorrelatedValuePropagation/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/Transforms/CorrelatedValuePropagation/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/test/Transforms/CorrelatedValuePropagation/range.ll b/test/Transforms/CorrelatedValuePropagation/range.ll
new file mode 100644
index 0000000..9b70ed2
--- /dev/null
+++ b/test/Transforms/CorrelatedValuePropagation/range.ll
@@ -0,0 +1,43 @@
+; RUN: opt -correlated-propagation -S < %s | FileCheck %s
+
+declare i32 @foo()
+
+define i32 @test1(i32 %a) nounwind {
+ %a.off = add i32 %a, -8
+ %cmp = icmp ult i32 %a.off, 8
+ br i1 %cmp, label %then, label %else
+
+then:
+ %dead = icmp eq i32 %a, 7
+ br i1 %dead, label %end, label %else
+
+else:
+ ret i32 1
+
+end:
+ ret i32 2
+
+; CHECK: @test1
+; CHECK: then:
+; CHECK-NEXT: br i1 false, label %end, label %else
+}
+
+define i32 @test2(i32 %a) nounwind {
+ %a.off = add i32 %a, -8
+ %cmp = icmp ult i32 %a.off, 8
+ br i1 %cmp, label %then, label %else
+
+then:
+ %dead = icmp ugt i32 %a, 15
+ br i1 %dead, label %end, label %else
+
+else:
+ ret i32 1
+
+end:
+ ret i32 2
+
+; CHECK: @test2
+; CHECK: then:
+; CHECK-NEXT: br i1 false, label %end, label %else
+}
diff --git a/test/Transforms/DeadArgElim/deadexternal.ll b/test/Transforms/DeadArgElim/deadexternal.ll
index b2d63ec..e3fe1bb 100644
--- a/test/Transforms/DeadArgElim/deadexternal.ll
+++ b/test/Transforms/DeadArgElim/deadexternal.ll
@@ -30,10 +30,10 @@ entry:
define void @h() {
entry:
%i = alloca i32, align 4
- volatile store i32 10, i32* %i, align 4
+ store volatile i32 10, 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
+ %tmp = load volatile i32* %i, align 4
call void @f(i32 %tmp)
ret void
}
diff --git a/test/Transforms/DeadArgElim/dg.exp b/test/Transforms/DeadArgElim/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/DeadArgElim/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/DeadArgElim/lit.local.cfg b/test/Transforms/DeadArgElim/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/DeadArgElim/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll b/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll
new file mode 100644
index 0000000..ed53eb5
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll
@@ -0,0 +1,95 @@
+; RUN: opt < %s -basicaa -dse -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+%struct.vec2 = type { <4 x i32>, <4 x i32> }
+%struct.vec2plusi = type { <4 x i32>, <4 x i32>, i32 }
+
+@glob1 = global %struct.vec2 zeroinitializer, align 16
+@glob2 = global %struct.vec2plusi zeroinitializer, align 16
+
+define void @write24to28(i32* nocapture %p) nounwind uwtable ssp {
+; CHECK: @write24to28
+entry:
+ %arrayidx0 = getelementptr inbounds i32* %p, i64 1
+ %p3 = bitcast i32* %arrayidx0 to i8*
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 24, i32 4, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+ %arrayidx1 = getelementptr inbounds i32* %p, i64 7
+ store i32 1, i32* %arrayidx1, align 4
+ ret void
+}
+
+define void @write28to32(i32* nocapture %p) nounwind uwtable ssp {
+; CHECK: @write28to32
+entry:
+ %p3 = bitcast i32* %p to i8*
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 32, i32 4, i1 false)
+ %arrayidx1 = getelementptr inbounds i32* %p, i64 7
+ store i32 1, i32* %arrayidx1, align 4
+ ret void
+}
+
+define void @dontwrite28to32memset(i32* nocapture %p) nounwind uwtable ssp {
+; CHECK: @dontwrite28to32memset
+entry:
+ %p3 = bitcast i32* %p to i8*
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 32, i32 16, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 32, i32 16, i1 false)
+ %arrayidx1 = getelementptr inbounds i32* %p, i64 7
+ store i32 1, i32* %arrayidx1, align 4
+ ret void
+}
+
+define void @write32to36(%struct.vec2plusi* nocapture %p) nounwind uwtable ssp {
+; CHECK: @write32to36
+entry:
+ %0 = bitcast %struct.vec2plusi* %p to i8*
+; CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.vec2plusi* @glob2 to i8*), i64 32, i32 16, i1 false)
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 16, i1 false)
+ %c = getelementptr inbounds %struct.vec2plusi* %p, i64 0, i32 2
+ store i32 1, i32* %c, align 4
+ ret void
+}
+
+define void @write16to32(%struct.vec2* nocapture %p) nounwind uwtable ssp {
+; CHECK: @write16to32
+entry:
+ %0 = bitcast %struct.vec2* %p to i8*
+; CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.vec2* @glob1 to i8*), i64 16, i32 16, i1 false)
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 16, i1 false)
+ %c = getelementptr inbounds %struct.vec2* %p, i64 0, i32 1
+ store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32>* %c, align 4
+ ret void
+}
+
+define void @dontwrite28to32memcpy(%struct.vec2* nocapture %p) nounwind uwtable ssp {
+; CHECK: @dontwrite28to32memcpy
+entry:
+ %0 = bitcast %struct.vec2* %p to i8*
+; CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 16, i1 false)
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 16, i1 false)
+ %arrayidx1 = getelementptr inbounds %struct.vec2* %p, i64 0, i32 0, i64 7
+ store i32 1, i32* %arrayidx1, align 4
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+%struct.trapframe = type { i64, i64, i64 }
+
+; bugzilla 11455 - make sure negative GEP's don't break this optimisation
+; CHECK: @cpu_lwp_fork
+define void @cpu_lwp_fork(%struct.trapframe* %md_regs, i64 %pcb_rsp0) nounwind uwtable noinline ssp {
+entry:
+ %0 = inttoptr i64 %pcb_rsp0 to %struct.trapframe*
+ %add.ptr = getelementptr inbounds %struct.trapframe* %0, i64 -1
+ %1 = bitcast %struct.trapframe* %add.ptr to i8*
+ %2 = bitcast %struct.trapframe* %md_regs to i8*
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 24, i32 1, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 24, i32 1, i1 false)
+ %tf_trapno = getelementptr inbounds %struct.trapframe* %0, i64 -1, i32 1
+ store i64 3, i64* %tf_trapno, align 8
+ ret void
+}
diff --git a/test/Transforms/DeadStoreElimination/dg.exp b/test/Transforms/DeadStoreElimination/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/DeadStoreElimination/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/DeadStoreElimination/dominate.ll b/test/Transforms/DeadStoreElimination/dominate.ll
new file mode 100644
index 0000000..284fea4
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/dominate.ll
@@ -0,0 +1,25 @@
+; RUN: opt %s -dse -disable-output
+; test that we don't crash
+declare void @bar()
+
+define void @foo() {
+bb1:
+ %memtmp3.i = alloca [21 x i8], align 1
+ %0 = getelementptr inbounds [21 x i8]* %memtmp3.i, i64 0, i64 0
+ br label %bb3
+
+bb2:
+ call void @llvm.lifetime.end(i64 -1, i8* %0)
+ br label %bb3
+
+bb3:
+ call void @bar()
+ call void @llvm.lifetime.end(i64 -1, i8* %0)
+ br label %bb4
+
+bb4:
+ ret void
+
+}
+
+declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
diff --git a/test/Transforms/DeadStoreElimination/free.ll b/test/Transforms/DeadStoreElimination/free.ll
index aa3f0ab..a5fbdc7 100644
--- a/test/Transforms/DeadStoreElimination/free.ll
+++ b/test/Transforms/DeadStoreElimination/free.ll
@@ -2,6 +2,9 @@
target datalayout = "e-p:64:64:64"
+declare void @free(i8* nocapture)
+declare noalias i8* @malloc(i64)
+
; CHECK: @test
; CHECK-NEXT: bitcast
; CHECK-NEXT: @free
@@ -26,10 +29,10 @@ define void @test2({i32, i32}* %P) {
ret void
}
-; CHECK: @test4
+; CHECK: @test3
; CHECK-NOT: store
; CHECK: ret void
-define void @test4() {
+define void @test3() {
%m = call i8* @malloc(i64 24)
store i8 0, i8* %m
%m1 = getelementptr i8* %m, i64 1
@@ -38,5 +41,30 @@ define void @test4() {
ret void
}
-declare void @free(i8*)
-declare i8* @malloc(i64)
+; PR11240
+; CHECK: @test4
+; CHECK-NOT: store
+; CHECK: ret void
+define void @test4(i1 %x) nounwind {
+entry:
+ %alloc1 = tail call noalias i8* @malloc(i64 4) nounwind
+ br i1 %x, label %skipinit1, label %init1
+
+init1:
+ store i8 1, i8* %alloc1
+ br label %skipinit1
+
+skipinit1:
+ tail call void @free(i8* %alloc1) nounwind
+ ret void
+}
+
+; CHECK: @test5
+define void @test5() {
+ br label %bb
+
+bb:
+ tail call void @free(i8* undef) nounwind
+ br label %bb
+}
+
diff --git a/test/Transforms/DeadStoreElimination/lit.local.cfg b/test/Transforms/DeadStoreElimination/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/DeadStoreElimination/pr11390.ll b/test/Transforms/DeadStoreElimination/pr11390.ll
new file mode 100644
index 0000000..2ce6eea
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/pr11390.ll
@@ -0,0 +1,38 @@
+; RUN: opt -basicaa -dse -S -o - %s | FileCheck %s
+; PR11390
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define fastcc void @cat_domain(i8* nocapture %name, i8* nocapture %domain, i8**
+nocapture %s) nounwind uwtable {
+entry:
+ %call = tail call i64 @strlen(i8* %name) nounwind readonly
+ %call1 = tail call i64 @strlen(i8* %domain) nounwind readonly
+ %add = add i64 %call, 1
+ %add2 = add i64 %add, %call1
+ %add3 = add i64 %add2, 1
+ %call4 = tail call noalias i8* @malloc(i64 %add3) nounwind
+ store i8* %call4, i8** %s, align 8
+ %tobool = icmp eq i8* %call4, null
+ br i1 %tobool, label %return, label %if.end
+
+if.end: ; preds = %entry
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %call4, i8* %name, i64 %call, i32 1, i1 false)
+ %arrayidx = getelementptr inbounds i8* %call4, i64 %call
+ store i8 46, i8* %arrayidx, align 1
+; CHECK: store i8 46
+ %add.ptr5 = getelementptr inbounds i8* %call4, i64 %add
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %add.ptr5, i8* %domain, i64 %call1, i32 1, i1 false)
+ %arrayidx8 = getelementptr inbounds i8* %call4, i64 %add2
+ store i8 0, i8* %arrayidx8, align 1
+ br label %return
+
+return: ; preds = %if.end, %entry
+ ret void
+}
+
+declare i64 @strlen(i8* nocapture) nounwind readonly
+
+declare noalias i8* @malloc(i64) nounwind
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll
index ec2f157..81eb5a8 100644
--- a/test/Transforms/DeadStoreElimination/simple.ll
+++ b/test/Transforms/DeadStoreElimination/simple.ll
@@ -251,3 +251,10 @@ bb:
; CHECK: call void @test19f
}
+define void @test20() {
+ %m = call i8* @malloc(i32 24)
+ store i8 0, i8* %m
+ ret void
+}
+; CHECK: @test20
+; CHECK-NEXT: ret void
diff --git a/test/Transforms/EarlyCSE/basic.ll b/test/Transforms/EarlyCSE/basic.ll
index 57b1697..32c302c 100644
--- a/test/Transforms/EarlyCSE/basic.ll
+++ b/test/Transforms/EarlyCSE/basic.ll
@@ -10,22 +10,22 @@ define void @test1(i8 %V, i32 *%P) {
%C = zext i8 %V to i32
%D = zext i8 %V to i32 ;; CSE
- volatile store i32 %C, i32* %P
- volatile store i32 %D, i32* %P
+ store volatile i32 %C, i32* %P
+ store volatile i32 %D, i32* %P
; CHECK-NEXT: %C = zext i8 %V to i32
; 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
+ store volatile i32 %E, i32* %P
+ store volatile i32 %F, i32* %P
; CHECK-NEXT: %E = add i32 %C, %C
; 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
+ store volatile i32 %G, i32* %P
; CHECK-NEXT: %G = add nuw i32 %C, %C
; CHECK-NEXT: store volatile i32 %G
ret void
diff --git a/test/Transforms/EarlyCSE/dg.exp b/test/Transforms/EarlyCSE/dg.exp
deleted file mode 100644
index de42dad..0000000
--- a/test/Transforms/EarlyCSE/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]]
diff --git a/test/Transforms/EarlyCSE/instsimplify-dom.ll b/test/Transforms/EarlyCSE/instsimplify-dom.ll
new file mode 100644
index 0000000..36dffec
--- /dev/null
+++ b/test/Transforms/EarlyCSE/instsimplify-dom.ll
@@ -0,0 +1,19 @@
+; RUN: opt -early-cse -S < %s | FileCheck %s
+; PR12231
+
+declare i32 @f()
+
+define i32 @fn() {
+entry:
+ br label %lbl_1215
+
+lbl_1215:
+ %ins34 = phi i32 [ %ins35, %xxx ], [ undef, %entry ]
+ ret i32 %ins34
+
+xxx:
+ %ins35 = call i32 @f()
+ br label %lbl_1215
+}
+
+; CHECK: define i32 @fn
diff --git a/test/Transforms/EarlyCSE/lit.local.cfg b/test/Transforms/EarlyCSE/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/Transforms/EarlyCSE/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/test/Transforms/FunctionAttrs/2008-09-13-VolatileRead.ll b/test/Transforms/FunctionAttrs/2008-09-13-VolatileRead.ll
index 85df09e..b7e4d1f 100644
--- a/test/Transforms/FunctionAttrs/2008-09-13-VolatileRead.ll
+++ b/test/Transforms/FunctionAttrs/2008-09-13-VolatileRead.ll
@@ -4,6 +4,6 @@
@g = global i32 0 ; <i32*> [#uses=1]
define i32 @f() {
- %t = volatile load i32* @g ; <i32> [#uses=1]
+ %t = load volatile i32* @g ; <i32> [#uses=1]
ret i32 %t
}
diff --git a/test/Transforms/FunctionAttrs/2010-10-30-volatile.ll b/test/Transforms/FunctionAttrs/2010-10-30-volatile.ll
index f21fabc..93991d2 100644
--- a/test/Transforms/FunctionAttrs/2010-10-30-volatile.ll
+++ b/test/Transforms/FunctionAttrs/2010-10-30-volatile.ll
@@ -5,6 +5,6 @@
define void @foo() {
; CHECK: void @foo() {
- %tmp = volatile load i32* @g
+ %tmp = load volatile i32* @g
ret void
}
diff --git a/test/Transforms/FunctionAttrs/dg.exp b/test/Transforms/FunctionAttrs/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/FunctionAttrs/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/FunctionAttrs/lit.local.cfg b/test/Transforms/FunctionAttrs/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/FunctionAttrs/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll b/test/Transforms/FunctionAttrs/nocapture.ll
index e2bab19..3027acd 100644
--- a/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll
+++ b/test/Transforms/FunctionAttrs/nocapture.ll
@@ -1,21 +1,24 @@
-; RUN: opt < %s -functionattrs -S | not grep {nocapture *%%q}
-; RUN: opt < %s -functionattrs -S | grep {nocapture *%%p} | count 6
+; RUN: opt < %s -functionattrs -S | FileCheck %s
@g = global i32* null ; <i32**> [#uses=1]
+; CHECK: define i32* @c1(i32* %q)
define i32* @c1(i32* %q) {
ret i32* %q
}
+; CHECK: define void @c2(i32* %q)
define void @c2(i32* %q) {
store i32* %q, i32** @g
ret void
}
+; CHECK: define void @c3(i32* %q)
define void @c3(i32* %q) {
call void @c2(i32* %q)
ret void
}
+; CHECK: define i1 @c4(i32* %q, i32 %bitno)
define i1 @c4(i32* %q, i32 %bitno) {
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -29,6 +32,7 @@ l1:
@lookup_table = global [2 x i1] [ i1 0, i1 1 ]
+; CHECK: define i1 @c5(i32* %q, i32 %bitno)
define i1 @c5(i32* %q, i32 %bitno) {
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -40,6 +44,8 @@ define i1 @c5(i32* %q, i32 %bitno) {
}
declare void @throw_if_bit_set(i8*, i8) readonly
+
+; CHECK: define i1 @c6(i8* %q, i8 %bit)
define i1 @c6(i8* %q, i8 %bit) {
invoke void @throw_if_bit_set(i8* %q, i8 %bit)
to label %ret0 unwind label %ret1
@@ -61,6 +67,7 @@ define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
ret i1* %lookup
}
+; CHECK: define i1 @c7(i32* %q, i32 %bitno)
define i1 @c7(i32* %q, i32 %bitno) {
%ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
%val = load i1* %ptr
@@ -68,6 +75,7 @@ define i1 @c7(i32* %q, i32 %bitno) {
}
+; CHECK: define i32 @nc1(i32* %q, i32* nocapture %p, i1 %b)
define i32 @nc1(i32* %q, i32* %p, i1 %b) {
e:
br label %l
@@ -82,24 +90,89 @@ l:
ret i32 %val
}
+; CHECK: define void @nc2(i32* nocapture %p, i32* %q)
define void @nc2(i32* %p, i32* %q) {
%1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
ret void
}
+; CHECK: define void @nc3(void ()* nocapture %p)
define void @nc3(void ()* %p) {
call void %p()
ret void
}
declare void @external(i8*) readonly nounwind
+; CHECK: define void @nc4(i8* nocapture %p)
define void @nc4(i8* %p) {
call void @external(i8* %p)
ret void
}
+; CHECK: define void @nc5(void (i8*)* nocapture %f, i8* nocapture %p)
define void @nc5(void (i8*)* %f, i8* %p) {
call void %f(i8* %p) readonly nounwind
call void %f(i8* nocapture %p)
ret void
}
+
+; CHECK: define void @test1_1(i8* nocapture %x1_1, i8* %y1_1)
+define void @test1_1(i8* %x1_1, i8* %y1_1) {
+ call i8* @test1_2(i8* %x1_1, i8* %y1_1)
+ store i32* null, i32** @g
+ ret void
+}
+
+; CHECK: define i8* @test1_2(i8* nocapture %x1_2, i8* %y1_2)
+define i8* @test1_2(i8* %x1_2, i8* %y1_2) {
+ call void @test1_1(i8* %x1_2, i8* %y1_2)
+ store i32* null, i32** @g
+ ret i8* %y1_2
+}
+
+; CHECK: define void @test2(i8* nocapture %x2)
+define void @test2(i8* %x2) {
+ call void @test2(i8* %x2)
+ store i32* null, i32** @g
+ ret void
+}
+
+; CHECK: define void @test3(i8* nocapture %x3, i8* nocapture %y3, i8* nocapture %z3)
+define void @test3(i8* %x3, i8* %y3, i8* %z3) {
+ call void @test3(i8* %z3, i8* %y3, i8* %x3)
+ store i32* null, i32** @g
+ ret void
+}
+
+; CHECK: define void @test4_1(i8* %x4_1)
+define void @test4_1(i8* %x4_1) {
+ call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1)
+ store i32* null, i32** @g
+ ret void
+}
+
+; CHECK: define i8* @test4_2(i8* nocapture %x4_2, i8* %y4_2, i8* nocapture %z4_2)
+define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) {
+ call void @test4_1(i8* null)
+ store i32* null, i32** @g
+ ret i8* %y4_2
+}
+
+declare i8* @test5_1(i8* %x5_1)
+
+; CHECK: define void @test5_2(i8* %x5_2)
+define void @test5_2(i8* %x5_2) {
+ call i8* @test5_1(i8* %x5_2)
+ store i32* null, i32** @g
+ ret void
+}
+
+declare void @test6_1(i8* %x6_1, i8* nocapture %y6_1, ...)
+
+; CHECK: define void @test6_2(i8* %x6_2, i8* nocapture %y6_2, i8* %z6_2)
+define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) {
+ call void (i8*, i8*, ...)* @test6_1(i8* %x6_2, i8* %y6_2, i8* %z6_2)
+ store i32* null, i32** @g
+ ret void
+}
+
diff --git a/test/Transforms/GVN/commute.ll b/test/Transforms/GVN/commute.ll
new file mode 100644
index 0000000..cf4fb7f
--- /dev/null
+++ b/test/Transforms/GVN/commute.ll
@@ -0,0 +1,23 @@
+; RUN: opt -gvn -S < %s | FileCheck %s
+
+declare void @use(i32, i32)
+
+define void @foo(i32 %x, i32 %y) {
+ ; CHECK: @foo
+ %add1 = add i32 %x, %y
+ %add2 = add i32 %y, %x
+ call void @use(i32 %add1, i32 %add2)
+ ; CHECK: @use(i32 %add1, i32 %add1)
+ ret void
+}
+
+declare void @vse(i1, i1)
+
+define void @bar(i32 %x, i32 %y) {
+ ; CHECK: @bar
+ %cmp1 = icmp ult i32 %x, %y
+ %cmp2 = icmp ugt i32 %y, %x
+ call void @vse(i1 %cmp1, i1 %cmp2)
+ ; CHECK: @vse(i1 %cmp1, i1 %cmp1)
+ ret void
+}
diff --git a/test/Transforms/GVN/condprop.ll b/test/Transforms/GVN/condprop.ll
index 0b31b01..9c28955 100644
--- a/test/Transforms/GVN/condprop.ll
+++ b/test/Transforms/GVN/condprop.ll
@@ -55,25 +55,6 @@ return: ; preds = %bb8
}
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
@@ -130,3 +111,141 @@ case3:
; CHECK: call void @bar(i32 %x)
ret void
}
+
+; CHECK: @test5
+define i1 @test5(i32 %x, i32 %y) {
+ %cmp = icmp eq i32 %x, %y
+ br i1 %cmp, label %same, label %different
+
+same:
+ %cmp2 = icmp ne i32 %x, %y
+; CHECK: ret i1 false
+ ret i1 %cmp2
+
+different:
+ %cmp3 = icmp eq i32 %x, %y
+; CHECK: ret i1 false
+ ret i1 %cmp3
+}
+
+; CHECK: @test6
+define i1 @test6(i32 %x, i32 %y) {
+ %cmp2 = icmp ne i32 %x, %y
+ %cmp = icmp eq i32 %x, %y
+ %cmp3 = icmp eq i32 %x, %y
+ br i1 %cmp, label %same, label %different
+
+same:
+; CHECK: ret i1 false
+ ret i1 %cmp2
+
+different:
+; CHECK: ret i1 false
+ ret i1 %cmp3
+}
+
+; CHECK: @test7
+define i1 @test7(i32 %x, i32 %y) {
+ %cmp = icmp sgt i32 %x, %y
+ br i1 %cmp, label %same, label %different
+
+same:
+ %cmp2 = icmp sle i32 %x, %y
+; CHECK: ret i1 false
+ ret i1 %cmp2
+
+different:
+ %cmp3 = icmp sgt i32 %x, %y
+; CHECK: ret i1 false
+ ret i1 %cmp3
+}
+
+; CHECK: @test8
+define i1 @test8(i32 %x, i32 %y) {
+ %cmp2 = icmp sle i32 %x, %y
+ %cmp = icmp sgt i32 %x, %y
+ %cmp3 = icmp sgt i32 %x, %y
+ br i1 %cmp, label %same, label %different
+
+same:
+; CHECK: ret i1 false
+ ret i1 %cmp2
+
+different:
+; CHECK: ret i1 false
+ ret i1 %cmp3
+}
+
+; PR1768
+; CHECK: @test9
+define i32 @test9(i32 %i, i32 %j) {
+ %cmp = icmp eq i32 %i, %j
+ br i1 %cmp, label %cond_true, label %ret
+
+cond_true:
+ %diff = sub i32 %i, %j
+ ret i32 %diff
+; CHECK: ret i32 0
+
+ret:
+ ret i32 5
+; CHECK: ret i32 5
+}
+
+; PR1768
+; CHECK: @test10
+define i32 @test10(i32 %j, i32 %i) {
+ %cmp = icmp eq i32 %i, %j
+ br i1 %cmp, label %cond_true, label %ret
+
+cond_true:
+ %diff = sub i32 %i, %j
+ ret i32 %diff
+; CHECK: ret i32 0
+
+ret:
+ ret i32 5
+; CHECK: ret i32 5
+}
+
+declare i32 @yogibar()
+
+; CHECK: @test11
+define i32 @test11(i32 %x) {
+ %v0 = call i32 @yogibar()
+ %v1 = call i32 @yogibar()
+ %cmp = icmp eq i32 %v0, %v1
+ br i1 %cmp, label %cond_true, label %next
+
+cond_true:
+ ret i32 %v1
+; CHECK: ret i32 %v0
+
+next:
+ %cmp2 = icmp eq i32 %x, %v0
+ br i1 %cmp2, label %cond_true2, label %next2
+
+cond_true2:
+ ret i32 %v0
+; CHECK: ret i32 %x
+
+next2:
+ ret i32 0
+}
+
+; CHECK: @test12
+define i32 @test12(i32 %x) {
+ %cmp = icmp eq i32 %x, 0
+ br i1 %cmp, label %cond_true, label %cond_false
+
+cond_true:
+ br label %ret
+
+cond_false:
+ br label %ret
+
+ret:
+ %res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ]
+; CHECK: %res = phi i32 [ 0, %cond_true ], [ %x, %cond_false ]
+ ret i32 %res
+}
diff --git a/test/Transforms/GVN/dg.exp b/test/Transforms/GVN/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/GVN/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/GVN/lit.local.cfg b/test/Transforms/GVN/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/GVN/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/GVN/pre-compare.ll b/test/Transforms/GVN/pre-compare.ll
new file mode 100644
index 0000000..18d0c2e
--- /dev/null
+++ b/test/Transforms/GVN/pre-compare.ll
@@ -0,0 +1,68 @@
+; RUN: opt -gvn -S < %s | FileCheck %s
+
+; C source:
+;
+; void f(int x) {
+; if (x != 1)
+; puts (x == 2 ? "a" : "b");
+; for (;;) {
+; puts("step 1");
+; if (x == 2)
+; continue;
+; printf("step 2: %d\n", x);
+; }
+; }
+;
+; If we PRE %cmp3, CodeGenPrepare won't be able to sink the compare down to its
+; uses, and we are forced to keep both %x and %cmp3 in registers in the loop.
+;
+; It is just as cheap to recompute the icmp against %x as it is to compare a
+; GPR against 0. On x86-64, the br i1 %cmp3 becomes:
+;
+; testb %r12b, %r12b
+; jne LBB0_3
+;
+; The sunk icmp is:
+;
+; cmpl $2, %ebx
+; je LBB0_3
+;
+; This is just as good, and it doesn't require a separate register.
+;
+; CHECK-NOT: phi i1
+
+@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1
+@.str1 = private unnamed_addr constant [2 x i8] c"b\00", align 1
+@.str2 = private unnamed_addr constant [7 x i8] c"step 1\00", align 1
+@.str3 = private unnamed_addr constant [12 x i8] c"step 2: %d\0A\00", align 1
+
+define void @f(i32 %x) noreturn nounwind uwtable ssp {
+entry:
+ %cmp = icmp eq i32 %x, 1
+ br i1 %cmp, label %for.cond.preheader, label %if.then
+
+if.then: ; preds = %entry
+ %cmp1 = icmp eq i32 %x, 2
+ %cond = select i1 %cmp1, i8* getelementptr inbounds ([2 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8]* @.str1, i64 0, i64 0)
+ %call = tail call i32 @puts(i8* %cond) nounwind
+ br label %for.cond.preheader
+
+for.cond.preheader: ; preds = %entry, %if.then
+ %cmp3 = icmp eq i32 %x, 2
+ br label %for.cond
+
+for.cond: ; preds = %for.cond.backedge, %for.cond.preheader
+ %call2 = tail call i32 @puts(i8* getelementptr inbounds ([7 x i8]* @.str2, i64 0, i64 0)) nounwind
+ br i1 %cmp3, label %for.cond.backedge, label %if.end5
+
+if.end5: ; preds = %for.cond
+ %call6 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str3, i64 0, i64 0), i32 %x) nounwind
+ br label %for.cond.backedge
+
+for.cond.backedge: ; preds = %if.end5, %for.cond
+ br label %for.cond
+}
+
+declare i32 @puts(i8* nocapture) nounwind
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/test/Transforms/GVN/rle.ll b/test/Transforms/GVN/rle.ll
index 2f0d2eb..9e08004 100644
--- a/test/Transforms/GVN/rle.ll
+++ b/test/Transforms/GVN/rle.ll
@@ -26,6 +26,15 @@ define i8 @crash0({i32, i32} %A, {i32, i32}* %P) {
ret i8 %Y
}
+;; No PR filed, crashed in CaptureTracker.
+declare void @helper()
+define void @crash1() {
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* undef, i8* undef, i64 undef, i32 1, i1 false) nounwind
+ %tmp = load i8* bitcast (void ()* @helper to i8*)
+ %x = icmp eq i8 %tmp, 15
+ ret void
+}
+
;;===----------------------------------------------------------------------===;;
;; Store -> Load and Load -> Load forwarding where src and dst are different
@@ -642,3 +651,28 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
+;;===----------------------------------------------------------------------===;;
+;; Load -> Store dependency which isn't interfered with by a call that happens
+;; before the pointer was captured.
+;;===----------------------------------------------------------------------===;;
+
+%class.X = type { [8 x i8] }
+
+@_ZTV1X = weak_odr constant [5 x i8*] zeroinitializer
+@_ZTV1Y = weak_odr constant [5 x i8*] zeroinitializer
+
+declare void @use()
+declare void @use3(i8***, i8**)
+
+; PR8908
+define void @test_escape1() nounwind {
+ %x = alloca i8**, align 8
+ store i8** getelementptr inbounds ([5 x i8*]* @_ZTV1X, i64 0, i64 2), i8*** %x, align 8
+ call void @use() nounwind
+ %DEAD = load i8*** %x, align 8
+ call void @use3(i8*** %x, i8** %DEAD) nounwind
+ ret void
+; CHECK: test_escape1
+; CHECK-NOT: DEAD
+; CHECK: ret
+}
diff --git a/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll b/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll
deleted file mode 100644
index 29864f8..0000000
--- a/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll
+++ /dev/null
@@ -1,264 +0,0 @@
-; RUN: opt < %s -globaldce | llc -O0 -o /dev/null
-
-%struct..0__pthread_mutex_s = type { i32, i32, i32, i32, i32, i32, %struct.__pthread_list_t }
-%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>" = type { i32 }
-%struct.__pthread_list_t = type { %struct.__pthread_list_t*, %struct.__pthread_list_t* }
-%struct.pthread_attr_t = type { i64, [48 x i8] }
-%struct.pthread_mutex_t = type { %struct..0__pthread_mutex_s }
-
-@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once ; <i32 (i32*, void ()*)*> [#uses=0]
-@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific ; <i8* (i32)*> [#uses=0]
-@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific ; <i32 (i32, i8*)*> [#uses=0]
-@_ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias weak i32 (i64*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)* @pthread_create ; <i32 (i64*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)*> [#uses=0]
-@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)* @pthread_cancel ; <i32 (i64)*> [#uses=0]
-@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_lock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
-@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_trylock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
-@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_unlock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
-@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%struct.pthread_mutex_t*, %"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)* @pthread_mutex_init ; <i32 (%struct.pthread_mutex_t*, %"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)*> [#uses=0]
-@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create ; <i32 (i32*, void (i8*)*)*> [#uses=0]
-@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete ; <i32 (i32)*> [#uses=0]
-@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)* @pthread_mutexattr_init ; <i32 (%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)*> [#uses=0]
-@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*, i32)* @pthread_mutexattr_settype ; <i32 (%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*, i32)*> [#uses=0]
-@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)* @pthread_mutexattr_destroy ; <i32 (%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)*> [#uses=0]
-
-define weak void @_ZN9__gnu_cxx26__aux_require_boolean_exprIbEEvRKT_(i8* %__t) {
-entry:
- tail call void @llvm.dbg.func.start(metadata !0)
- tail call void @llvm.dbg.stoppoint(i32 240, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !0)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_19_ConvertibleConceptIjjEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !8)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !8)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPcEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !11)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !11)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKcEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !12)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !12)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPwEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !13)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !13)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKwEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !14)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !14)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPwEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !15)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !15)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPcEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !16)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !16)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIiEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !17)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !17)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIlEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !18)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !18)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIxEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !19)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !19)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIjEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !20)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !20)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIcSt11char_traitsIcEEcEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !21)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !21)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIwSt11char_traitsIwEEwEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !22)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !22)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPcEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !23)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !23)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKcEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !24)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !24)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKcSsEEEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !25)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !25)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPcSsEEEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !26)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !26)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKwSbIwSt11char_traitsIwESaIwEEEEEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !27)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !27)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPwSbIwSt11char_traitsIwESaIwEEEEEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !28)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !28)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPwEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !29)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !29)
- ret void
-}
-
-define weak void @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKwEEEEvv() {
-entry:
- tail call void @llvm.dbg.func.start(metadata !30)
- tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
- tail call void @llvm.dbg.region.end(metadata !30)
- ret void
-}
-
-declare void @llvm.dbg.func.start(metadata) nounwind readnone
-
-declare void @llvm.dbg.stoppoint(i32, i32, metadata) nounwind readnone
-
-declare void @llvm.dbg.region.end(metadata) nounwind readnone
-
-declare extern_weak i32 @pthread_once(i32*, void ()*)
-
-declare extern_weak i8* @pthread_getspecific(i32)
-
-declare extern_weak i32 @pthread_setspecific(i32, i8*)
-
-declare extern_weak i32 @pthread_create(i64*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)
-
-declare extern_weak i32 @pthread_cancel(i64)
-
-declare extern_weak i32 @pthread_mutex_lock(%struct.pthread_mutex_t*)
-
-declare extern_weak i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*)
-
-declare extern_weak i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*)
-
-declare extern_weak i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)
-
-declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*)
-
-declare extern_weak i32 @pthread_key_delete(i32)
-
-declare extern_weak i32 @pthread_mutexattr_init(%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)
-
-declare extern_weak i32 @pthread_mutexattr_settype(%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*, i32)
-
-declare extern_weak i32 @pthread_mutexattr_destroy(%"struct.__gnu_cxx::_ConvertibleConcept<unsigned int,unsigned int>"*)
-
-!0 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__aux_require_boolean_expr<bool>", metadata !"__aux_require_boolean_expr<bool>", metadata !"_ZN9__gnu_cxx26__aux_require_boolean_exprIbEEvRKT_", metadata !2, i32 239, metadata !3, i1 false, i1 true}
-!1 = metadata !{i32 458769, i32 0, i32 4, metadata !"concept-inst.cc", metadata !"/home/buildbot/buildslave/llvm-x86_64-linux-selfhost/llvm-gcc.obj/x86_64-unknown-linux-gnu/libstdc++-v3/src/../../../../llvm-gcc.src/libstdc++-v3/src", metadata !"4.2.1 (Based on Apple Inc. build 5649) (LLVM build)", i1 true, i1 true, metadata !"", i32 0}
-!2 = metadata !{i32 458769, i32 0, i32 4, metadata !"boost_concept_check.h", metadata !"/home/buildbot/buildslave/llvm-x86_64-linux-selfhost/llvm-gcc.obj/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits", metadata !"4.2.1 (Based on Apple Inc. build 5649) (LLVM build)", i1 false, i1 true, metadata !"", i32 0}
-!3 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0}
-!4 = metadata !{null, metadata !5}
-!5 = metadata !{i32 458768, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !6}
-!6 = metadata !{i32 458790, metadata !1, metadata !"", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, metadata !7}
-!7 = metadata !{i32 458788, metadata !1, metadata !"bool", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2}
-!8 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_ConvertibleConcept<unsigned int, unsigned int> >", metadata !"__function_requires<__gnu_cxx::_ConvertibleConcept<unsigned int, unsigned int> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_19_ConvertibleConceptIjjEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!9 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !10, i32 0}
-!10 = metadata !{null}
-!11 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<char*> >", metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<char*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPcEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!12 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<const char*> >", metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<const char*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKcEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!13 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<wchar_t*> >", metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<wchar_t*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPwEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!14 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<const wchar_t*> >", metadata !"__function_requires<__gnu_cxx::_InputIteratorConcept<const wchar_t*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKwEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!15 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<wchar_t*> >", metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<wchar_t*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPwEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!16 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<char*> >", metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<char*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPcEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!17 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<int> >", metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<int> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIiEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!18 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<long int> >", metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<long int> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIlEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!19 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<long long int> >", metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<long long int> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIxEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!20 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<unsigned int> >", metadata !"__function_requires<__gnu_cxx::_LessThanComparableConcept<unsigned int> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIjEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!21 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_OutputIteratorConcept<std::ostreambuf_iterator<char, std::char_traits<char> >, char> >", metadata !"__function_requires<__gnu_cxx::_OutputIteratorConcept<std::ostreambuf_iterator<char, std::char_traits<char> >, char> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIcSt11char_traitsIcEEcEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!22 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_OutputIteratorConcept<std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> >, wchar_t> >", metadata !"__function_requires<__gnu_cxx::_OutputIteratorConcept<std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> >, wchar_t> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIwSt11char_traitsIwEEwEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!23 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<char*> >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<char*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPcEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!24 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<const char*> >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<const char*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKcEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!25 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKcSsEEEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!26 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPcSsEEEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!27 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<const wchar_t*, std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<const wchar_t*, std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKwSbIwSt11char_traitsIwESaIwEEEEEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!28 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<wchar_t*, std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator<wchar_t*, std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPwSbIwSt11char_traitsIwESaIwEEEEEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!29 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<wchar_t*> >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<wchar_t*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPwEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
-!30 = metadata !{i32 458798, i32 0, metadata !1, metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<const wchar_t*> >", metadata !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept<const wchar_t*> >", metadata !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKwEEEEvv", metadata !2, i32 61, metadata !9, i1 false, i1 true}
diff --git a/test/Transforms/GlobalDCE/dg.exp b/test/Transforms/GlobalDCE/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/GlobalDCE/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/GlobalDCE/lit.local.cfg b/test/Transforms/GlobalDCE/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/GlobalDCE/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll b/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
index a6803ab..588d5c9 100644
--- a/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
+++ b/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll
@@ -3,7 +3,7 @@
define double @foo() nounwind {
entry:
- %tmp1 = volatile load double* @t0.1441, align 8 ; <double> [#uses=2]
+ %tmp1 = load volatile double* @t0.1441, align 8 ; <double> [#uses=2]
%tmp4 = fmul double %tmp1, %tmp1 ; <double> [#uses=1]
ret double %tmp4
}
diff --git a/test/Transforms/GlobalOpt/2008-02-16-NestAttr.ll b/test/Transforms/GlobalOpt/2008-02-16-NestAttr.ll
deleted file mode 100644
index 0e70c49..0000000
--- a/test/Transforms/GlobalOpt/2008-02-16-NestAttr.ll
+++ /dev/null
@@ -1,57 +0,0 @@
-; RUN: opt < %s -globalopt -S | grep { nest } | count 1
- %struct.FRAME.nest = type { i32, i32 (i32)* }
- %struct.__builtin_trampoline = type { [10 x i8] }
-@.str = internal constant [7 x i8] c"%d %d\0A\00" ; <[7 x i8]*> [#uses=1]
-
-define i32 @process(i32 (i32)* %func) nounwind {
-entry:
- %tmp2 = tail call i32 %func( i32 1 ) nounwind ; <i32> [#uses=1]
- ret i32 %tmp2
-}
-
-define internal fastcc i32 @g.1478(%struct.FRAME.nest* nest %CHAIN.1, i32 %m) nounwind {
-entry:
- %tmp3 = getelementptr %struct.FRAME.nest* %CHAIN.1, i32 0, i32 0 ; <i32*> [#uses=1]
- %tmp4 = load i32* %tmp3, align 4 ; <i32> [#uses=1]
- %tmp7 = icmp eq i32 %tmp4, %m ; <i1> [#uses=1]
- %tmp78 = zext i1 %tmp7 to i32 ; <i32> [#uses=1]
- ret i32 %tmp78
-}
-
-define internal i32 @f.1481(%struct.FRAME.nest* nest %CHAIN.2, i32 %m) nounwind {
-entry:
- %tmp4 = tail call fastcc i32 @g.1478( %struct.FRAME.nest* nest %CHAIN.2, i32 %m ) nounwind ; <i32> [#uses=1]
- %tmp6 = getelementptr %struct.FRAME.nest* %CHAIN.2, i32 0, i32 0 ; <i32*> [#uses=1]
- %tmp7 = load i32* %tmp6, align 4 ; <i32> [#uses=1]
- %tmp9 = icmp eq i32 %tmp4, %tmp7 ; <i1> [#uses=1]
- %tmp910 = zext i1 %tmp9 to i32 ; <i32> [#uses=1]
- ret i32 %tmp910
-}
-
-define i32 @nest(i32 %n) nounwind {
-entry:
- %TRAMP.316 = alloca [10 x i8] ; <[10 x i8]*> [#uses=1]
- %FRAME.0 = alloca %struct.FRAME.nest ; <%struct.FRAME.nest*> [#uses=3]
- %TRAMP.316.sub = getelementptr [10 x i8]* %TRAMP.316, i32 0, i32 0 ; <i8*> [#uses=1]
- %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.316.sub, i8* bitcast (i32 (%struct.FRAME.nest*, i32)* @f.1481 to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
- %tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (i32)**> [#uses=1]
- %tmp89 = bitcast i8* %tramp to i32 (i32)* ; <i32 (i32)*> [#uses=2]
- store i32 (i32)* %tmp89, i32 (i32)** %tmp7, align 4
- %tmp13 = call i32 @process( i32 (i32)* %tmp89 ) nounwind ; <i32> [#uses=1]
- ret i32 %tmp13
-}
-
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind
-
-define i32 @main() nounwind {
-entry:
- %tmp = tail call i32 @nest( i32 2 ) nounwind ; <i32> [#uses=1]
- %tmp1 = tail call i32 @nest( i32 1 ) nounwind ; <i32> [#uses=1]
- %tmp3 = tail call i32 (i8*, ...)* @printf( i8* noalias getelementptr ([7 x i8]* @.str, i32 0, i32 0), i32 %tmp1, i32 %tmp ) nounwind ; <i32> [#uses=0]
- ret i32 undef
-}
-
-declare i32 @printf(i8*, ...) nounwind
diff --git a/test/Transforms/GlobalOpt/atomic.ll b/test/Transforms/GlobalOpt/atomic.ll
new file mode 100644
index 0000000..4c3f439
--- /dev/null
+++ b/test/Transforms/GlobalOpt/atomic.ll
@@ -0,0 +1,10 @@
+; RUN: opt -globalopt < %s -S -o - | FileCheck %s
+
+@GV1 = internal global i64 1
+; CHECK: @GV1 = internal unnamed_addr constant i64 1
+
+define void @test1() {
+entry:
+ %0 = load atomic i8* bitcast (i64* @GV1 to i8*) acquire, align 8
+ ret void
+}
diff --git a/test/Transforms/GlobalOpt/constantfold-initializers.ll b/test/Transforms/GlobalOpt/constantfold-initializers.ll
index 834bd00..af8fa32 100644
--- a/test/Transforms/GlobalOpt/constantfold-initializers.ll
+++ b/test/Transforms/GlobalOpt/constantfold-initializers.ll
@@ -6,3 +6,46 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; CHECK: @A = global i1 false
@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)
+
+; PR11352
+
+@xs = global [2 x i32] zeroinitializer, align 4
+; CHECK: @xs = global [2 x i32] [i32 1, i32 1]
+
+define internal void @test1() {
+entry:
+ store i32 1, i32* getelementptr inbounds ([2 x i32]* @xs, i64 0, i64 0)
+ %0 = load i32* getelementptr inbounds ([2 x i32]* @xs, i32 0, i64 0), align 4
+ store i32 %0, i32* getelementptr inbounds ([2 x i32]* @xs, i64 0, i64 1)
+ ret void
+}
+
+; PR12060
+
+%closure = type { i32 }
+
+@f = internal global %closure zeroinitializer, align 4
+@m = global i32 0, align 4
+; CHECK-NOT: @f
+; CHECK: @m = global i32 13
+
+define internal i32 @test2_helper(%closure* %this, i32 %b) {
+entry:
+ %0 = getelementptr inbounds %closure* %this, i32 0, i32 0
+ %1 = load i32* %0, align 4
+ %add = add nsw i32 %1, %b
+ ret i32 %add
+}
+
+define internal void @test2() {
+entry:
+ store i32 4, i32* getelementptr inbounds (%closure* @f, i32 0, i32 0)
+ %call = call i32 @test2_helper(%closure* @f, i32 9)
+ store i32 %call, i32* @m, align 4
+ ret void
+}
+
+@llvm.global_ctors = appending constant
+ [2 x { i32, void ()* }]
+ [{ i32, void ()* } { i32 65535, void ()* @test1 },
+ { i32, void ()* } { i32 65535, void ()* @test2 }]
diff --git a/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll b/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
index 204f979..e3bc473 100644
--- a/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
+++ b/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll
@@ -4,20 +4,31 @@ target triple = "x86_64-apple-darwin10.0.0"
%0 = type { i32, void ()* }
%struct.foo = type { i32* }
+%struct.bar = type { i128 }
@G = global i32 0, align 4
@H = global i32 0, align 4
@X = global %struct.foo zeroinitializer, align 8
-@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @init }]
+@X2 = global %struct.bar zeroinitializer, align 8
+@llvm.global_ctors = appending global [2 x %0] [%0 { i32 65535, void ()* @init1 }, %0 { i32 65535, void ()* @init2 }]
; PR8710 - GlobalOpt shouldn't change the global's initializer to have this
; arbitrary constant expression, the code generator can't handle it.
-define internal void @init() {
+define internal void @init1() {
entry:
%tmp = getelementptr inbounds %struct.foo* @X, i32 0, i32 0
store i32* inttoptr (i64 sdiv (i64 ptrtoint (i32* @G to i64), i64 ptrtoint (i32* @H to i64)) to i32*), i32** %tmp, align 8
ret void
}
-
-; CHECK: @init
+; CHECK: @init1
; CHECK: store i32*
+
+; PR11705 - ptrtoint isn't safe in general in global initializers.
+define internal void @init2() {
+entry:
+ %tmp = getelementptr inbounds %struct.bar* @X2, i32 0, i32 0
+ store i128 ptrtoint (i32* @G to i128), i128* %tmp, align 16
+ ret void
+}
+; CHECK: @init2
+; CHECK: store i128
diff --git a/test/Transforms/GlobalOpt/cxx-dtor.ll b/test/Transforms/GlobalOpt/cxx-dtor.ll
index 2263562..7c6ae78 100644
--- a/test/Transforms/GlobalOpt/cxx-dtor.ll
+++ b/test/Transforms/GlobalOpt/cxx-dtor.ll
@@ -2,6 +2,7 @@
%0 = type { i32, void ()* }
%struct.A = type { i8 }
+%struct.B = type { }
@a = global %struct.A zeroinitializer, align 1
@__dso_handle = external global i8*
@@ -15,13 +16,14 @@ define internal void @__cxx_global_var_init() nounwind section "__TEXT,__StaticI
}
define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 {
- call void @_ZN1AD2Ev(%struct.A* %this)
+ %t = bitcast %struct.A* %this to %struct.B*
+ call void @_ZN1BD1Ev(%struct.B* %t)
ret void
}
declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
-define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 {
+define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) nounwind align 2 {
ret void
}
diff --git a/test/Transforms/GlobalOpt/deadfunction.ll b/test/Transforms/GlobalOpt/deadfunction.ll
new file mode 100644
index 0000000..5e003c6
--- /dev/null
+++ b/test/Transforms/GlobalOpt/deadfunction.ll
@@ -0,0 +1,27 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; CHECK-NOT: test
+
+declare void @aa()
+declare void @bb()
+
+; Test that we can erase a function which has a blockaddress referring to it
+@test.x = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@test, %a), i8* blockaddress(@test, %b), i8* blockaddress(@test, %c)], align 16
+define internal void @test(i32 %n) nounwind noinline {
+entry:
+ %idxprom = sext i32 %n to i64
+ %arrayidx = getelementptr inbounds [3 x i8*]* @test.x, i64 0, i64 %idxprom
+ %0 = load i8** %arrayidx, align 8
+ indirectbr i8* %0, [label %a, label %b, label %c]
+
+a:
+ tail call void @aa() nounwind
+ br label %b
+
+b:
+ tail call void @bb() nounwind
+ br label %c
+
+c:
+ ret void
+}
diff --git a/test/Transforms/GlobalOpt/dg.exp b/test/Transforms/GlobalOpt/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/GlobalOpt/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/GlobalOpt/invariant.ll b/test/Transforms/GlobalOpt/invariant.ll
new file mode 100644
index 0000000..6b99193
--- /dev/null
+++ b/test/Transforms/GlobalOpt/invariant.ll
@@ -0,0 +1,59 @@
+; RUN: opt -globalopt -S -o - < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare {}* @llvm.invariant.start(i64 %size, i8* nocapture %ptr)
+
+define void @test1(i8* %ptr) {
+ call {}* @llvm.invariant.start(i64 4, i8* %ptr)
+ ret void
+}
+
+@object1 = global i32 0
+; CHECK: @object1 = constant i32 -1
+define void @ctor1() {
+ store i32 -1, i32* @object1
+ %A = bitcast i32* @object1 to i8*
+ call void @test1(i8* %A)
+ ret void
+}
+
+
+@object2 = global i32 0
+; CHECK: @object2 = global i32 0
+define void @ctor2() {
+ store i32 -1, i32* @object2
+ %A = bitcast i32* @object2 to i8*
+ %B = call {}* @llvm.invariant.start(i64 4, i8* %A)
+ %C = bitcast {}* %B to i8*
+ ret void
+}
+
+
+@object3 = global i32 0
+; CHECK: @object3 = global i32 -1
+define void @ctor3() {
+ store i32 -1, i32* @object3
+ %A = bitcast i32* @object3 to i8*
+ call {}* @llvm.invariant.start(i64 3, i8* %A)
+ ret void
+}
+
+
+@object4 = global i32 0
+; CHECK: @object4 = global i32 -1
+define void @ctor4() {
+ store i32 -1, i32* @object4
+ %A = bitcast i32* @object4 to i8*
+ call {}* @llvm.invariant.start(i64 -1, i8* %A)
+ ret void
+}
+
+
+@llvm.global_ctors = appending constant
+ [4 x { i32, void ()* }]
+ [ { i32, void ()* } { i32 65535, void ()* @ctor1 },
+ { i32, void ()* } { i32 65535, void ()* @ctor2 },
+ { i32, void ()* } { i32 65535, void ()* @ctor3 },
+ { i32, void ()* } { i32 65535, void ()* @ctor4 } ]
diff --git a/test/Transforms/GlobalOpt/invoke.ll b/test/Transforms/GlobalOpt/invoke.ll
new file mode 100644
index 0000000..c1f499c
--- /dev/null
+++ b/test/Transforms/GlobalOpt/invoke.ll
@@ -0,0 +1,27 @@
+; RUN: opt -S -globalopt < %s | FileCheck %s
+; rdar://11022897
+
+; Globalopt should be able to evaluate an invoke.
+; CHECK: @tmp = global i32 1
+
+@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+@tmp = global i32 0
+
+define i32 @one() {
+ ret i32 1
+}
+
+define void @_GLOBAL__I_a() {
+bb:
+ %tmp1 = invoke i32 @one()
+ to label %bb2 unwind label %bb4
+
+bb2: ; preds = %bb
+ store i32 %tmp1, i32* @tmp
+ ret void
+
+bb4: ; preds = %bb
+ %tmp5 = landingpad { i8*, i32 } personality i8* undef
+ filter [0 x i8*] zeroinitializer
+ unreachable
+}
diff --git a/test/Transforms/GlobalOpt/lit.local.cfg b/test/Transforms/GlobalOpt/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/GlobalOpt/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll b/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll
new file mode 100644
index 0000000..d613601
--- /dev/null
+++ b/test/Transforms/GlobalOpt/zeroinitializer-gep-load.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+
+@zero = internal global [10 x i32] zeroinitializer
+
+define i32 @test1(i64 %idx) nounwind {
+ %arrayidx = getelementptr inbounds [10 x i32]* @zero, i64 0, i64 %idx
+ %l = load i32* %arrayidx
+ ret i32 %l
+; CHECK: @test1
+; CHECK: ret i32 0
+}
diff --git a/test/Transforms/IPConstantProp/dangling-block-address.ll b/test/Transforms/IPConstantProp/dangling-block-address.ll
index 0489dfa..bb101333 100644
--- a/test/Transforms/IPConstantProp/dangling-block-address.ll
+++ b/test/Transforms/IPConstantProp/dangling-block-address.ll
@@ -12,7 +12,7 @@
define void @foo(i32 %x) nounwind readnone {
entry:
%b = alloca i32, align 4 ; <i32*> [#uses=1]
- volatile store i32 -1, i32* %b
+ store volatile i32 -1, i32* %b
ret void
}
diff --git a/test/Transforms/IPConstantProp/dg.exp b/test/Transforms/IPConstantProp/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/IPConstantProp/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/IPConstantProp/lit.local.cfg b/test/Transforms/IPConstantProp/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/IPConstantProp/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll b/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
index 77354f7..af9f1b3 100644
--- a/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
+++ b/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
+; RUN: opt < %s -indvars -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.
@@ -19,7 +19,7 @@ for.body153: ; preds = %for.body153, %for.b
; CHECK: add nsw i64 %indvars.iv, 1
for.body170: ; preds = %for.body170, %for.body153
- %i2.19 = phi i32 [ %add249, %for.body170 ], [ undef, %for.body153 ]
+ %i2.19 = phi i32 [ %add249, %for.body170 ], [ 0, %for.body153 ]
%add219 = add nsw i32 %i2.19, 1
%idxprom220 = sext i32 %add219 to i64
%add249 = add nsw i32 %i2.19, %shl132
diff --git a/test/Transforms/IndVarSimplify/2011-10-27-lftrnull.ll b/test/Transforms/IndVarSimplify/2011-10-27-lftrnull.ll
new file mode 100644
index 0000000..76c90e0
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-10-27-lftrnull.ll
@@ -0,0 +1,59 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+; rdar://10359193: assert "IndVar type must match IVInit type"
+
+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-darwin"
+
+; CHECK: @test
+; CHECK: if.end.i126:
+; CHECK: %exitcond = icmp ne i8* %incdec.ptr.i, getelementptr (i8* null, i32 undef)
+define void @test() nounwind {
+entry:
+ br label %while.cond
+
+while.cond:
+ br i1 undef, label %while.end, label %while.body
+
+while.body: ; preds = %while.cond
+ br i1 undef, label %if.then165, label %while.cond
+
+if.then165: ; preds = %while.body
+ br i1 undef, label %while.cond, label %for.body.lr.ph.i81
+
+for.body.lr.ph.i81: ; preds = %if.then165
+ br label %for.body.i86
+
+for.body.i86: ; preds = %for.end.i129, %for.body.lr.ph.i81
+ %cmp196.i = icmp ult i32 0, undef
+ br i1 %cmp196.i, label %for.body21.lr.ph.i, label %for.end.i129
+
+for.body21.lr.ph.i: ; preds = %for.body.i86
+ br label %for.body21.i
+
+for.body21.i:
+ %destYPixelPtr.010.i = phi i8* [ null, %for.body21.lr.ph.i ], [ %incdec.ptr.i, %if.end.i126 ]
+ %x.09.i = phi i32 [ 0, %for.body21.lr.ph.i ], [ %inc.i125, %if.end.i126 ]
+ br i1 undef, label %if.end.i126, label %if.else.i124
+
+if.else.i124: ; preds = %for.body21.i
+ store i8 undef, i8* %destYPixelPtr.010.i, align 1
+ br label %if.end.i126
+
+if.end.i126: ; preds = %if.else.i124, %for.body21.i
+ %incdec.ptr.i = getelementptr inbounds i8* %destYPixelPtr.010.i, i32 1
+ %inc.i125 = add i32 %x.09.i, 1
+ %cmp19.i = icmp ult i32 %inc.i125, undef
+ br i1 %cmp19.i, label %for.body21.i, label %for.end.i129
+
+for.end.i129: ; preds = %if.end.i126, %for.body.i86
+ br i1 undef, label %for.body.i86, label %while.cond
+
+while.end: ; preds = %while.cond
+ br label %bail
+
+bail: ; preds = %while.end, %lor.lhs.false44, %lor.lhs.false41, %if.end29, %if.end
+ unreachable
+
+return: ; preds = %lor.lhs.false20, %lor.lhs.false12, %lor.lhs.false, %entry
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll b/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll
new file mode 100644
index 0000000..c0c508f
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll
@@ -0,0 +1,140 @@
+; RUN: opt < %s -indvars -S "-default-data-layout=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" | FileCheck %s
+; RUN: opt < %s -indvars -S "-default-data-layout=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" | FileCheck %s
+;
+; PR11279: Assertion !IVLimit->getType()->isPointerTy()
+;
+; Test LinearFunctionTestReplace of a pointer-type loop counter. Note
+; that BECount may or may not be a pointer type. A pointer type
+; BECount doesn't really make sense, but that's what falls out of
+; SCEV. Since it's an i8*, it has unit stride so we never adjust the
+; SCEV expression in a way that would convert it to an integer type.
+
+; CHECK: @testnullptrptr
+; CHECK: loop:
+; CHECK: icmp ne
+define i8 @testnullptrptr(i8* %buf, i8* %end) nounwind {
+ br label %loopguard
+
+loopguard:
+ %guard = icmp ult i8* null, %end
+ br i1 %guard, label %preheader, label %exit
+
+preheader:
+ br label %loop
+
+loop:
+ %p.01.us.us = phi i8* [ null, %preheader ], [ %gep, %loop ]
+ %s = phi i8 [0, %preheader], [%snext, %loop]
+ %gep = getelementptr inbounds i8* %p.01.us.us, i64 1
+ %snext = load i8* %gep
+ %cmp = icmp ult i8* %gep, %end
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret i8 %snext
+}
+
+; CHECK: @testptrptr
+; CHECK: loop:
+; CHECK: icmp ne
+define i8 @testptrptr(i8* %buf, i8* %end) nounwind {
+ br label %loopguard
+
+loopguard:
+ %guard = icmp ult i8* %buf, %end
+ br i1 %guard, label %preheader, label %exit
+
+preheader:
+ br label %loop
+
+loop:
+ %p.01.us.us = phi i8* [ %buf, %preheader ], [ %gep, %loop ]
+ %s = phi i8 [0, %preheader], [%snext, %loop]
+ %gep = getelementptr inbounds i8* %p.01.us.us, i64 1
+ %snext = load i8* %gep
+ %cmp = icmp ult i8* %gep, %end
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret i8 %snext
+}
+
+; CHECK: @testnullptrint
+; CHECK: loop:
+; CHECK: icmp ne
+define i8 @testnullptrint(i8* %buf, i8* %end) nounwind {
+ br label %loopguard
+
+loopguard:
+ %bi = ptrtoint i8* %buf to i32
+ %ei = ptrtoint i8* %end to i32
+ %cnt = sub i32 %ei, %bi
+ %guard = icmp ult i32 0, %cnt
+ br i1 %guard, label %preheader, label %exit
+
+preheader:
+ br label %loop
+
+loop:
+ %p.01.us.us = phi i8* [ null, %preheader ], [ %gep, %loop ]
+ %iv = phi i32 [ 0, %preheader ], [ %ivnext, %loop ]
+ %s = phi i8 [0, %preheader], [%snext, %loop]
+ %gep = getelementptr inbounds i8* %p.01.us.us, i64 1
+ %snext = load i8* %gep
+ %ivnext = add i32 %iv, 1
+ %cmp = icmp ult i32 %ivnext, %cnt
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret i8 %snext
+}
+
+; CHECK: @testptrint
+; CHECK: loop:
+; CHECK: icmp ne
+define i8 @testptrint(i8* %buf, i8* %end) nounwind {
+ br label %loopguard
+
+loopguard:
+ %bi = ptrtoint i8* %buf to i32
+ %ei = ptrtoint i8* %end to i32
+ %cnt = sub i32 %ei, %bi
+ %guard = icmp ult i32 %bi, %cnt
+ br i1 %guard, label %preheader, label %exit
+
+preheader:
+ br label %loop
+
+loop:
+ %p.01.us.us = phi i8* [ %buf, %preheader ], [ %gep, %loop ]
+ %iv = phi i32 [ %bi, %preheader ], [ %ivnext, %loop ]
+ %s = phi i8 [0, %preheader], [%snext, %loop]
+ %gep = getelementptr inbounds i8* %p.01.us.us, i64 1
+ %snext = load i8* %gep
+ %ivnext = add i32 %iv, 1
+ %cmp = icmp ult i32 %ivnext, %cnt
+ br i1 %cmp, label %loop, label %exit
+
+exit:
+ ret i8 %snext
+}
+
+; IV and BECount have two different pointer types here.
+define void @testnullptr([512 x i8]* %base) nounwind {
+entry:
+ %add.ptr1603 = getelementptr [512 x i8]* %base, i64 0, i64 512
+ br label %preheader
+
+preheader:
+ %cmp1604192 = icmp ult i8* undef, %add.ptr1603
+ br i1 %cmp1604192, label %for.body, label %for.end1609
+
+for.body:
+ %r.17193 = phi i8* [ %incdec.ptr1608, %for.body ], [ null, %preheader ]
+ %incdec.ptr1608 = getelementptr i8* %r.17193, i64 1
+ %cmp1604 = icmp ult i8* %incdec.ptr1608, %add.ptr1603
+ br i1 %cmp1604, label %for.body, label %for.end1609
+
+for.end1609:
+ unreachable
+}
diff --git a/test/Transforms/IndVarSimplify/2011-11-15-multiexit.ll b/test/Transforms/IndVarSimplify/2011-11-15-multiexit.ll
new file mode 100644
index 0000000..c74d04e
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-11-15-multiexit.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+;
+; Prior to the fix for PR11375, indvars would replace %firstIV with a
+; loop-invariant gep computed in the preheader. This was incorrect
+; because it was based on the minimum "ExitNotTaken" count. If the
+; final loop test is skipped (odd number of elements) then the early
+; exit would be taken and the loop invariant value would be incorrect.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-darwin"
+
+; CHECK: if.end:
+; CHECK: phi i32* [ %first.lcssa, %early.exit ]
+define i32 @test(i32* %first, i32* %last) uwtable ssp {
+entry:
+ br i1 undef, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ br i1 undef, label %if.end, label %do.body
+
+do.body: ; preds = %if.else, %if.then
+ %firstIV = phi i32* [ %incdec.ptr2, %if.else ], [ %first, %if.then ]
+ %incdec.ptr1 = getelementptr inbounds i32* %firstIV, i64 1
+ %cmp1 = icmp eq i32* %incdec.ptr1, %last
+ br i1 %cmp1, label %early.exit, label %if.else
+
+if.else: ; preds = %do.body
+ %incdec.ptr2 = getelementptr inbounds i32* %firstIV, i64 2
+ %cmp2 = icmp eq i32* %incdec.ptr2, %last
+ br i1 %cmp2, label %if.end, label %do.body
+
+early.exit:
+ %first.lcssa = phi i32* [ %firstIV, %do.body ]
+ br label %if.end
+
+if.end:
+ %tmp = phi i32* [ %first.lcssa, %early.exit ], [ %first, %if.then ], [ %first, %entry ], [ undef, %if.else ]
+ %val = load i32* %tmp
+ ret i32 %val
+}
diff --git a/test/Transforms/IndVarSimplify/2011-11-17-selfphi.ll b/test/Transforms/IndVarSimplify/2011-11-17-selfphi.ll
new file mode 100644
index 0000000..ccf2595
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/2011-11-17-selfphi.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+; PR11350: Check that SimplifyIndvar handles a cycle of useless self-phis.
+
+; CHECK: @test
+; CHECK-NOT: lcssa = phi
+define void @test() nounwind {
+entry:
+ br label %for.cond.preheader
+
+for.cond.preheader: ; preds = %entry
+ br label %for.cond.outer
+
+for.cond.outer: ; preds = %for.cond.preheader, %for.end
+ %p_41.addr.0.ph = phi i32 [ %p_41.addr.1.lcssa, %for.end ], [ 1, %for.cond.preheader ]
+ br label %for.cond
+
+for.cond:
+ br i1 true, label %for.end, label %for.ph
+
+for.ph: ; preds = %for.cond4.preheader
+ br label %for.end
+
+for.end:
+ %p_41.addr.1.lcssa = phi i32 [ undef, %for.ph ], [ %p_41.addr.0.ph, %for.cond ]
+ %p_68.lobit.i = lshr i32 %p_41.addr.1.lcssa, 31
+ %cmp7 = icmp eq i32 %p_41.addr.1.lcssa, 0
+ %conv8 = zext i1 %cmp7 to i32
+ br label %for.cond.outer
+}
diff --git a/test/Transforms/IndVarSimplify/ada-loops.ll b/test/Transforms/IndVarSimplify/ada-loops.ll
index 154de6f..c093298 100644
--- a/test/Transforms/IndVarSimplify/ada-loops.ll
+++ b/test/Transforms/IndVarSimplify/ada-loops.ll
@@ -1,5 +1,4 @@
; RUN: opt < %s -indvars -S | FileCheck %s
-; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
;
; PR1301
diff --git a/test/Transforms/IndVarSimplify/avoid-i0.ll b/test/Transforms/IndVarSimplify/avoid-i0.ll
index 59661fa..22f2e4b 100644
--- a/test/Transforms/IndVarSimplify/avoid-i0.ll
+++ b/test/Transforms/IndVarSimplify/avoid-i0.ll
@@ -90,7 +90,7 @@ entry:
br label %bb4
bb: ; preds = %bb4
- %0 = volatile load i32* @x, align 4 ; <i32> [#uses=1]
+ %0 = load volatile i32* @x, align 4 ; <i32> [#uses=1]
store i32 %0, i32* %vol.0, align 4
store i32 0, i32* %l_52, align 4
br label %bb2
diff --git a/test/Transforms/IndVarSimplify/complex-scev.ll b/test/Transforms/IndVarSimplify/complex-scev.ll
deleted file mode 100644
index 395377e..0000000
--- a/test/Transforms/IndVarSimplify/complex-scev.ll
+++ /dev/null
@@ -1,31 +0,0 @@
-; 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 -enable-iv-rewrite | FileCheck %s
-; CHECK: phi
-; CHECK-NOT: phi
-
-define void @foo() {
-entry:
- br label %bb6
-
-bb6: ; preds = %cond_true, %entry
- %j.0 = phi i32 [ 1, %entry ], [ %tmp5, %cond_true ] ; <i32> [#uses=3]
- %i.0 = phi i32 [ 0, %entry ], [ %j.0, %cond_true ] ; <i32> [#uses=1]
- %tmp7 = call i32 (...)* @foo2( ) ; <i32> [#uses=1]
- %tmp = icmp ne i32 %tmp7, 0 ; <i1> [#uses=1]
- br i1 %tmp, label %cond_true, label %return
-
-cond_true: ; preds = %bb6
- %tmp2 = call i32 (...)* @bar( i32 %i.0, i32 %j.0 ) ; <i32> [#uses=0]
- %tmp5 = add i32 %j.0, 1 ; <i32> [#uses=1]
- br label %bb6
-
-return: ; preds = %bb6
- ret void
-}
-
-declare i32 @bar(...)
-
-declare i32 @foo2(...)
-
diff --git a/test/Transforms/IndVarSimplify/dg.exp b/test/Transforms/IndVarSimplify/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/IndVarSimplify/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/IndVarSimplify/elim-extend.ll b/test/Transforms/IndVarSimplify/elim-extend.ll
index 43c162f..ad5679f 100644
--- a/test/Transforms/IndVarSimplify/elim-extend.ll
+++ b/test/Transforms/IndVarSimplify/elim-extend.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
+; RUN: opt < %s -indvars -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/gep-with-mul-base.ll b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
deleted file mode 100644
index 7e1e2a3..0000000
--- a/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
+++ /dev/null
@@ -1,68 +0,0 @@
-; 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:
- %tmp = icmp sgt i64 %n, 0 ; <i1> [#uses=1]
- br i1 %tmp, label %bb.nph, label %return
-
-bb.nph: ; preds = %entry
- %tmp1 = mul i64 %n, 37 ; <i64> [#uses=1]
- %tmp2 = mul i64 %tmp1, %m ; <i64> [#uses=1]
- %tmp3 = mul i64 %tmp2, %o ; <i64> [#uses=1]
- br label %bb
-
-bb: ; preds = %bb, %bb.nph
- %i.01 = phi i64 [ %tmp3, %bb.nph ], [ %tmp13, %bb ] ; <i64> [#uses=3]
- %tmp9 = getelementptr double* %p, i64 %i.01 ; <double*> [#uses=1]
- %tmp10 = load double* %tmp9, align 8 ; <double> [#uses=1]
- %tmp11 = fdiv double %tmp10, 2.100000e+00 ; <double> [#uses=1]
- store double %tmp11, double* %tmp9, align 8
- %tmp13 = add i64 %i.01, 1 ; <i64> [#uses=2]
- %tmp14 = icmp slt i64 %tmp13, %n ; <i1> [#uses=1]
- br i1 %tmp14, label %bb, label %return.loopexit
-
-return.loopexit: ; preds = %bb
- br label %return
-
-return: ; preds = %return.loopexit, %entry
- ret void
-}
-define void @bar(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind {
-entry:
- %tmp = icmp sgt i64 %n, 0 ; <i1> [#uses=1]
- br i1 %tmp, label %bb.nph, label %return
-
-bb.nph: ; preds = %entry
- %tmp1 = mul i64 %n, %q ; <i64> [#uses=1]
- %tmp2 = mul i64 %tmp1, %m ; <i64> [#uses=1]
- %tmp3 = mul i64 %tmp2, %o ; <i64> [#uses=1]
- br label %bb
-
-bb: ; preds = %bb, %bb.nph
- %i.01 = phi i64 [ %tmp3, %bb.nph ], [ %tmp13, %bb ] ; <i64> [#uses=3]
- %tmp9 = getelementptr double* %p, i64 %i.01 ; <double*> [#uses=1]
- %tmp10 = load double* %tmp9, align 8 ; <double> [#uses=1]
- %tmp11 = fdiv double %tmp10, 2.100000e+00 ; <double> [#uses=1]
- store double %tmp11, double* %tmp9, align 8
- %tmp13 = add i64 %i.01, 1 ; <i64> [#uses=2]
- %tmp14 = icmp slt i64 %tmp13, %n ; <i1> [#uses=1]
- br i1 %tmp14, label %bb, label %return.loopexit
-
-return.loopexit: ; preds = %bb
- br label %return
-
-return: ; preds = %return.loopexit, %entry
- ret void
-}
diff --git a/test/Transforms/IndVarSimplify/iv-fold.ll b/test/Transforms/IndVarSimplify/iv-fold.ll
index 2e19118..e0b05cd 100644
--- a/test/Transforms/IndVarSimplify/iv-fold.ll
+++ b/test/Transforms/IndVarSimplify/iv-fold.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
+; RUN: opt < %s -indvars -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"
diff --git a/test/Transforms/IndVarSimplify/iv-zext.ll b/test/Transforms/IndVarSimplify/iv-zext.ll
index 646e6c0..2e0f70c 100644
--- a/test/Transforms/IndVarSimplify/iv-zext.ll
+++ b/test/Transforms/IndVarSimplify/iv-zext.ll
@@ -1,5 +1,4 @@
; RUN: opt < %s -indvars -S | FileCheck %s
-; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
; CHECK-NOT: and
; CHECK-NOT: zext
diff --git a/test/Transforms/IndVarSimplify/lftr-reuse.ll b/test/Transforms/IndVarSimplify/lftr-reuse.ll
index 490eee9..9abfe13 100644
--- a/test/Transforms/IndVarSimplify/lftr-reuse.ll
+++ b/test/Transforms/IndVarSimplify/lftr-reuse.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -enable-iv-rewrite=false -S | FileCheck %s
+; RUN: opt < %s -indvars -S | FileCheck %s
;
; Make sure that indvars can perform LFTR without a canonical IV.
diff --git a/test/Transforms/IndVarSimplify/lit.local.cfg b/test/Transforms/IndVarSimplify/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/IndVarSimplify/loop_evaluate10.ll b/test/Transforms/IndVarSimplify/loop_evaluate10.ll
index 269478a..c3619f6 100644
--- a/test/Transforms/IndVarSimplify/loop_evaluate10.ll
+++ b/test/Transforms/IndVarSimplify/loop_evaluate10.ll
@@ -1,8 +1,14 @@
; RUN: opt < %s -indvars -S \
; RUN: | grep {%b.1 = phi i32 \\\[ 2, %bb \\\], \\\[ 1, %bb2 \\\]}
-
+;
; This loop has multiple exits, and the value of %b1 depends on which
; exit is taken. Indvars should correctly compute the exit values.
+;
+; XFAIL: *
+; Indvars does not currently replace loop invariant values unless all
+; loop exits have the same exit value. We could handle some cases,
+; such as this, by making getSCEVAtScope() sensitive to a particular
+; loop exit. See PR11388.
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-pc-linux-gnu"
diff --git a/test/Transforms/IndVarSimplify/loop_evaluate9.ll b/test/Transforms/IndVarSimplify/loop_evaluate9.ll
index 8184a73..9f3bcaf 100644
--- a/test/Transforms/IndVarSimplify/loop_evaluate9.ll
+++ b/test/Transforms/IndVarSimplify/loop_evaluate9.ll
@@ -2,8 +2,13 @@
; RUN: grep {\[%\]tmp7 = icmp eq i8 -28, -28} %t
; RUN: grep {\[%\]tmp8 = icmp eq i8 63, 63} %t
; PR4477
-
; Indvars should compute the exit values in loop.
+;
+; XFAIL: *
+; Indvars does not currently replace loop invariant values unless all
+; loop exits have the same exit value. We could handle some cases,
+; such as this, by making getSCEVAtScope() sensitive to a particular
+; loop exit. See PR11388.
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:32:32"
target triple = "i386-pc-linux-gnu"
diff --git a/test/Transforms/IndVarSimplify/no-iv-rewrite.ll b/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
index 9c2abd0..bfdd000 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 -enable-iv-rewrite=false -S | FileCheck %s
+; RUN: opt < %s -indvars -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.
@@ -333,9 +333,9 @@ entry:
; CHECK: loop:
; CHECK: phi %structIF*
-; CHECK: phi i32*
-; CHECK: getelementptr inbounds
+; CHECK-NOT: phi
; CHECK: getelementptr inbounds
+; CHECK-NOT: getelementptr
; CHECK: exit:
loop:
%ptr.iv = phi %structIF* [ %ptr.inc, %latch ], [ %base, %entry ]
diff --git a/test/Transforms/IndVarSimplify/preserve-gep-nested.ll b/test/Transforms/IndVarSimplify/preserve-gep-nested.ll
deleted file mode 100644
index cdcaaa0..0000000
--- a/test/Transforms/IndVarSimplify/preserve-gep-nested.ll
+++ /dev/null
@@ -1,76 +0,0 @@
-; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
-; No explicit integer multiplications!
-; No i8* arithmetic or pointer casting anywhere!
-; 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-n32:64"
-
-%struct.Q = type { [10 x %struct.N] }
-%struct.N = type { %struct.S }
-%struct.S = type { [100 x double], [100 x double] }
-
-define void @foo(%struct.Q* %s, i64 %n) nounwind {
-entry:
- br label %bb1
-
-bb1:
- %i = phi i64 [ 2, %entry ], [ %i.next, %bb ]
- %j = phi i64 [ 0, %entry ], [ %j.next, %bb ]
- %t5 = icmp slt i64 %i, %n
- br i1 %t5, label %bb, label %return
-
-bb:
- %t0 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 0, i32 0, i32 0, i64 %i
- %t1 = load double* %t0, align 8
- %t2 = fmul double %t1, 3.200000e+00
- %t3 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 0, i32 0, i32 0, i64 %i
- store double %t2, double* %t3, align 8
-
- %s0 = getelementptr inbounds %struct.Q* %s, i64 13, i32 0, i64 7, i32 0, i32 1, i64 %i
- %s1 = load double* %s0, align 8
- %s2 = fmul double %s1, 3.200000e+00
- %s3 = getelementptr inbounds %struct.Q* %s, i64 13, i32 0, i64 7, i32 0, i32 1, i64 %i
- store double %s2, double* %s3, align 8
-
- %u0 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 7, i32 0, i32 1, i64 %j
- %u1 = load double* %u0, align 8
- %u2 = fmul double %u1, 3.200000e+00
- %u3 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 7, i32 0, i32 1, i64 %j
- store double %u2, double* %u3, align 8
-
- %v0 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 0, i32 0, i32 1, i64 %i
- %v1 = load double* %v0, align 8
- %v2 = fmul double %v1, 3.200000e+00
- %v3 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 0, i32 0, i32 1, i64 %i
- store double %v2, double* %v3, align 8
-
- %w0 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 0, i32 0, i32 0, i64 %j
- %w1 = load double* %w0, align 8
- %w2 = fmul double %w1, 3.200000e+00
- %w3 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 0, i32 0, i32 0, i64 %j
- store double %w2, double* %w3, align 8
-
- %x0 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 3, i32 0, i32 0, i64 %i
- %x1 = load double* %x0, align 8
- %x2 = fmul double %x1, 3.200000e+00
- %x3 = getelementptr inbounds %struct.Q* %s, i64 0, i32 0, i64 3, i32 0, i32 0, i64 %i
- store double %x2, double* %x3, align 8
-
- %i.next = add i64 %i, 1
- %j.next = add i64 %j, 1
- br label %bb1
-
-return:
- ret void
-}
diff --git a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll
deleted file mode 100644
index 2f3100f..0000000
--- a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; 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
-; or something. That's valid, but more obscure.
-
-define void @foo([3 x [3 x double]]* noalias %p) nounwind {
-entry:
- br label %loop
-
-loop:
- %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
- %ip = add i64 %i, 1
- %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 2, i64 %ip, i64 1
- volatile store double 0.0, double* %p.2.ip.1
- %i.next = add i64 %i, 1
- br label %loop
-}
diff --git a/test/Transforms/IndVarSimplify/preserve-gep.ll b/test/Transforms/IndVarSimplify/preserve-gep.ll
deleted file mode 100644
index fec8a28..0000000
--- a/test/Transforms/IndVarSimplify/preserve-gep.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; 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-n32:64"
-target triple = "x86_64-unknown-linux-gnu"
- %struct.Foo = type { i32, i32, [10 x i32], i32 }
-
-define void @me(%struct.Foo* nocapture %Bar) nounwind {
-entry:
- br i1 false, label %return, label %bb.nph
-
-bb.nph: ; preds = %entry
- br label %bb
-
-bb: ; preds = %bb1, %bb.nph
- %i.01 = phi i64 [ %4, %bb1 ], [ 0, %bb.nph ] ; <i64> [#uses=3]
- %0 = getelementptr %struct.Foo* %Bar, i64 %i.01, i32 2, i64 3 ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- %2 = mul i32 %1, 113 ; <i32> [#uses=1]
- %3 = getelementptr %struct.Foo* %Bar, i64 %i.01, i32 2, i64 3 ; <i32*> [#uses=1]
- store i32 %2, i32* %3, align 4
- %4 = add i64 %i.01, 1 ; <i64> [#uses=2]
- br label %bb1
-
-bb1: ; preds = %bb
- %phitmp = icmp sgt i64 %4, 19999 ; <i1> [#uses=1]
- br i1 %phitmp, 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-signed-wrap.ll b/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll
index 22e2092..f619e8d 100644
--- a/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll
+++ b/test/Transforms/IndVarSimplify/preserve-signed-wrap.ll
@@ -1,5 +1,4 @@
; RUN: opt < %s -indvars -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/sink-alloca.ll b/test/Transforms/IndVarSimplify/sink-alloca.ll
index 3a6c683..64207d8 100644
--- a/test/Transforms/IndVarSimplify/sink-alloca.ll
+++ b/test/Transforms/IndVarSimplify/sink-alloca.ll
@@ -1,15 +1,10 @@
; RUN: opt < %s -indvars -S | FileCheck %s
-; PR4775
-
-; Indvars shouldn't sink the alloca out of the entry block, even though
-; it's not used until after the loop.
-
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-darwin10.0"
-@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @main to i8*)],
-section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
-
+; PR4775
+; Indvars shouldn't sink the alloca out of the entry block, even though
+; it's not used until after the loop.
define i32 @main() nounwind {
; CHECK: entry:
; CHECK-NEXT: %result.i = alloca i32, align 4
@@ -23,9 +18,39 @@ while.cond: ; preds = %while.cond, %entry
br i1 %tobool, label %while.end, label %while.cond
while.end: ; preds = %while.cond
- volatile store i32 0, i32* %result.i
- %tmp.i = volatile load i32* %result.i ; <i32> [#uses=0]
+ store volatile i32 0, i32* %result.i
+ %tmp.i = load volatile i32* %result.i ; <i32> [#uses=0]
ret i32 0
}
-
declare i32 @bar()
+
+; <rdar://problem/10352360>
+; Indvars shouldn't sink the first alloca between the stacksave and stackrestore
+; intrinsics.
+declare i8* @a(...)
+declare i8* @llvm.stacksave() nounwind
+declare void @llvm.stackrestore(i8*) nounwind
+define void @h(i64 %n) nounwind uwtable ssp {
+; CHECK: entry:
+; CHECK-NEXT: %vla = alloca i8*
+; CHECK-NEXT: %savedstack = call i8* @llvm.stacksave()
+entry:
+ %vla = alloca i8*, i64 %n, align 16
+ %savedstack = call i8* @llvm.stacksave() nounwind
+ %vla.i = alloca i8*, i64 %n, align 16
+ br label %for.body.i
+
+for.body.i:
+ %indvars.iv37.i = phi i64 [ %indvars.iv.next38.i, %for.body.i ], [ 0, %entry ]
+ %call.i = call i8* (...)* @a() nounwind
+ %arrayidx.i = getelementptr inbounds i8** %vla.i, i64 %indvars.iv37.i
+ store i8* %call.i, i8** %arrayidx.i, align 8
+ %indvars.iv.next38.i = add i64 %indvars.iv37.i, 1
+ %exitcond5 = icmp eq i64 %indvars.iv.next38.i, %n
+ br i1 %exitcond5, label %g.exit, label %for.body.i
+
+g.exit:
+ call void @llvm.stackrestore(i8* %savedstack) nounwind
+ %call1 = call i8* (...)* @a(i8** %vla) nounwind
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll b/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
index fc906cd..fb9ef22 100644
--- a/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
+++ b/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
@@ -1,5 +1,4 @@
; RUN: opt < %s -indvars -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/2007-06-06-NoInline.ll b/test/Transforms/Inline/2007-06-06-NoInline.ll
deleted file mode 100644
index d5a7953..0000000
--- a/test/Transforms/Inline/2007-06-06-NoInline.ll
+++ /dev/null
@@ -1,46 +0,0 @@
-; RUN: opt < %s -inline -S | grep "define internal i32 @bar"
-@llvm.noinline = appending global [1 x i8*] [ i8* bitcast (i32 (i32, i32)* @bar to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
-
-define internal i32 @bar(i32 %x, i32 %y) {
-entry:
- %x_addr = alloca i32 ; <i32*> [#uses=2]
- %y_addr = alloca i32 ; <i32*> [#uses=2]
- %retval = alloca i32, align 4 ; <i32*> [#uses=2]
- %tmp = alloca i32, align 4 ; <i32*> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- store i32 %x, i32* %x_addr
- store i32 %y, i32* %y_addr
- %tmp1 = load i32* %x_addr ; <i32> [#uses=1]
- %tmp2 = load i32* %y_addr ; <i32> [#uses=1]
- %tmp3 = add i32 %tmp1, %tmp2 ; <i32> [#uses=1]
- store i32 %tmp3, i32* %tmp
- %tmp4 = load i32* %tmp ; <i32> [#uses=1]
- store i32 %tmp4, i32* %retval
- br label %return
-
-return: ; preds = %entry
- %retval5 = load i32* %retval ; <i32> [#uses=1]
- ret i32 %retval5
-}
-
-define i32 @foo(i32 %a, i32 %b) {
-entry:
- %a_addr = alloca i32 ; <i32*> [#uses=2]
- %b_addr = alloca i32 ; <i32*> [#uses=2]
- %retval = alloca i32, align 4 ; <i32*> [#uses=2]
- %tmp = alloca i32, align 4 ; <i32*> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- store i32 %a, i32* %a_addr
- store i32 %b, i32* %b_addr
- %tmp1 = load i32* %b_addr ; <i32> [#uses=1]
- %tmp2 = load i32* %a_addr ; <i32> [#uses=1]
- %tmp3 = call i32 @bar( i32 %tmp1, i32 %tmp2 ) ; <i32> [#uses=1]
- store i32 %tmp3, i32* %tmp
- %tmp4 = load i32* %tmp ; <i32> [#uses=1]
- store i32 %tmp4, i32* %retval
- br label %return
-
-return: ; preds = %entry
- %retval5 = load i32* %retval ; <i32> [#uses=1]
- ret i32 %retval5
-}
diff --git a/test/Transforms/Inline/2008-09-02-AlwaysInline.ll b/test/Transforms/Inline/2008-09-02-AlwaysInline.ll
deleted file mode 100644
index 39095c4..0000000
--- a/test/Transforms/Inline/2008-09-02-AlwaysInline.ll
+++ /dev/null
@@ -1,10 +0,0 @@
-; RUN: opt < %s -inline-threshold=0 -inline -S | not grep call
-
-define i32 @fn2() alwaysinline {
- ret i32 1
-}
-
-define i32 @fn3() {
- %r = call i32 @fn2()
- ret i32 %r
-}
diff --git a/test/Transforms/Inline/2008-10-30-AlwaysInline.ll b/test/Transforms/Inline/2008-10-30-AlwaysInline.ll
deleted file mode 100644
index 11e5012..0000000
--- a/test/Transforms/Inline/2008-10-30-AlwaysInline.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt < %s -always-inline -S | not grep call
-
-; Ensure that threshold doesn't disrupt always inline.
-; RUN: opt < %s -inline-threshold=-2000000001 -always-inline -S | not grep call
-
-
-define internal i32 @if0() alwaysinline {
- ret i32 1
-}
-
-define i32 @f0() {
- %r = call i32 @if0()
- ret i32 %r
-}
diff --git a/test/Transforms/Inline/2008-11-04-AlwaysInline.ll b/test/Transforms/Inline/2008-11-04-AlwaysInline.ll
deleted file mode 100644
index bc9787b..0000000
--- a/test/Transforms/Inline/2008-11-04-AlwaysInline.ll
+++ /dev/null
@@ -1,7 +0,0 @@
-; RUN: opt < %s -always-inline -S | grep {@foo}
-; Ensure that foo is not removed by always inliner
-; PR 2945
-
-define internal i32 @foo() nounwind {
- ret i32 0
-}
diff --git a/test/Transforms/Inline/alloca-bonus.ll b/test/Transforms/Inline/alloca-bonus.ll
new file mode 100644
index 0000000..d04d54e
--- /dev/null
+++ b/test/Transforms/Inline/alloca-bonus.ll
@@ -0,0 +1,155 @@
+; RUN: opt -inline < %s -S -o - -inline-threshold=8 | FileCheck %s
+
+target datalayout = "p:32:32"
+
+declare void @llvm.lifetime.start(i64 %size, i8* nocapture %ptr)
+
+@glbl = external global i32
+
+define void @outer1() {
+; CHECK: @outer1
+; CHECK-NOT: call void @inner1
+ %ptr = alloca i32
+ call void @inner1(i32* %ptr)
+ ret void
+}
+
+define void @inner1(i32 *%ptr) {
+ %A = load i32* %ptr
+ store i32 0, i32* %ptr
+ %C = getelementptr inbounds i32* %ptr, i32 0
+ %D = getelementptr inbounds i32* %ptr, i32 1
+ %E = bitcast i32* %ptr to i8*
+ %F = select i1 false, i32* %ptr, i32* @glbl
+ call void @llvm.lifetime.start(i64 0, i8* %E)
+ ret void
+}
+
+define void @outer2() {
+; CHECK: @outer2
+; CHECK: call void @inner2
+ %ptr = alloca i32
+ call void @inner2(i32* %ptr)
+ ret void
+}
+
+; %D poisons this call, scalar-repl can't handle that instruction.
+define void @inner2(i32 *%ptr) {
+ %A = load i32* %ptr
+ store i32 0, i32* %ptr
+ %C = getelementptr inbounds i32* %ptr, i32 0
+ %D = getelementptr inbounds i32* %ptr, i32 %A
+ %E = bitcast i32* %ptr to i8*
+ %F = select i1 false, i32* %ptr, i32* @glbl
+ call void @llvm.lifetime.start(i64 0, i8* %E)
+ ret void
+}
+
+define void @outer3() {
+; CHECK: @outer3
+; CHECK-NOT: call void @inner3
+ %ptr = alloca i32
+ call void @inner3(i32* %ptr, i1 undef)
+ ret void
+}
+
+define void @inner3(i32 *%ptr, i1 %x) {
+ %A = icmp eq i32* %ptr, null
+ %B = and i1 %x, %A
+ br i1 %A, label %bb.true, label %bb.false
+bb.true:
+ ; This block musn't be counted in the inline cost.
+ %t1 = load i32* %ptr
+ %t2 = add i32 %t1, 1
+ %t3 = add i32 %t2, 1
+ %t4 = add i32 %t3, 1
+ %t5 = add i32 %t4, 1
+ %t6 = add i32 %t5, 1
+ %t7 = add i32 %t6, 1
+ %t8 = add i32 %t7, 1
+ %t9 = add i32 %t8, 1
+ %t10 = add i32 %t9, 1
+ %t11 = add i32 %t10, 1
+ %t12 = add i32 %t11, 1
+ %t13 = add i32 %t12, 1
+ %t14 = add i32 %t13, 1
+ %t15 = add i32 %t14, 1
+ %t16 = add i32 %t15, 1
+ %t17 = add i32 %t16, 1
+ %t18 = add i32 %t17, 1
+ %t19 = add i32 %t18, 1
+ %t20 = add i32 %t19, 1
+ ret void
+bb.false:
+ ret void
+}
+
+define void @outer4(i32 %A) {
+; CHECK: @outer4
+; CHECK-NOT: call void @inner4
+ %ptr = alloca i32
+ call void @inner4(i32* %ptr, i32 %A)
+ ret void
+}
+
+; %B poisons this call, scalar-repl can't handle that instruction. However, we
+; still want to detect that the icmp and branch *can* be handled.
+define void @inner4(i32 *%ptr, i32 %A) {
+ %B = getelementptr inbounds i32* %ptr, i32 %A
+ %C = icmp eq i32* %ptr, null
+ br i1 %C, label %bb.true, label %bb.false
+bb.true:
+ ; This block musn't be counted in the inline cost.
+ %t1 = load i32* %ptr
+ %t2 = add i32 %t1, 1
+ %t3 = add i32 %t2, 1
+ %t4 = add i32 %t3, 1
+ %t5 = add i32 %t4, 1
+ %t6 = add i32 %t5, 1
+ %t7 = add i32 %t6, 1
+ %t8 = add i32 %t7, 1
+ %t9 = add i32 %t8, 1
+ %t10 = add i32 %t9, 1
+ %t11 = add i32 %t10, 1
+ %t12 = add i32 %t11, 1
+ %t13 = add i32 %t12, 1
+ %t14 = add i32 %t13, 1
+ %t15 = add i32 %t14, 1
+ %t16 = add i32 %t15, 1
+ %t17 = add i32 %t16, 1
+ %t18 = add i32 %t17, 1
+ %t19 = add i32 %t18, 1
+ %t20 = add i32 %t19, 1
+ ret void
+bb.false:
+ ret void
+}
+
+define void @outer5() {
+; CHECK: @outer5
+; CHECK-NOT: call void @inner5
+ %ptr = alloca i32
+ call void @inner5(i1 false, i32* %ptr)
+ ret void
+}
+
+; %D poisons this call, scalar-repl can't handle that instruction. However, if
+; the flag is set appropriately, the poisoning instruction is inside of dead
+; code, and so shouldn't be counted.
+define void @inner5(i1 %flag, i32 *%ptr) {
+ %A = load i32* %ptr
+ store i32 0, i32* %ptr
+ %C = getelementptr inbounds i32* %ptr, i32 0
+ br i1 %flag, label %if.then, label %exit
+
+if.then:
+ %D = getelementptr inbounds i32* %ptr, i32 %A
+ %E = bitcast i32* %ptr to i8*
+ %F = select i1 false, i32* %ptr, i32* @glbl
+ call void @llvm.lifetime.start(i64 0, i8* %E)
+ ret void
+
+exit:
+ ret void
+}
+
diff --git a/test/Transforms/Inline/always-inline.ll b/test/Transforms/Inline/always-inline.ll
new file mode 100644
index 0000000..e0be41f
--- /dev/null
+++ b/test/Transforms/Inline/always-inline.ll
@@ -0,0 +1,125 @@
+; RUN: opt < %s -inline-threshold=0 -always-inline -S | FileCheck %s
+;
+; Ensure the threshold has no impact on these decisions.
+; RUN: opt < %s -inline-threshold=20000000 -always-inline -S | FileCheck %s
+; RUN: opt < %s -inline-threshold=-20000000 -always-inline -S | FileCheck %s
+
+define i32 @inner1() alwaysinline {
+ ret i32 1
+}
+define i32 @outer1() {
+; CHECK: @outer1
+; CHECK-NOT: call
+; CHECK: ret
+
+ %r = call i32 @inner1()
+ ret i32 %r
+}
+
+; The always inliner can't DCE internal functions. PR2945
+; CHECK: @pr2945
+define internal i32 @pr2945() nounwind {
+ ret i32 0
+}
+
+define internal void @inner2(i32 %N) alwaysinline {
+ %P = alloca i32, i32 %N
+ ret void
+}
+define void @outer2(i32 %N) {
+; The always inliner (unlike the normal one) should be willing to inline
+; a function with a dynamic alloca into one without a dynamic alloca.
+; rdar://6655932
+;
+; CHECK: @outer2
+; CHECK-NOT: call void @inner2
+; CHECK alloca i32, i32 %N
+; CHECK-NOT: call void @inner2
+; CHECK: ret void
+
+ call void @inner2( i32 %N )
+ ret void
+}
+
+declare i32 @a() returns_twice
+declare i32 @b() returns_twice
+
+define i32 @inner3() alwaysinline {
+entry:
+ %call = call i32 @a() returns_twice
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+define i32 @outer3() {
+entry:
+; CHECK: @outer3
+; CHECK-NOT: call i32 @a
+; CHECK: ret
+
+ %call = call i32 @inner3()
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+
+define i32 @inner4() alwaysinline returns_twice {
+entry:
+ %call = call i32 @b() returns_twice
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+
+define i32 @outer4() {
+entry:
+; CHECK: @outer4
+; CHECK: call i32 @b()
+; CHECK: ret
+
+ %call = call i32 @inner4() returns_twice
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+
+define i32 @inner5(i8* %addr) alwaysinline {
+entry:
+ indirectbr i8* %addr, [ label %one, label %two ]
+
+one:
+ ret i32 42
+
+two:
+ ret i32 44
+}
+define i32 @outer5(i32 %x) {
+; CHECK: @outer5
+; CHECK: call i32 @inner5
+; CHECK: ret
+
+ %cmp = icmp slt i32 %x, 42
+ %addr = select i1 %cmp, i8* blockaddress(@inner5, %one), i8* blockaddress(@inner5, %two)
+ %call = call i32 @inner5(i8* %addr)
+ ret i32 %call
+}
+
+define void @inner6(i32 %x) alwaysinline {
+entry:
+ %icmp = icmp slt i32 %x, 0
+ br i1 %icmp, label %return, label %bb
+
+bb:
+ %sub = sub nsw i32 %x, 1
+ call void @inner6(i32 %sub)
+ ret void
+
+return:
+ ret void
+}
+define void @outer6() {
+; CHECK: @outer6
+; CHECK: call void @inner6(i32 42)
+; CHECK: ret
+
+entry:
+ call void @inner6(i32 42)
+ ret void
+}
+
diff --git a/test/Transforms/Inline/always_inline_dyn_alloca.ll b/test/Transforms/Inline/always_inline_dyn_alloca.ll
deleted file mode 100644
index 25cfc49..0000000
--- a/test/Transforms/Inline/always_inline_dyn_alloca.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -inline -S | not grep callee
-; rdar://6655932
-
-; If callee is marked alwaysinline, inline it! Even if callee has dynamic
-; alloca and caller does not,
-
-define internal void @callee(i32 %N) alwaysinline {
- %P = alloca i32, i32 %N
- ret void
-}
-
-define void @foo(i32 %N) {
- call void @callee( i32 %N )
- ret void
-}
diff --git a/test/Transforms/Inline/blockaddress.ll b/test/Transforms/Inline/blockaddress.ll
new file mode 100644
index 0000000..4206312
--- /dev/null
+++ b/test/Transforms/Inline/blockaddress.ll
@@ -0,0 +1,27 @@
+; RUN: opt -inline -S < %s | FileCheck %s
+; PR10162
+
+; Make sure the blockaddress is mapped correctly when doit is inlined
+; CHECK: store i8* blockaddress(@f, %here.i), i8** @ptr1, align 8
+
+@i = global i32 1, align 4
+@ptr1 = common global i8* null, align 8
+
+define void @doit(i8** nocapture %pptr, i32 %cond) nounwind uwtable {
+entry:
+ %tobool = icmp eq i32 %cond, 0
+ br i1 %tobool, label %if.end, label %here
+
+here:
+ store i8* blockaddress(@doit, %here), i8** %pptr, align 8
+ br label %if.end
+
+if.end:
+ ret void
+}
+
+define void @f(i32 %cond) nounwind uwtable {
+entry:
+ call void @doit(i8** @ptr1, i32 %cond)
+ ret void
+}
diff --git a/test/Transforms/Inline/dg.exp b/test/Transforms/Inline/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/Inline/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/Inline/dynamic_alloca_test.ll b/test/Transforms/Inline/dynamic_alloca_test.ll
index 0286535..15a5c66 100644
--- a/test/Transforms/Inline/dynamic_alloca_test.ll
+++ b/test/Transforms/Inline/dynamic_alloca_test.ll
@@ -3,33 +3,43 @@
; Functions with dynamic allocas can only be inlined into functions that
; already have dynamic allocas.
-; RUN: opt < %s -inline -S | \
-; RUN: grep llvm.stacksave
-; RUN: opt < %s -inline -S | not grep callee
-
+; RUN: opt < %s -inline -S | FileCheck %s
+;
+; FIXME: This test is xfailed because the inline cost rewrite disabled *all*
+; inlining of functions which contain a dynamic alloca. It should be re-enabled
+; once that functionality is restored.
+; XFAIL: *
declare void @ext(i32*)
define internal void @callee(i32 %N) {
- %P = alloca i32, i32 %N ; <i32*> [#uses=1]
- call void @ext( i32* %P )
- ret void
+ %P = alloca i32, i32 %N
+ call void @ext(i32* %P)
+ ret void
}
define void @foo(i32 %N) {
-; <label>:0
- %P = alloca i32, i32 %N ; <i32*> [#uses=1]
- call void @ext( i32* %P )
- br label %Loop
-
-Loop: ; preds = %Loop, %0
- %count = phi i32 [ 0, %0 ], [ %next, %Loop ] ; <i32> [#uses=2]
- %next = add i32 %count, 1 ; <i32> [#uses=1]
- call void @callee( i32 %N )
- %cond = icmp eq i32 %count, 100000 ; <i1> [#uses=1]
- br i1 %cond, label %out, label %Loop
-
-out: ; preds = %Loop
- ret void
+; CHECK: @foo
+; CHECK: alloca i32, i32 %{{.*}}
+; CHECK: call i8* @llvm.stacksave()
+; CHECK: alloca i32, i32 %{{.*}}
+; CHECK: call void @ext
+; CHECK: call void @llvm.stackrestore
+; CHECK: ret
+
+entry:
+ %P = alloca i32, i32 %N
+ call void @ext(i32* %P)
+ br label %loop
+
+loop:
+ %count = phi i32 [ 0, %entry ], [ %next, %loop ]
+ %next = add i32 %count, 1
+ call void @callee(i32 %N)
+ %cond = icmp eq i32 %count, 100000
+ br i1 %cond, label %out, label %loop
+
+out:
+ ret void
}
diff --git a/test/Transforms/Inline/inline-invoke-tail.ll b/test/Transforms/Inline/inline-invoke-tail.ll
index 462c29a..1f34113 100644
--- a/test/Transforms/Inline/inline-invoke-tail.ll
+++ b/test/Transforms/Inline/inline-invoke-tail.ll
@@ -23,15 +23,11 @@ invcont:
ret i32 %retval
lpad:
- %eh_ptr = call i8* @llvm.eh.exception()
- %eh_select = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
unreachable
}
-declare i8* @llvm.eh.exception() nounwind readonly
-
-declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
-
declare i32 @__gxx_personality_v0(...)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
diff --git a/test/Transforms/Inline/inline_cleanup.ll b/test/Transforms/Inline/inline_cleanup.ll
index 4c64721..3898aa7 100644
--- a/test/Transforms/Inline/inline_cleanup.ll
+++ b/test/Transforms/Inline/inline_cleanup.ll
@@ -1,10 +1,8 @@
; Test that the inliner doesn't leave around dead allocas, and that it folds
; uncond branches away after it is done specializing.
-; RUN: opt < %s -inline -S | \
-; RUN: not grep {alloca.*uses=0}
-; RUN: opt < %s -inline -S | \
-; RUN: not grep {br label}
+; RUN: opt < %s -inline -S | FileCheck %s
+
@A = weak global i32 0 ; <i32*> [#uses=1]
@B = weak global i32 0 ; <i32*> [#uses=1]
@C = weak global i32 0 ; <i32*> [#uses=1]
@@ -54,6 +52,18 @@ UnifiedReturnBlock: ; preds = %cond_next13
declare void @ext(i32*)
define void @test() {
+; CHECK: @test
+; CHECK-NOT: ret
+;
+; FIXME: This should be a CHECK-NOT, but currently we have a bug that causes us
+; to not nuke unused allocas.
+; CHECK: alloca
+; CHECK-NOT: ret
+;
+; No branches should survive the inliner's cleanup.
+; CHECK-NOT: br
+; CHECK: ret void
+
entry:
tail call fastcc void @foo( i32 1 )
tail call fastcc void @foo( i32 2 )
@@ -61,3 +71,143 @@ entry:
tail call fastcc void @foo( i32 8 )
ret void
}
+
+declare void @f(i32 %x)
+
+define void @inner2(i32 %x, i32 %y, i32 %z, i1 %b) {
+entry:
+ %cmp1 = icmp ne i32 %x, 0
+ br i1 %cmp1, label %then1, label %end1
+
+then1:
+ call void @f(i32 %x)
+ br label %end1
+
+end1:
+ %x2 = and i32 %x, %z
+ %cmp2 = icmp sgt i32 %x2, 1
+ br i1 %cmp2, label %then2, label %end2
+
+then2:
+ call void @f(i32 %x2)
+ br label %end2
+
+end2:
+ %y2 = or i32 %y, %z
+ %cmp3 = icmp sgt i32 %y2, 0
+ br i1 %cmp3, label %then3, label %end3
+
+then3:
+ call void @f(i32 %y2)
+ br label %end3
+
+end3:
+ br i1 %b, label %end3.1, label %end3.2
+
+end3.1:
+ %x3.1 = or i32 %x, 10
+ br label %end3.3
+
+end3.2:
+ %x3.2 = or i32 %x, 10
+ br label %end3.3
+
+end3.3:
+ %x3.3 = phi i32 [ %x3.1, %end3.1 ], [ %x3.2, %end3.2 ]
+ %cmp4 = icmp slt i32 %x3.3, 1
+ br i1 %cmp4, label %then4, label %end4
+
+then4:
+ call void @f(i32 %x3.3)
+ br label %end4
+
+end4:
+ ret void
+}
+
+define void @outer2(i32 %z, i1 %b) {
+; Ensure that after inlining, none of the blocks with a call to @f actually
+; make it through inlining.
+; CHECK: define void @outer2
+; CHECK-NOT: call
+; CHECK: ret void
+
+entry:
+ call void @inner2(i32 0, i32 -1, i32 %z, i1 %b)
+ ret void
+}
+
+define void @PR12470_inner(i16 signext %p1) nounwind uwtable {
+entry:
+ br i1 undef, label %cond.true, label %cond.false
+
+cond.true:
+ br label %cond.end
+
+cond.false:
+ %conv = sext i16 %p1 to i32
+ br label %cond.end
+
+cond.end:
+ %cond = phi i32 [ undef, %cond.true ], [ 0, %cond.false ]
+ %tobool = icmp eq i32 %cond, 0
+ br i1 %tobool, label %if.end5, label %if.then
+
+if.then:
+ ret void
+
+if.end5:
+ ret void
+}
+
+define void @PR12470_outer() {
+; This previously crashed during inliner cleanup and folding inner return
+; instructions. Check that we don't crash and we produce a function with a single
+; return instruction due to merging the returns of the inlined function.
+; CHECK: define void @PR12470_outer
+; CHECK-NOT: call
+; CHECK: ret void
+; CHECK-NOT: ret void
+; CHECK: }
+
+entry:
+ call void @PR12470_inner(i16 signext 1)
+ ret void
+}
+
+define void @crasher_inner() nounwind uwtable {
+entry:
+ br i1 false, label %for.end28, label %for.body6
+
+for.body6:
+ br i1 undef, label %for.body6, label %for.cond12.for.inc26_crit_edge
+
+for.cond12.for.inc26_crit_edge:
+ br label %for.body6.1
+
+for.end28:
+ ret void
+
+for.body6.1:
+ br i1 undef, label %for.body6.1, label %for.cond12.for.inc26_crit_edge.1
+
+for.cond12.for.inc26_crit_edge.1:
+ br label %for.body6.2
+
+for.body6.2:
+ br i1 undef, label %for.body6.2, label %for.cond12.for.inc26_crit_edge.2
+
+for.cond12.for.inc26_crit_edge.2:
+ br label %for.end28
+}
+
+define void @crasher_outer() {
+; CHECK: @crasher_outer
+; CHECK-NOT: call
+; CHECK: ret void
+; CHECK-NOT: ret
+; CHECK: }
+entry:
+ tail call void @crasher_inner()
+ ret void
+}
diff --git a/test/Transforms/Inline/inline_constprop.ll b/test/Transforms/Inline/inline_constprop.ll
index 537c69b..dc35b60 100644
--- a/test/Transforms/Inline/inline_constprop.ll
+++ b/test/Transforms/Inline/inline_constprop.ll
@@ -1,14 +1,112 @@
-; RUN: opt < %s -inline -S | not grep callee
-; RUN: opt < %s -inline -S | not grep div
+; RUN: opt < %s -inline -inline-threshold=20 -S | FileCheck %s
+define internal i32 @callee1(i32 %A, i32 %B) {
+ %C = sdiv i32 %A, %B
+ ret i32 %C
+}
+
+define i32 @caller1() {
+; CHECK: define i32 @caller1
+; CHECK-NEXT: ret i32 3
+
+ %X = call i32 @callee1( i32 10, i32 3 )
+ ret i32 %X
+}
+
+define i32 @caller2() {
+; Check that we can constant-prop through instructions after inlining callee21
+; to get constants in the inlined callsite to callee22.
+; FIXME: Currently, the threshold is fixed at 20 because we don't perform
+; *recursive* cost analysis to realize that the nested call site will definitely
+; inline and be cheap. We should eventually do that and lower the threshold here
+; to 1.
+;
+; CHECK: @caller2
+; CHECK-NOT: call void @callee2
+; CHECK: ret
+
+ %x = call i32 @callee21(i32 42, i32 48)
+ ret i32 %x
+}
+
+define i32 @callee21(i32 %x, i32 %y) {
+ %sub = sub i32 %y, %x
+ %result = call i32 @callee22(i32 %sub)
+ ret i32 %result
+}
-define internal i32 @callee(i32 %A, i32 %B) {
- %C = sdiv i32 %A, %B ; <i32> [#uses=1]
- ret i32 %C
+declare i8* @getptr()
+
+define i32 @callee22(i32 %x) {
+ %icmp = icmp ugt i32 %x, 42
+ br i1 %icmp, label %bb.true, label %bb.false
+bb.true:
+ ; This block musn't be counted in the inline cost.
+ %x1 = add i32 %x, 1
+ %x2 = add i32 %x1, 1
+ %x3 = add i32 %x2, 1
+ %x4 = add i32 %x3, 1
+ %x5 = add i32 %x4, 1
+ %x6 = add i32 %x5, 1
+ %x7 = add i32 %x6, 1
+ %x8 = add i32 %x7, 1
+
+ ret i32 %x8
+bb.false:
+ ret i32 %x
}
-define i32 @test() {
- %X = call i32 @callee( i32 10, i32 3 ) ; <i32> [#uses=1]
- ret i32 %X
+define i32 @caller3() {
+; Check that even if the expensive path is hidden behind several basic blocks,
+; it doesn't count toward the inline cost when constant-prop proves those paths
+; dead.
+;
+; CHECK: @caller3
+; CHECK-NOT: call
+; CHECK: ret i32 6
+
+entry:
+ %x = call i32 @callee3(i32 42, i32 48)
+ ret i32 %x
}
+define i32 @callee3(i32 %x, i32 %y) {
+ %sub = sub i32 %y, %x
+ %icmp = icmp ugt i32 %sub, 42
+ br i1 %icmp, label %bb.true, label %bb.false
+
+bb.true:
+ %icmp2 = icmp ult i32 %sub, 64
+ br i1 %icmp2, label %bb.true.true, label %bb.true.false
+
+bb.true.true:
+ ; This block musn't be counted in the inline cost.
+ %x1 = add i32 %x, 1
+ %x2 = add i32 %x1, 1
+ %x3 = add i32 %x2, 1
+ %x4 = add i32 %x3, 1
+ %x5 = add i32 %x4, 1
+ %x6 = add i32 %x5, 1
+ %x7 = add i32 %x6, 1
+ %x8 = add i32 %x7, 1
+ br label %bb.merge
+
+bb.true.false:
+ ; This block musn't be counted in the inline cost.
+ %y1 = add i32 %y, 1
+ %y2 = add i32 %y1, 1
+ %y3 = add i32 %y2, 1
+ %y4 = add i32 %y3, 1
+ %y5 = add i32 %y4, 1
+ %y6 = add i32 %y5, 1
+ %y7 = add i32 %y6, 1
+ %y8 = add i32 %y7, 1
+ br label %bb.merge
+
+bb.merge:
+ %result = phi i32 [ %x8, %bb.true.true ], [ %y8, %bb.true.false ]
+ ret i32 %result
+
+bb.false:
+ ret i32 %sub
+}
diff --git a/test/Transforms/Inline/inline_returns_twice.ll b/test/Transforms/Inline/inline_returns_twice.ll
new file mode 100644
index 0000000..ab2e954
--- /dev/null
+++ b/test/Transforms/Inline/inline_returns_twice.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -inline -S | FileCheck %s
+
+; Check that functions with "returns_twice" calls are only inlined,
+; if they are themselve marked as such.
+
+declare i32 @a() returns_twice
+declare i32 @b() returns_twice
+
+define i32 @f() {
+entry:
+ %call = call i32 @a() returns_twice
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+
+define i32 @g() {
+entry:
+; CHECK: define i32 @g
+; CHECK: call i32 @f()
+; CHECK-NOT: call i32 @a()
+ %call = call i32 @f()
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+
+define i32 @h() returns_twice {
+entry:
+ %call = call i32 @b() returns_twice
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
+
+define i32 @i() {
+entry:
+; CHECK: define i32 @i
+; CHECK: call i32 @b()
+; CHECK-NOT: call i32 @h()
+ %call = call i32 @h() returns_twice
+ %add = add nsw i32 1, %call
+ ret i32 %add
+}
diff --git a/test/Transforms/Inline/lit.local.cfg b/test/Transforms/Inline/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/Inline/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/Inline/noinline-recursive-fn.ll b/test/Transforms/Inline/noinline-recursive-fn.ll
index 1d5ebbb..6cde0e2 100644
--- a/test/Transforms/Inline/noinline-recursive-fn.ll
+++ b/test/Transforms/Inline/noinline-recursive-fn.ll
@@ -17,7 +17,7 @@ entry:
bb: ; preds = %entry
%1 = sub nsw i32 %x, 1 ; <i32> [#uses=1]
call void @foo(i32 %1) nounwind ssp
- volatile store i32 1, i32* @g, align 4
+ store volatile i32 1, i32* @g, align 4
ret void
return: ; preds = %entry
@@ -42,7 +42,7 @@ entry:
%0 = bitcast i8* %Bar to void (i32, i8*, i8*)*
%1 = sub nsw i32 %x, 1
call void %0(i32 %1, i8* %Foo, i8* %Bar) nounwind
- volatile store i32 42, i32* @g, align 4
+ store volatile i32 42, i32* @g, align 4
ret void
}
@@ -54,7 +54,7 @@ entry:
bb: ; preds = %entry
%1 = bitcast i8* %Foo to void (i32, i8*, i8*)* ; <void (i32, i8*, i8*)*> [#uses=1]
call void %1(i32 %x, i8* %Foo, i8* %Bar) nounwind
- volatile store i32 13, i32* @g, align 4
+ store volatile i32 13, i32* @g, align 4
ret void
return: ; preds = %entry
@@ -71,3 +71,40 @@ entry:
call void @f2(i32 123, i8* bitcast (void (i32, i8*, i8*)* @f1 to i8*), i8* bitcast (void (i32, i8*, i8*)* @f2 to i8*)) nounwind ssp
ret void
}
+
+
+; Check that a recursive function, when called with a constant that makes the
+; recursive path dead code can actually be inlined.
+define i32 @fib(i32 %i) {
+entry:
+ %is.zero = icmp eq i32 %i, 0
+ br i1 %is.zero, label %zero.then, label %zero.else
+
+zero.then:
+ ret i32 0
+
+zero.else:
+ %is.one = icmp eq i32 %i, 1
+ br i1 %is.one, label %one.then, label %one.else
+
+one.then:
+ ret i32 1
+
+one.else:
+ %i1 = sub i32 %i, 1
+ %f1 = call i32 @fib(i32 %i1)
+ %i2 = sub i32 %i, 2
+ %f2 = call i32 @fib(i32 %i2)
+ %f = add i32 %f1, %f2
+ ret i32 %f
+}
+
+define i32 @fib_caller() {
+; CHECK: @fib_caller
+; CHECK-NOT: call
+; CHECK: ret
+ %f1 = call i32 @fib(i32 0)
+ %f2 = call i32 @fib(i32 1)
+ %result = add i32 %f1, %f2
+ ret i32 %result
+}
diff --git a/test/Transforms/Inline/ptr-diff.ll b/test/Transforms/Inline/ptr-diff.ll
new file mode 100644
index 0000000..60fc3e2
--- /dev/null
+++ b/test/Transforms/Inline/ptr-diff.ll
@@ -0,0 +1,58 @@
+; RUN: opt -inline < %s -S -o - -inline-threshold=10 | FileCheck %s
+
+target datalayout = "p:32:32"
+
+define i32 @outer1() {
+; CHECK: @outer1
+; CHECK-NOT: call
+; CHECK: ret i32
+
+ %ptr = alloca i32
+ %ptr1 = getelementptr inbounds i32* %ptr, i32 0
+ %ptr2 = getelementptr inbounds i32* %ptr, i32 42
+ %result = call i32 @inner1(i32* %ptr1, i32* %ptr2)
+ ret i32 %result
+}
+
+define i32 @inner1(i32* %begin, i32* %end) {
+ %begin.i = ptrtoint i32* %begin to i32
+ %end.i = ptrtoint i32* %end to i32
+ %distance = sub i32 %end.i, %begin.i
+ %icmp = icmp sle i32 %distance, 42
+ br i1 %icmp, label %then, label %else
+
+then:
+ ret i32 3
+
+else:
+ %t = load i32* %begin
+ ret i32 %t
+}
+
+define i32 @outer2(i32* %ptr) {
+; Test that an inbounds GEP disables this -- it isn't safe in general as
+; wrapping changes the behavior of lessthan and greaterthan comparisions.
+; CHECK: @outer2
+; CHECK: call i32 @inner2
+; CHECK: ret i32
+
+ %ptr1 = getelementptr i32* %ptr, i32 0
+ %ptr2 = getelementptr i32* %ptr, i32 42
+ %result = call i32 @inner2(i32* %ptr1, i32* %ptr2)
+ ret i32 %result
+}
+
+define i32 @inner2(i32* %begin, i32* %end) {
+ %begin.i = ptrtoint i32* %begin to i32
+ %end.i = ptrtoint i32* %end to i32
+ %distance = sub i32 %end.i, %begin.i
+ %icmp = icmp sle i32 %distance, 42
+ br i1 %icmp, label %then, label %else
+
+then:
+ ret i32 3
+
+else:
+ %t = load i32* %begin
+ ret i32 %t
+}
diff --git a/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll b/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll
index 3297919..7f73908 100644
--- a/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll
+++ b/test/Transforms/InstCombine/2003-09-09-VolatileLoadElim.ll
@@ -2,6 +2,6 @@
define void @test(i32* %P) {
; Dead but not deletable!
- %X = volatile load i32* %P ; <i32> [#uses=0]
+ %X = load volatile i32* %P ; <i32> [#uses=0]
ret void
}
diff --git a/test/Transforms/InstCombine/2007-09-11-Trampoline.ll b/test/Transforms/InstCombine/2007-09-11-Trampoline.ll
deleted file mode 100644
index 6190aa9..0000000
--- a/test/Transforms/InstCombine/2007-09-11-Trampoline.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; RUN: opt < %s -instcombine -S | grep {call i32 @f}
-
- %struct.FRAME.nest = type { i32, i32 (i32)* }
- %struct.__builtin_trampoline = type { [10 x i8] }
-
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*)
-
-declare i32 @f(%struct.FRAME.nest* nest , i32 )
-
-define i32 @nest(i32 %n) {
-entry:
- %FRAME.0 = alloca %struct.FRAME.nest, align 8 ; <%struct.FRAME.nest*> [#uses=3]
- %TRAMP.216 = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1]
- %TRAMP.216.sub = getelementptr [10 x i8]* %TRAMP.216, i32 0, i32 0 ; <i8*> [#uses=1]
- %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* , i32)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
- %tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (i32)**> [#uses=1]
- %tmp89 = bitcast i8* %tramp to i32 (i32)* ; <i32 (i32)*> [#uses=2]
- store i32 (i32)* %tmp89, i32 (i32)** %tmp7, align 8
- %tmp2.i = call i32 %tmp89( i32 1 ) ; <i32> [#uses=1]
- ret i32 %tmp2.i
-}
diff --git a/test/Transforms/InstCombine/2007-10-28-stacksave.ll b/test/Transforms/InstCombine/2007-10-28-stacksave.ll
index 76bceb6..4c5c367 100644
--- a/test/Transforms/InstCombine/2007-10-28-stacksave.ll
+++ b/test/Transforms/InstCombine/2007-10-28-stacksave.ll
@@ -26,7 +26,7 @@ lab: ; preds = %cleanup31, %entry
%tmp21 = getelementptr i32* %tmp1819, i32 0 ; <i32*> [#uses=1]
store i32 1, i32* %tmp21, align 4
%tmp2223 = bitcast i32* %tmp1819 to i8* ; <i8*> [#uses=1]
- volatile store i8* %tmp2223, i8** @p, align 4
+ store volatile i8* %tmp2223, i8** @p, align 4
%tmp25 = add i32 %n.0, 1 ; <i32> [#uses=2]
%tmp27 = icmp sle i32 %tmp25, 999999 ; <i1> [#uses=1]
%tmp2728 = zext i1 %tmp27 to i8 ; <i8> [#uses=1]
diff --git a/test/Transforms/InstCombine/2008-01-14-DoubleNest.ll b/test/Transforms/InstCombine/2008-01-14-DoubleNest.ll
deleted file mode 100644
index 6401dfd..0000000
--- a/test/Transforms/InstCombine/2008-01-14-DoubleNest.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; RUN: opt < %s -instcombine -disable-output
-
- %struct.FRAME.nest = type { i32, i32 (i32*)* }
- %struct.__builtin_trampoline = type { [10 x i8] }
-
-declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind
-
-declare i32 @f(%struct.FRAME.nest* nest , i32*)
-
-define i32 @nest(i32 %n) {
-entry:
- %FRAME.0 = alloca %struct.FRAME.nest, align 8 ; <%struct.FRAME.nest*> [#uses=3]
- %TRAMP.216 = alloca [10 x i8], align 16 ; <[10 x i8]*> [#uses=1]
- %TRAMP.216.sub = getelementptr [10 x i8]* %TRAMP.216, i32 0, i32 0 ; <i8*> [#uses=1]
- %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*, i32*)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1]
- %tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (i32*)**> [#uses=1]
- %tmp89 = bitcast i8* %tramp to i32 (i32*)* ; <i32 (i32*)*> [#uses=2]
- store i32 (i32*)* %tmp89, i32 (i32*)** %tmp7, align 8
- %tmp2.i = call i32 %tmp89( i32* nest null ) ; <i32> [#uses=1]
- ret i32 %tmp2.i
-}
diff --git a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
index 6847f5e..de08c32 100644
--- a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
+++ b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll
@@ -2,7 +2,7 @@
define void @test() {
%votf = alloca <4 x float> ; <<4 x float>*> [#uses=1]
- volatile store <4 x float> zeroinitializer, <4 x float>* %votf, align 16
+ store volatile <4 x float> zeroinitializer, <4 x float>* %votf, align 16
ret void
}
diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
index a24f307..1286e3d 100644
--- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
+++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll
@@ -6,17 +6,17 @@ target triple = "i386-apple-darwin8"
define i32 @main() nounwind {
entry:
%tmp93 = icmp slt i32 0, 10 ; <i1> [#uses=0]
- %tmp34 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp34 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br label %bb
bb: ; preds = %bb, %entry
%b.0.reg2mem.0 = phi i32 [ 0, %entry ], [ %tmp6, %bb ] ; <i32> [#uses=1]
%tmp3.reg2mem.0 = phi i32 [ %tmp34, %entry ], [ %tmp3, %bb ] ; <i32> [#uses=1]
%tmp4 = add i32 %tmp3.reg2mem.0, 5 ; <i32> [#uses=1]
- volatile store i32 %tmp4, i32* @g_1, align 4
+ store volatile i32 %tmp4, i32* @g_1, align 4
%tmp6 = add i32 %b.0.reg2mem.0, 1 ; <i32> [#uses=2]
%tmp9 = icmp slt i32 %tmp6, 10 ; <i1> [#uses=1]
- %tmp3 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp3 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br i1 %tmp9, label %bb, label %bb11
bb11: ; preds = %bb
diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
index 5fb11ff..ebbd3a7 100644
--- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
+++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll
@@ -7,11 +7,11 @@ target triple = "i386-apple-darwin8"
define i32 @main(i32 %i) nounwind {
entry:
%tmp93 = icmp slt i32 %i, 10 ; <i1> [#uses=0]
- %tmp34 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp34 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br i1 %tmp93, label %bb11, label %bb
bb: ; preds = %bb, %entry
- %tmp3 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp3 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br label %bb11
bb11: ; preds = %bb
diff --git a/test/Transforms/InstCombine/2008-06-24-StackRestore.ll b/test/Transforms/InstCombine/2008-06-24-StackRestore.ll
index 8307834..4f4709b 100644
--- a/test/Transforms/InstCombine/2008-06-24-StackRestore.ll
+++ b/test/Transforms/InstCombine/2008-06-24-StackRestore.ll
@@ -10,7 +10,7 @@ entry:
%tmp2752 = alloca i32 ; <i32*> [#uses=2]
%tmpcast53 = bitcast i32* %tmp2752 to i8* ; <i8*> [#uses=1]
store i32 2, i32* %tmp2752, align 4
- volatile store i8* %tmpcast53, i8** @p, align 4
+ store volatile i8* %tmpcast53, i8** @p, align 4
br label %bb44
bb: ; preds = %bb44
@@ -29,7 +29,7 @@ bb44: ; preds = %bb44, %entry
store i32 1, i32* %tmp27, align 4
%tmp34 = getelementptr i32* %tmp27, i32 %tmp4 ; <i32*> [#uses=1]
store i32 2, i32* %tmp34, align 4
- volatile store i8* %tmpcast, i8** @p, align 4
+ store volatile i8* %tmpcast, i8** @p, align 4
%exitcond = icmp eq i32 %tmp3857, 999999 ; <i1> [#uses=1]
br i1 %exitcond, label %bb, label %bb44
}
diff --git a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
index 8104408..1ed5323 100644
--- a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
+++ b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll
@@ -7,17 +7,17 @@ target triple = "i386-apple-darwin8"
define i32 @main() nounwind {
entry:
%tmp93 = icmp slt i32 0, 10 ; <i1> [#uses=0]
- %tmp34 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp34 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br label %bb
bb: ; preds = %bb, %entry
%b.0.reg2mem.0 = phi i32 [ 0, %entry ], [ %tmp6, %bb ] ; <i32> [#uses=1]
%tmp3.reg2mem.0 = phi i32 [ %tmp3, %bb ], [ %tmp34, %entry ]
%tmp4 = add i32 %tmp3.reg2mem.0, 5 ; <i32> [#uses=1]
- volatile store i32 %tmp4, i32* @g_1, align 4
+ store volatile i32 %tmp4, i32* @g_1, align 4
%tmp6 = add i32 %b.0.reg2mem.0, 1 ; <i32> [#uses=2]
%tmp9 = icmp slt i32 %tmp6, 10 ; <i1> [#uses=1]
- %tmp3 = volatile load i32* @g_1, align 4 ; <i32> [#uses=1]
+ %tmp3 = load volatile i32* @g_1, align 4 ; <i32> [#uses=1]
br i1 %tmp9, label %bb, label %bb11
bb11: ; preds = %bb
diff --git a/test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll b/test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll
new file mode 100644
index 0000000..abab9dc
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-01-11-OpaqueBitcastCrash.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine -disable-output
+
+%opaque_struct = type opaque
+
+@G = external global [0 x %opaque_struct]
+
+declare void @foo(%opaque_struct*)
+
+define void @bar() {
+ call void @foo(%opaque_struct* bitcast ([0 x %opaque_struct]* @G to %opaque_struct*))
+ ret void
+}
diff --git a/test/Transforms/InstCombine/2012-02-13-FCmp.ll b/test/Transforms/InstCombine/2012-02-13-FCmp.ll
new file mode 100644
index 0000000..39b0594
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-02-13-FCmp.ll
@@ -0,0 +1,35 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+; Radar 10803727
+@.str = private unnamed_addr constant [35 x i8] c"\0Ain_range input (should be 0): %f\0A\00", align 1
+@.str1 = external hidden unnamed_addr constant [35 x i8], align 1
+
+declare i32 @printf(i8*, ...)
+define i64 @_Z8tempCastj(i32 %val) uwtable ssp {
+entry:
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([35 x i8]* @.str1, i64 0, i64 0), i32 %val)
+ %conv = uitofp i32 %val to double
+ %call.i = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([35 x i8]* @.str, i64 0, i64 0), double %conv)
+ %cmp.i = fcmp oge double %conv, -1.000000e+00
+ br i1 %cmp.i, label %land.rhs.i, label %if.end.critedge
+; CHECK: br i1 true, label %land.rhs.i, label %if.end.critedge
+
+land.rhs.i: ; preds = %entry
+ %cmp1.i = fcmp olt double %conv, 1.000000e+00
+ br i1 %cmp1.i, label %if.then, label %if.end
+
+if.then: ; preds = %land.rhs.i
+ %add = fadd double %conv, 5.000000e-01
+ %conv3 = fptosi double %add to i64
+ br label %return
+
+if.end.critedge: ; preds = %entry
+ br label %if.end
+
+if.end: ; preds = %if.end.critedge, %land.rhs.i
+ br label %return
+
+return: ; preds = %if.end, %if.then
+ %retval.0 = phi i64 [ %conv3, %if.then ], [ -1, %if.end ]
+ ret i64 %retval.0
+}
+
diff --git a/test/Transforms/InstCombine/2012-02-28-ICmp.ll b/test/Transforms/InstCombine/2012-02-28-ICmp.ll
new file mode 100644
index 0000000..82cf85f
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-02-28-ICmp.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; <rdar://problem/10803154>
+
+; There should be no transformation.
+; CHECK: %a = trunc i32 %x to i8
+; CHECK: %b = icmp ne i8 %a, 0
+; CHECK: %c = and i32 %x, 16711680
+; CHECK: %d = icmp ne i32 %c, 0
+; CHECK: %e = and i1 %b, %d
+; CHECK: ret i1 %e
+
+define i1 @f1(i32 %x) {
+ %a = trunc i32 %x to i8
+ %b = icmp ne i8 %a, 0
+ %c = and i32 %x, 16711680
+ %d = icmp ne i32 %c, 0
+ %e = and i1 %b, %d
+ ret i1 %e
+}
diff --git a/test/Transforms/InstCombine/2012-03-10-InstCombine.ll b/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
new file mode 100644
index 0000000..58ccf12
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -S -instcombine | FileCheck %s
+
+; Derived from gcc.c-torture/execute/frame-address.c
+
+; CHECK: @func
+; CHECK: return:
+; CHECK-NOT: ret i32 0
+; CHECK: ret i32 %retval
+
+define i32 @func(i8* %c, i8* %f) nounwind uwtable readnone noinline ssp {
+entry:
+ %d = alloca i8, align 1
+ store i8 0, i8* %d, align 1
+ %cmp = icmp ugt i8* %d, %c
+ br i1 %cmp, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ %cmp2 = icmp ule i8* %d, %f
+ %not.cmp1 = icmp uge i8* %c, %f
+ %.cmp2 = and i1 %cmp2, %not.cmp1
+ %land.ext = zext i1 %.cmp2 to i32
+ br label %return
+
+if.else: ; preds = %entry
+ %cmp5 = icmp uge i8* %d, %f
+ %not.cmp3 = icmp ule i8* %c, %f
+ %.cmp5 = and i1 %cmp5, %not.cmp3
+ %land.ext7 = zext i1 %.cmp5 to i32
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ %land.ext, %if.then ], [ %land.ext7, %if.else ]
+ ret i32 %retval.0
+}
+
diff --git a/test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll b/test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll
new file mode 100644
index 0000000..c1602da
--- /dev/null
+++ b/test/Transforms/InstCombine/2012-3-15-or-xor-constant.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; PR12234
+
+@g = extern_weak global i32
+define i32 @function(i32 %x) nounwind {
+entry:
+ %xor = xor i32 %x, 1
+ store volatile i32 %xor, i32* inttoptr (i64 1 to i32*), align 4
+ %or4 = or i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 1), %xor
+ ret i32 %or4
+}
+; CHECK: define i32 @function
diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll
index 055bdcc..de3b2d3 100644
--- a/test/Transforms/InstCombine/LandingPadClauses.ll
+++ b/test/Transforms/InstCombine/LandingPadClauses.ll
@@ -6,6 +6,7 @@
declare i32 @generic_personality(i32, i64, i8*, i8*)
declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+declare i32 @__objc_personality_v0(i32, i64, i8*, i8*)
declare void @bar()
@@ -179,3 +180,54 @@ lpad.d:
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
}
+
+define void @foo_objc() {
+; CHECK: @foo_objc
+ 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*)* @__objc_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*)* @__objc_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*)* @__objc_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*)* @__objc_personality_v0
+ cleanup
+ catch i32* null
+ unreachable
+; CHECK: %d = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+}
diff --git a/test/Transforms/InstCombine/align-external.ll b/test/Transforms/InstCombine/align-external.ll
index 6e8ad87..d4a5d42 100644
--- a/test/Transforms/InstCombine/align-external.ll
+++ b/test/Transforms/InstCombine/align-external.ll
@@ -1,7 +1,7 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-; Don't assume that external global variables have their preferred
-; alignment. They may only have the ABI minimum alignment.
+; Don't assume that external global variables or those with weak linkage have
+; their preferred alignment. They may only have the ABI minimum alignment.
; CHECK: %s = shl i64 %a, 3
; CHECK: %r = or i64 %s, ptrtoint (i32* @A to i64)
@@ -11,7 +11,7 @@
target datalayout = "-i32:8:32"
@A = external global i32
-@B = external global i32
+@B = weak_odr global i32 0
define i64 @foo(i64 %a) {
%t = ptrtoint i32* @A to i64
@@ -20,3 +20,10 @@ define i64 @foo(i64 %a) {
%q = add i64 %r, 1
ret i64 %q
}
+
+define i32 @bar() {
+; CHECK: @bar
+ %r = load i32* @B, align 1
+; CHECK: align 1
+ ret i32 %r
+}
diff --git a/test/Transforms/InstCombine/alloca.ll b/test/Transforms/InstCombine/alloca.ll
index e4d1367..ef7185c 100644
--- a/test/Transforms/InstCombine/alloca.ll
+++ b/test/Transforms/InstCombine/alloca.ll
@@ -44,3 +44,47 @@ define i32* @test4(i32 %n) {
%A = alloca i32, i32 %n
ret i32* %A
}
+
+; Allocas which are only used by GEPs, bitcasts, and stores (transitively)
+; should be deleted.
+define void @test5() {
+; CHECK: @test5
+; CHECK-NOT: alloca
+; CHECK-NOT: store
+; CHECK: ret
+
+entry:
+ %a = alloca { i32 }
+ %b = alloca i32*
+ %a.1 = getelementptr { i32 }* %a, i32 0, i32 0
+ store i32 123, i32* %a.1
+ store i32* %a.1, i32** %b
+ %b.1 = bitcast i32** %b to i32*
+ store i32 123, i32* %b.1
+ %a.2 = getelementptr { i32 }* %a, i32 0, i32 0
+ store atomic i32 2, i32* %a.2 unordered, align 4
+ %a.3 = getelementptr { i32 }* %a, i32 0, i32 0
+ store atomic i32 3, i32* %a.3 release, align 4
+ %a.4 = getelementptr { i32 }* %a, i32 0, i32 0
+ store atomic i32 4, i32* %a.4 seq_cst, align 4
+ ret void
+}
+
+declare void @f(i32* %p)
+
+; Check that we don't delete allocas in some erroneous cases.
+define void @test6() {
+; CHECK: @test6
+; CHECK-NOT: ret
+; CHECK: alloca
+; CHECK-NEXT: alloca
+; CHECK: ret
+
+entry:
+ %a = alloca { i32 }
+ %b = alloca i32
+ %a.1 = getelementptr { i32 }* %a, i32 0, i32 0
+ store volatile i32 123, i32* %a.1
+ tail call void @f(i32* %b)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/apint-shl-trunc.ll b/test/Transforms/InstCombine/apint-shl-trunc.ll
index 8163e6d..f2dc7d5 100644
--- a/test/Transforms/InstCombine/apint-shl-trunc.ll
+++ b/test/Transforms/InstCombine/apint-shl-trunc.ll
@@ -1,13 +1,24 @@
-; RUN: opt < %s -instcombine -S | grep shl
-; END.
+; RUN: opt < %s -instcombine -S | FileCheck %s
define i1 @test0(i39 %X, i39 %A) {
+; CHECK: @test0
+; CHECK: %[[V1:.*]] = shl i39 1, %A
+; CHECK: %[[V2:.*]] = and i39 %[[V1]], %X
+; CHECK: %[[V3:.*]] = icmp ne i39 %[[V2]], 0
+; CHECK: ret i1 %[[V3]]
+
%B = lshr i39 %X, %A
%D = trunc i39 %B to i1
ret i1 %D
}
define i1 @test1(i799 %X, i799 %A) {
+; CHECK: @test1
+; CHECK: %[[V1:.*]] = shl i799 1, %A
+; CHECK: %[[V2:.*]] = and i799 %[[V1]], %X
+; CHECK: %[[V3:.*]] = icmp ne i799 %[[V2]], 0
+; CHECK: ret i1 %[[V3]]
+
%B = lshr i799 %X, %A
%D = trunc i799 %B to i1
ret i1 %D
diff --git a/test/Transforms/InstCombine/bitcount.ll b/test/Transforms/InstCombine/bitcount.ll
index f75ca2d..a6fd837 100644
--- a/test/Transforms/InstCombine/bitcount.ll
+++ b/test/Transforms/InstCombine/bitcount.ll
@@ -4,13 +4,13 @@
; RUN: grep -v declare | not grep llvm.ct
declare i31 @llvm.ctpop.i31(i31 %val)
-declare i32 @llvm.cttz.i32(i32 %val)
-declare i33 @llvm.ctlz.i33(i33 %val)
+declare i32 @llvm.cttz.i32(i32 %val, i1)
+declare i33 @llvm.ctlz.i33(i33 %val, i1)
define i32 @test(i32 %A) {
%c1 = call i31 @llvm.ctpop.i31(i31 12415124)
- %c2 = call i32 @llvm.cttz.i32(i32 87359874)
- %c3 = call i33 @llvm.ctlz.i33(i33 87359874)
+ %c2 = call i32 @llvm.cttz.i32(i32 87359874, i1 true)
+ %c3 = call i33 @llvm.ctlz.i33(i33 87359874, i1 true)
%t1 = zext i31 %c1 to i32
%t3 = trunc i33 %c3 to i32
%r1 = add i32 %t1, %c2
diff --git a/test/Transforms/InstCombine/constant-fold-gep.ll b/test/Transforms/InstCombine/constant-fold-gep.ll
index c679226..e5b16ea 100644
--- a/test/Transforms/InstCombine/constant-fold-gep.ll
+++ b/test/Transforms/InstCombine/constant-fold-gep.ll
@@ -9,7 +9,7 @@ target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
@Y = internal global [3 x %struct.X] zeroinitializer
define void @frob() {
-; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0), align 8
+; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0), align 16
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 0), align 4
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 1), align 4
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 1), align 4
@@ -33,7 +33,7 @@ define void @frob() {
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 10), align 4
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 1, i32 1, i64 2), align 4
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 11), align 4
-; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 0), align 8
+; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 0), align 16
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 12), align 4
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 0, i64 2, i32 0, i64 1), align 4
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 13), align 4
@@ -47,7 +47,7 @@ define void @frob() {
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 17), align 8
; CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.X]* @Y, i64 1, i64 0, i32 0, i64 0), align 8
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 18), align 8
-; CHECK: store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 2, i64 0, i32 0, i64 0), align 8
+; CHECK: store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 2, i64 0, i32 0, i64 0), align 16
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 36), align 8
; CHECK: store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 1, i64 0, i32 0, i64 1), align 8
store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 19), align 8
diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll
index 54a77aa..d5af532 100644
--- a/test/Transforms/InstCombine/crash.ll
+++ b/test/Transforms/InstCombine/crash.ll
@@ -165,20 +165,19 @@ entry:
br i1 %tobool, label %cond.end, label %cond.false
terminate.handler: ; preds = %ehcleanup
- %exc = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
- %0 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
+ %exc = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
call void @_ZSt9terminatev() noreturn nounwind
unreachable
ehcleanup: ; preds = %cond.false
- %exc1 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
- %1 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc1, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; <i32> [#uses=0]
+ %exc1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
invoke void @_ZN6UStackD1Ev(%class.UStack* %breaks)
to label %cont unwind label %terminate.handler
cont: ; preds = %ehcleanup
- call void @_Unwind_Resume_or_Rethrow(i8* %exc1)
- unreachable
+ resume { i8*, i32 } %exc1
cond.false: ; preds = %entry
%tmp4 = getelementptr inbounds %class.RuleBasedBreakIterator* %this, i32 0, i32 0 ; <i64 ()**> [#uses=1]
@@ -199,10 +198,6 @@ declare void @_ZN6UStackD1Ev(%class.UStack*)
declare i32 @__gxx_personality_v0(...)
-declare i8* @llvm.eh.exception() nounwind readonly
-
-declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
-
declare void @_ZSt9terminatev()
declare void @_Unwind_Resume_or_Rethrow(i8*)
diff --git a/test/Transforms/InstCombine/dg.exp b/test/Transforms/InstCombine/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/InstCombine/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/InstCombine/extractvalue.ll b/test/Transforms/InstCombine/extractvalue.ll
index cf36b8f..5e4c677 100644
--- a/test/Transforms/InstCombine/extractvalue.ll
+++ b/test/Transforms/InstCombine/extractvalue.ll
@@ -88,7 +88,7 @@ define i32 @doubleextract2gep({i32, {i32, i32}}* %arg) {
; CHECK-NEXT: ret
define i32 @nogep-multiuse({i32, i32}* %pair) {
; The load should be left unchanged since both parts are needed.
- %L = volatile load {i32, i32}* %pair
+ %L = load volatile {i32, i32}* %pair
%LHS = extractvalue {i32, i32} %L, 0
%RHS = extractvalue {i32, i32} %L, 1
%R = add i32 %LHS, %RHS
@@ -100,8 +100,8 @@ define i32 @nogep-multiuse({i32, i32}* %pair) {
; CHECK-NEXT: extractvalue
; CHECK-NEXT: ret
define i32 @nogep-volatile({i32, i32}* %pair) {
- ; The volatile load should be left unchanged.
- %L = volatile load {i32, i32}* %pair
+ ; The load volatile should be left unchanged.
+ %L = load volatile {i32, i32}* %pair
%E = extractvalue {i32, i32} %L, 1
ret i32 %E
}
diff --git a/test/Transforms/InstCombine/fold-sqrt-sqrtf.ll b/test/Transforms/InstCombine/fold-sqrt-sqrtf.ll
new file mode 100644
index 0000000..bd92b4a
--- /dev/null
+++ b/test/Transforms/InstCombine/fold-sqrt-sqrtf.ll
@@ -0,0 +1,17 @@
+; RUN: opt -instcombine -S -disable-simplify-libcalls < %s | FileCheck %s
+; rdar://10466410
+
+; Instcombine tries to fold (fptrunc (sqrt (fpext x))) -> (sqrtf x), but this
+; shouldn't fold when sqrtf isn't available.
+define float @foo(float %f) uwtable ssp {
+entry:
+; CHECK: %conv = fpext float %f to double
+; CHECK: %call = tail call double @sqrt(double %conv)
+; CHECK: %conv1 = fptrunc double %call to float
+ %conv = fpext float %f to double
+ %call = tail call double @sqrt(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
+}
+
+declare double @sqrt(double)
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 77ca62c..a9ae221 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -121,8 +121,8 @@ define i1 @test12(i1 %A) {
%B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
ret i1 %B
; CHECK: @test12
-; CHECK-NEXT: %B = select i1
-; CHECK-NEXT: ret i1 %B
+; CHECK-NEXT: = xor i1 %A, true
+; CHECK-NEXT: ret i1
}
; PR6481
@@ -524,7 +524,7 @@ define i1 @test53(i32 %a, i32 %b) nounwind {
; CHECK: @test54
; CHECK-NEXT: %and = and i8 %a, -64
-; CHECK-NEXT icmp eq i8 %and, -128
+; CHECK-NEXT: icmp eq i8 %and, -128
define i1 @test54(i8 %a) nounwind {
%ext = zext i8 %a to i32
%and = and i32 %ext, 192
@@ -559,3 +559,81 @@ define i1 @test57(i32 %a) {
call void @foo(i32 %and)
ret i1 %cmp
}
+
+; rdar://problem/10482509
+; CHECK: @cmpabs1
+; CHECK-NEXT: icmp ne
+define zeroext i1 @cmpabs1(i64 %val) {
+ %sub = sub nsw i64 0, %val
+ %cmp = icmp slt i64 %val, 0
+ %sub.val = select i1 %cmp, i64 %sub, i64 %val
+ %tobool = icmp ne i64 %sub.val, 0
+ ret i1 %tobool
+}
+
+; CHECK: @cmpabs2
+; CHECK-NEXT: icmp ne
+define zeroext i1 @cmpabs2(i64 %val) {
+ %sub = sub nsw i64 0, %val
+ %cmp = icmp slt i64 %val, 0
+ %sub.val = select i1 %cmp, i64 %val, i64 %sub
+ %tobool = icmp ne i64 %sub.val, 0
+ ret i1 %tobool
+}
+
+; CHECK: @test58
+; CHECK-NEXT: call i32 @test58_d(i64 36029346783166592)
+define void @test58() nounwind {
+ %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
+ %call = call i32 @test58_d( i64 %cast) nounwind
+ ret void
+}
+declare i32 @test58_d(i64)
+
+define i1 @test59(i8* %foo) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr inbounds i32* %bit, i64 2
+ %gep2 = getelementptr inbounds i8* %foo, i64 10
+ %cast1 = bitcast i32* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ %use = ptrtoint i8* %cast1 to i64
+ %call = call i32 @test58_d(i64 %use) nounwind
+ ret i1 %cmp
+; CHECK: @test59
+; CHECK: ret i1 true
+}
+
+define i1 @test60(i8* %foo, i64 %i, i64 %j) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr inbounds i32* %bit, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = bitcast i32* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ ret i1 %cmp
+; CHECK: @test60
+; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
+; CHECK-NEXT: icmp slt i64 %gep1.idx, %j
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test61(i8* %foo, i64 %i, i64 %j) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr i32* %bit, i64 %i
+ %gep2 = getelementptr i8* %foo, i64 %j
+ %cast1 = bitcast i32* %gep1 to i8*
+ %cmp = icmp ult i8* %cast1, %gep2
+ ret i1 %cmp
+; Don't transform non-inbounds GEPs.
+; CHECK: @test61
+; CHECK: icmp ult i8* %cast1, %gep2
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test62(i8* %a) {
+ %arrayidx1 = getelementptr inbounds i8* %a, i64 1
+ %arrayidx2 = getelementptr inbounds i8* %a, i64 10
+ %cmp = icmp slt i8* %arrayidx1, %arrayidx2
+ ret i1 %cmp
+; CHECK: @test62
+; CHECK-NEXT: ret i1 true
+}
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index f033e51..382e6b3 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -5,10 +5,10 @@
declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
declare double @llvm.powi.f64(double, i32) nounwind readonly
-declare i32 @llvm.cttz.i32(i32) nounwind readnone
-declare i32 @llvm.ctlz.i32(i32) nounwind readnone
+declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
+declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
declare i32 @llvm.ctpop.i32(i32) nounwind readnone
-declare i8 @llvm.ctlz.i8(i8) nounwind readnone
+declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone
define i8 @uaddtest1(i8 %A, i8 %B) {
%x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B)
@@ -142,13 +142,13 @@ define i32 @umultest4(i32 %n) nounwind {
define void @powi(double %V, double *%P) {
entry:
%A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind
- volatile store double %A, double* %P
+ store volatile double %A, double* %P
%B = tail call double @llvm.powi.f64(double %V, i32 0) nounwind
- volatile store double %B, double* %P
+ store volatile double %B, double* %P
%C = tail call double @llvm.powi.f64(double %V, i32 1) nounwind
- volatile store double %C, double* %P
+ store volatile double %C, double* %P
ret void
; CHECK: @powi
; CHECK: %A = fdiv double 1.0{{.*}}, %V
@@ -161,7 +161,7 @@ define i32 @cttz(i32 %a) {
entry:
%or = or i32 %a, 8
%and = and i32 %or, -8
- %count = tail call i32 @llvm.cttz.i32(i32 %and) nounwind readnone
+ %count = tail call i32 @llvm.cttz.i32(i32 %and, i1 true) nounwind readnone
ret i32 %count
; CHECK: @cttz
; CHECK-NEXT: entry:
@@ -172,7 +172,7 @@ define i8 @ctlz(i8 %a) {
entry:
%or = or i8 %a, 32
%and = and i8 %or, 63
- %count = tail call i8 @llvm.ctlz.i8(i8 %and) nounwind readnone
+ %count = tail call i8 @llvm.ctlz.i8(i8 %and, i1 true) nounwind readnone
ret i8 %count
; CHECK: @ctlz
; CHECK-NEXT: entry:
@@ -181,15 +181,15 @@ entry:
define void @cmp.simplify(i32 %a, i32 %b, i1* %c) {
entry:
- %lz = tail call i32 @llvm.ctlz.i32(i32 %a) nounwind readnone
+ %lz = tail call i32 @llvm.ctlz.i32(i32 %a, i1 false) nounwind readnone
%lz.cmp = icmp eq i32 %lz, 32
- volatile store i1 %lz.cmp, i1* %c
- %tz = tail call i32 @llvm.cttz.i32(i32 %a) nounwind readnone
+ store volatile i1 %lz.cmp, i1* %c
+ %tz = tail call i32 @llvm.cttz.i32(i32 %a, i1 false) nounwind readnone
%tz.cmp = icmp ne i32 %tz, 32
- volatile store i1 %tz.cmp, i1* %c
+ store volatile i1 %tz.cmp, i1* %c
%pop = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone
%pop.cmp = icmp eq i32 %pop, 0
- volatile store i1 %pop.cmp, i1* %c
+ store volatile i1 %pop.cmp, i1* %c
ret void
; CHECK: @cmp.simplify
; CHECK-NEXT: entry:
@@ -201,16 +201,22 @@ entry:
; CHECK-NEXT: store volatile i1 %pop.cmp, i1* %c
}
-
-define i32 @cttz_simplify1(i32 %x) nounwind readnone ssp {
- %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x) ; <i32> [#uses=1]
- %shr3 = lshr i32 %tmp1, 5 ; <i32> [#uses=1]
+define i32 @cttz_simplify1a(i32 %x) nounwind readnone ssp {
+ %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+ %shr3 = lshr i32 %tmp1, 5
ret i32 %shr3
-
-; CHECK: @cttz_simplify1
+
+; CHECK: @cttz_simplify1a
; CHECK: icmp eq i32 %x, 0
-; CHECK-NEXT: zext i1
+; CHECK-NEXT: zext i1
; CHECK-NEXT: ret i32
}
+define i32 @cttz_simplify1b(i32 %x) nounwind readnone ssp {
+ %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %shr3 = lshr i32 %tmp1, 5
+ ret i32 %shr3
+; CHECK: @cttz_simplify1b
+; CHECK-NEXT: ret i32 0
+}
diff --git a/test/Transforms/InstCombine/lit.local.cfg b/test/Transforms/InstCombine/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/InstCombine/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index 53a5643..edb5305 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -1,116 +1,184 @@
; This test makes sure that mul instructions are properly eliminated.
-; RUN: opt < %s -instcombine -S | not grep mul
+; RUN: opt < %s -instcombine -S | FileCheck %s
define i32 @test1(i32 %A) {
+; CHECK: @test1
%B = mul i32 %A, 1 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: ret i32 %A
}
define i32 @test2(i32 %A) {
+; CHECK: @test2
; Should convert to an add instruction
%B = mul i32 %A, 2 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: shl i32 %A, 1
}
define i32 @test3(i32 %A) {
+; CHECK: @test3
; This should disappear entirely
%B = mul i32 %A, 0 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: ret i32 0
}
define double @test4(double %A) {
+; CHECK: @test4
; This is safe for FP
%B = fmul double 1.000000e+00, %A ; <double> [#uses=1]
ret double %B
+; CHECK: ret double %A
}
define i32 @test5(i32 %A) {
+; CHECK: @test5
%B = mul i32 %A, 8 ; <i32> [#uses=1]
ret i32 %B
+; CHECK: shl i32 %A, 3
}
define i8 @test6(i8 %A) {
+; CHECK: @test6
%B = mul i8 %A, 8 ; <i8> [#uses=1]
%C = mul i8 %B, 8 ; <i8> [#uses=1]
ret i8 %C
+; CHECK: shl i8 %A, 6
}
define i32 @test7(i32 %i) {
+; CHECK: @test7
%tmp = mul i32 %i, -1 ; <i32> [#uses=1]
ret i32 %tmp
+; CHECK: sub i32 0, %i
}
define i64 @test8(i64 %i) {
- ; tmp = sub 0, %i
+; CHECK: @test8
%j = mul i64 %i, -1 ; <i64> [#uses=1]
ret i64 %j
+; CHECK: sub i64 0, %i
}
define i32 @test9(i32 %i) {
- ; %j = sub 0, %i
+; CHECK: @test9
%j = mul i32 %i, -1 ; <i32> [#uses=1]
ret i32 %j
+; CHECJ: sub i32 0, %i
}
define i32 @test10(i32 %a, i32 %b) {
+; CHECK: @test10
%c = icmp slt i32 %a, 0 ; <i1> [#uses=1]
%d = zext i1 %c to i32 ; <i32> [#uses=1]
; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST10:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST10]], %b
+; CHECK-NEXT: ret i32 %e
}
define i32 @test11(i32 %a, i32 %b) {
+; CHECK: @test11
%c = icmp sle i32 %a, -1 ; <i1> [#uses=1]
%d = zext i1 %c to i32 ; <i32> [#uses=1]
; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST11:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST11]], %b
+; CHECK-NEXT: ret i32 %e
}
-define i32 @test12(i8 %a, i32 %b) {
- %c = icmp ugt i8 %a, 127 ; <i1> [#uses=1]
+define i32 @test12(i32 %a, i32 %b) {
+; CHECK: @test12
+ %c = icmp ugt i32 %a, 2147483647 ; <i1> [#uses=1]
%d = zext i1 %c to i32 ; <i32> [#uses=1]
- ; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST12:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST12]], %b
+; CHECK-NEXT: ret i32 %e
+
}
; PR2642
define internal void @test13(<4 x float>*) {
+; CHECK: @test13
load <4 x float>* %0, align 1
fmul <4 x float> %2, < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >
store <4 x float> %3, <4 x float>* %0, align 1
ret void
+; CHECK-NEXT: ret void
}
define <16 x i8> @test14(<16 x i8> %a) {
+; CHECK: @test14
%b = mul <16 x i8> %a, zeroinitializer
ret <16 x i8> %b
+; CHECK-NEXT: ret <16 x i8> zeroinitializer
}
; rdar://7293527
define i32 @test15(i32 %A, i32 %B) {
+; CHECK: @test15
entry:
%shl = shl i32 1, %B
%m = mul i32 %shl, %A
ret i32 %m
+; CHECK: shl i32 %A, %B
}
; X * Y (when Y is 0 or 1) --> x & (0-Y)
define i32 @test16(i32 %b, i1 %c) {
+; CHECK: @test16
%d = zext i1 %c to i32 ; <i32> [#uses=1]
; e = b & (a >> 31)
%e = mul i32 %d, %b ; <i32> [#uses=1]
ret i32 %e
+; CHECK: [[TEST16:%.*]] = sext i1 %c to i32
+; CHECK-NEXT: %e = and i32 [[TEST16]], %b
+; CHECK-NEXT: ret i32 %e
}
; X * Y (when Y is 0 or 1) --> x & (0-Y)
define i32 @test17(i32 %a, i32 %b) {
+; CHECK: @test17
%a.lobit = lshr i32 %a, 31
%e = mul i32 %a.lobit, %b
ret i32 %e
+; CHECK: [[TEST17:%.*]] = ashr i32 %a, 31
+; CHECK-NEXT: %e = and i32 [[TEST17]], %b
+; CHECK-NEXT: ret i32 %e
+}
+
+define i32 @test18(i32 %A, i32 %B) {
+; CHECK: @test18
+ %C = and i32 %A, 1
+ %D = and i32 %B, 1
+
+ %E = mul i32 %C, %D
+ %F = and i32 %E, 16
+ ret i32 %F
+; CHECK-NEXT: ret i32 0
}
+declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
+declare void @use(i1)
+define i32 @test19(i32 %A, i32 %B) {
+; CHECK: @test19
+ %C = and i32 %A, 1
+ %D = and i32 %B, 1
+; It would be nice if we also started proving that this doesn't overflow.
+ %E = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %C, i32 %D)
+ %F = extractvalue {i32, i1} %E, 0
+ %G = extractvalue {i32, i1} %E, 1
+ call void @use(i1 %G)
+ %H = and i32 %F, 16
+ ret i32 %H
+; CHECK: ret i32 0
+}
diff --git a/test/Transforms/InstCombine/overflow.ll b/test/Transforms/InstCombine/overflow.ll
index 9123283..81ceef8 100644
--- a/test/Transforms/InstCombine/overflow.ll
+++ b/test/Transforms/InstCombine/overflow.ll
@@ -130,4 +130,26 @@ entry:
ret i64 %Q
}
+; CHECK: @test8
+; PR11438
+; This is @test1, but the operands are not sign-extended. Make sure
+; we don't transform this case.
+define i32 @test8(i64 %a, i64 %b) nounwind ssp {
+entry:
+; CHECK-NOT: llvm.sadd
+; CHECK: add i64 %a, %b
+; CHECK-NOT: llvm.sadd
+; CHECK: ret
+ %add = add i64 %a, %b
+ %add.off = add i64 %add, 2147483648
+ %0 = icmp ugt i64 %add.off, 4294967295
+ br i1 %0, label %if.then, label %if.end
+
+if.then:
+ tail call void @throwAnExceptionOrWhatever() nounwind
+ br label %if.end
+if.end:
+ %conv9 = trunc i64 %add to i32
+ ret i32 %conv9
+}
diff --git a/test/Transforms/InstCombine/pr12251.ll b/test/Transforms/InstCombine/pr12251.ll
new file mode 100644
index 0000000..74a41eb
--- /dev/null
+++ b/test/Transforms/InstCombine/pr12251.ll
@@ -0,0 +1,15 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define zeroext i1 @_Z3fooPb(i8* nocapture %x) {
+entry:
+ %a = load i8* %x, align 1, !range !0
+ %b = and i8 %a, 1
+ %tobool = icmp ne i8 %b, 0
+ ret i1 %tobool
+}
+
+; CHECK: %a = load i8* %x, align 1, !range !0
+; CHECK-NEXT: %tobool = icmp ne i8 %a, 0
+; CHECK-NEXT: ret i1 %tobool
+
+!0 = metadata !{i8 0, i8 2}
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 4661561..4baae26 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -809,3 +809,23 @@ define i32 @test61(i32* %ptr) {
; CHECK: @test61
; CHECK: ret i32 10
}
+
+define i1 @test62(i1 %A, i1 %B) {
+ %not = xor i1 %A, true
+ %C = select i1 %A, i1 %not, i1 %B
+ ret i1 %C
+; CHECK: @test62
+; CHECK: %not = xor i1 %A, true
+; CHECK: %C = and i1 %not, %B
+; CHECK: ret i1 %C
+}
+
+define i1 @test63(i1 %A, i1 %B) {
+ %not = xor i1 %A, true
+ %C = select i1 %A, i1 %B, i1 %not
+ ret i1 %C
+; CHECK: @test63
+; CHECK: %not = xor i1 %A, true
+; CHECK: %C = or i1 %B, %not
+; CHECK: ret i1 %C
+}
diff --git a/test/Transforms/InstCombine/sext.ll b/test/Transforms/InstCombine/sext.ll
index f49a2ef..f198797 100644
--- a/test/Transforms/InstCombine/sext.ll
+++ b/test/Transforms/InstCombine/sext.ll
@@ -3,8 +3,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"
declare i32 @llvm.ctpop.i32(i32)
-declare i32 @llvm.ctlz.i32(i32)
-declare i32 @llvm.cttz.i32(i32)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
define i64 @test1(i32 %x) {
%t = call i32 @llvm.ctpop.i32(i32 %x)
@@ -16,7 +16,7 @@ define i64 @test1(i32 %x) {
}
define i64 @test2(i32 %x) {
- %t = call i32 @llvm.ctlz.i32(i32 %x)
+ %t = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
%s = sext i32 %t to i64
ret i64 %s
@@ -25,7 +25,7 @@ define i64 @test2(i32 %x) {
}
define i64 @test3(i32 %x) {
- %t = call i32 @llvm.cttz.i32(i32 %x)
+ %t = call i32 @llvm.cttz.i32(i32 %x, i1 true)
%s = sext i32 %t to i64
ret i64 %s
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll
index 132d51a..52310e3 100644
--- a/test/Transforms/InstCombine/shift.ll
+++ b/test/Transforms/InstCombine/shift.ll
@@ -542,3 +542,75 @@ define i32 @test45(i32 %a) nounwind {
; CHECK-NEXT: %y = lshr i32 %a, 5
; CHECK-NEXT: ret i32 %y
}
+
+define i32 @test46(i32 %a) {
+ %y = ashr exact i32 %a, 3
+ %z = shl i32 %y, 1
+ ret i32 %z
+; CHECK: @test46
+; CHECK-NEXT: %z = ashr exact i32 %a, 2
+; CHECK-NEXT: ret i32 %z
+}
+
+define i32 @test47(i32 %a) {
+ %y = lshr exact i32 %a, 3
+ %z = shl i32 %y, 1
+ ret i32 %z
+; CHECK: @test47
+; CHECK-NEXT: %z = lshr exact i32 %a, 2
+; CHECK-NEXT: ret i32 %z
+}
+
+define i32 @test48(i32 %x) {
+ %A = lshr exact i32 %x, 1
+ %B = shl i32 %A, 3
+ ret i32 %B
+; CHECK: @test48
+; CHECK-NEXT: %B = shl i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test49(i32 %x) {
+ %A = ashr exact i32 %x, 1
+ %B = shl i32 %A, 3
+ ret i32 %B
+; CHECK: @test49
+; CHECK-NEXT: %B = shl i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test50(i32 %x) {
+ %A = shl nsw i32 %x, 1
+ %B = ashr i32 %A, 3
+ ret i32 %B
+; CHECK: @test50
+; CHECK-NEXT: %B = ashr i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test51(i32 %x) {
+ %A = shl nuw i32 %x, 1
+ %B = lshr i32 %A, 3
+ ret i32 %B
+; CHECK: @test51
+; CHECK-NEXT: %B = lshr i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test52(i32 %x) {
+ %A = shl nsw i32 %x, 3
+ %B = ashr i32 %A, 1
+ ret i32 %B
+; CHECK: @test52
+; CHECK-NEXT: %B = shl nsw i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
+
+define i32 @test53(i32 %x) {
+ %A = shl nuw i32 %x, 3
+ %B = lshr i32 %A, 1
+ ret i32 %B
+; CHECK: @test53
+; CHECK-NEXT: %B = shl nuw i32 %x, 2
+; CHECK-NEXT: ret i32 %B
+}
diff --git a/test/Transforms/InstCombine/sign-test-and-or.ll b/test/Transforms/InstCombine/sign-test-and-or.ll
index 47f5f30..a6066d8 100644
--- a/test/Transforms/InstCombine/sign-test-and-or.ll
+++ b/test/Transforms/InstCombine/sign-test-and-or.ll
@@ -77,3 +77,103 @@ if.then:
if.end:
ret void
}
+
+define void @test5(i32 %a) nounwind {
+ %and = and i32 %a, 134217728
+ %1 = icmp eq i32 %and, 0
+ %2 = icmp sgt i32 %a, -1
+ %or.cond = and i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test5
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test6(i32 %a) nounwind {
+ %1 = icmp sgt i32 %a, -1
+ %and = and i32 %a, 134217728
+ %2 = icmp eq i32 %and, 0
+ %or.cond = and i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test6
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test7(i32 %a) nounwind {
+ %and = and i32 %a, 134217728
+ %1 = icmp ne i32 %and, 0
+ %2 = icmp slt i32 %a, 0
+ %or.cond = or i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test7
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test8(i32 %a) nounwind {
+ %1 = icmp slt i32 %a, 0
+ %and = and i32 %a, 134217728
+ %2 = icmp ne i32 %and, 0
+ %or.cond = or i1 %1, %2
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test8
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
+
+define void @test9(i32 %a) nounwind {
+ %1 = and i32 %a, 1073741824
+ %2 = icmp ne i32 %1, 0
+ %3 = icmp sgt i32 %a, -1
+ %or.cond = and i1 %2, %3
+ br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test9
+; CHECK-NEXT: %1 = and i32 %a, -1073741824
+; CHECK-NEXT: %2 = icmp eq i32 %1, 1073741824
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo() nounwind
+ ret void
+
+if.end:
+ ret void
+}
diff --git a/test/Transforms/InstCombine/sub-xor.ll b/test/Transforms/InstCombine/sub-xor.ll
new file mode 100644
index 0000000..279e4ac
--- /dev/null
+++ b/test/Transforms/InstCombine/sub-xor.ll
@@ -0,0 +1,37 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+define i32 @test1(i32 %x) nounwind {
+ %and = and i32 %x, 31
+ %sub = sub i32 63, %and
+ ret i32 %sub
+
+; CHECK: @test1
+; CHECK-NEXT: and i32 %x, 31
+; CHECK-NEXT: xor i32 %and, 63
+; CHECK-NEXT: ret
+}
+
+declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
+
+define i32 @test2(i32 %x) nounwind {
+ %count = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) nounwind readnone
+ %sub = sub i32 31, %count
+ ret i32 %sub
+
+; CHECK: @test2
+; CHECK-NEXT: ctlz
+; CHECK-NEXT: xor i32 %count, 31
+; CHECK-NEXT: ret
+}
+
+define i32 @test3(i32 %x) nounwind {
+ %and = and i32 %x, 31
+ %sub = xor i32 31, %and
+ %add = add i32 %sub, 42
+ ret i32 %add
+
+; CHECK: @test3
+; CHECK-NEXT: and i32 %x, 31
+; CHECK-NEXT: sub i32 73, %and
+; CHECK-NEXT: ret
+}
diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll
index 37de328..b71ec8c 100644
--- a/test/Transforms/InstCombine/sub.ll
+++ b/test/Transforms/InstCombine/sub.ll
@@ -301,3 +301,29 @@ define i32 @test28(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: add i32
; CHECK-NEXT: ret i32
}
+
+define i64 @test29(i8* %foo, i64 %i, i64 %j) {
+ %gep1 = getelementptr inbounds i8* %foo, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = ptrtoint i8* %gep1 to i64
+ %cast2 = ptrtoint i8* %gep2 to i64
+ %sub = sub i64 %cast1, %cast2
+ ret i64 %sub
+; CHECK: @test29
+; CHECK-NEXT: sub i64 %i, %j
+; CHECK-NEXT: ret i64
+}
+
+define i64 @test30(i8* %foo, i64 %i, i64 %j) {
+ %bit = bitcast i8* %foo to i32*
+ %gep1 = getelementptr inbounds i32* %bit, i64 %i
+ %gep2 = getelementptr inbounds i8* %foo, i64 %j
+ %cast1 = ptrtoint i32* %gep1 to i64
+ %cast2 = ptrtoint i8* %gep2 to i64
+ %sub = sub i64 %cast1, %cast2
+ ret i64 %sub
+; CHECK: @test30
+; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
+; CHECK-NEXT: sub i64 %gep1.idx, %j
+; CHECK-NEXT: ret i64
+}
diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll
index 896cb88..8f78c2e 100644
--- a/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/test/Transforms/InstCombine/vec_shuffle.ll
@@ -98,6 +98,17 @@ define <4 x i8> @test9a(<16 x i8> %tmp6) nounwind {
ret <4 x i8> %tmp9
}
+; Test fold of two shuffles where the first shuffle vectors inputs are a
+; different length then the second.
+define <4 x i8> @test9b(<4 x i8> %tmp6, <4 x i8> %tmp7) nounwind {
+; CHECK: @test9
+; CHECK-NEXT: shufflevector
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <4 x i8> %tmp6, <4 x i8> %tmp7, <8 x i32> <i32 0, i32 1, i32 4, i32 5, i32 4, i32 5, i32 2, i32 3> ; <<4 x i8>> [#uses=1]
+ %tmp9 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5> ; <<4 x i8>> [#uses=1]
+ ret <4 x i8> %tmp9
+}
+
; Redundant vector splats should be removed. Radar 8597790.
define <4 x i32> @test10(<4 x i32> %tmp5) nounwind {
; CHECK: @test10
@@ -107,3 +118,38 @@ define <4 x i32> @test10(<4 x i32> %tmp5) nounwind {
%tmp7 = shufflevector <4 x i32> %tmp6, <4 x i32> undef, <4 x i32> zeroinitializer
ret <4 x i32> %tmp7
}
+
+; Test fold of two shuffles where the two shufflevector inputs's op1 are
+; the same
+define <8 x i8> @test11(<16 x i8> %tmp6) nounwind {
+; CHECK: @test11
+; CHECK-NEXT: shufflevector <16 x i8> %tmp6, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x i8>> [#uses=1]
+ %tmp2 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> ; <<4 x i8>> [#uses=1]
+ %tmp3 = shufflevector <4 x i8> %tmp1, <4 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> ; <<8 x i8>> [#uses=1]
+ ret <8 x i8> %tmp3
+}
+
+; Test fold of two shuffles where the first shufflevector's inputs are
+; the same as the second
+define <8 x i8> @test12(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind {
+; CHECK: @test12
+; CHECK-NEXT: shufflevector <8 x i8> %tmp6, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12>
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7> ; <<8 x i8>> [#uses=1]
+ %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12> ; <<8 x i8>> [#uses=1]
+ ret <8 x i8> %tmp3
+}
+
+; Test fold of two shuffles where the first shufflevector's inputs are
+; the same as the second
+define <8 x i8> @test12a(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind {
+; CHECK: @test12a
+; CHECK-NEXT: shufflevector <8 x i8> %tmp2, <8 x i8> %tmp6, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11>
+; CHECK-NEXT: ret
+ %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7> ; <<8 x i8>> [#uses=1]
+ %tmp3 = shufflevector <8 x i8> %tmp2, <8 x i8> %tmp1, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11> ; <<8 x i8>> [#uses=1]
+ ret <8 x i8> %tmp3
+}
+
diff --git a/test/Transforms/InstCombine/vector_gep1.ll b/test/Transforms/InstCombine/vector_gep1.ll
new file mode 100644
index 0000000..6523622
--- /dev/null
+++ b/test/Transforms/InstCombine/vector_gep1.ll
@@ -0,0 +1,37 @@
+; RUN: opt -instcombine %s -disable-output
+; RUN: opt -instsimplify %s -disable-output
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@G1 = global i8 zeroinitializer
+
+define <2 x i1> @test(<2 x i8*> %a, <2 x i8*> %b) {
+ %A = icmp eq <2 x i8*> %a, %b
+ ret <2 x i1> %A
+}
+
+define <2 x i1> @test2(<2 x i8*> %a) {
+ %A = inttoptr <2 x i32> <i32 1, i32 2> to <2 x i8*>
+ %B = icmp ult <2 x i8*> %A, zeroinitializer
+ ret <2 x i1> %B
+}
+
+define <2 x i1> @test3(<2 x i8*> %a) {
+ %g = getelementptr <2 x i8*> %a, <2 x i32> <i32 1, i32 0>
+ %B = icmp ult <2 x i8*> %g, zeroinitializer
+ ret <2 x i1> %B
+}
+
+define <1 x i1> @test4(<1 x i8*> %a) {
+ %g = getelementptr <1 x i8*> %a, <1 x i32> <i32 1>
+ %B = icmp ult <1 x i8*> %g, zeroinitializer
+ ret <1 x i1> %B
+}
+
+define <2 x i1> @test5(<2 x i8*> %a) {
+ %w = getelementptr <2 x i8*> %a, <2 x i32> zeroinitializer
+ %e = getelementptr <2 x i8*> %w, <2 x i32> <i32 5, i32 9>
+ %g = getelementptr <2 x i8*> %e, <2 x i32> <i32 1, i32 0>
+ %B = icmp ult <2 x i8*> %g, zeroinitializer
+ ret <2 x i1> %B
+}
diff --git a/test/Transforms/InstCombine/volatile_store.ll b/test/Transforms/InstCombine/volatile_store.ll
index 0518e5a..2256678 100644
--- a/test/Transforms/InstCombine/volatile_store.ll
+++ b/test/Transforms/InstCombine/volatile_store.ll
@@ -5,8 +5,8 @@
define void @self_assign_1() {
entry:
- %tmp = volatile load i32* @x ; <i32> [#uses=1]
- volatile store i32 %tmp, i32* @x
+ %tmp = load volatile i32* @x ; <i32> [#uses=1]
+ store volatile i32 %tmp, i32* @x
br label %return
return: ; preds = %entry
diff --git a/test/Transforms/InstSimplify/2011-10-27-BinOpCrash.ll b/test/Transforms/InstSimplify/2011-10-27-BinOpCrash.ll
new file mode 100644
index 0000000..a10081a
--- /dev/null
+++ b/test/Transforms/InstSimplify/2011-10-27-BinOpCrash.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -instcombine
+
+@_ZN11xercesc_2_5L11gDigitCharsE = external constant [32 x i16], align 2
+@_ZN11xercesc_2_5L10gBaseCharsE = external constant [354 x i16], align 2
+@_ZN11xercesc_2_5L17gIdeographicCharsE = external constant [7 x i16], align 2
+@_ZN11xercesc_2_5L15gCombiningCharsE = external constant [163 x i16], align 2
+
+define i32 @_ZN11xercesc_2_515XMLRangeFactory11buildRangesEv(i32 %x) {
+ %a = add i32 %x, add (i32 add (i32 ashr (i32 add (i32 mul (i32 ptrtoint ([32 x i16]* @_ZN11xercesc_2_5L11gDigitCharsE to i32), i32 -1), i32 ptrtoint (i16* getelementptr inbounds ([32 x i16]* @_ZN11xercesc_2_5L11gDigitCharsE, i32 0, i32 30) to i32)), i32 1), i32 ashr (i32 add (i32 mul (i32 ptrtoint ([7 x i16]* @_ZN11xercesc_2_5L17gIdeographicCharsE to i32), i32 -1), i32 ptrtoint (i16* getelementptr inbounds ([7 x i16]* @_ZN11xercesc_2_5L17gIdeographicCharsE, i32 0, i32 4) to i32)), i32 1)), i32 8)
+ %b = add i32 %a, %x
+ ret i32 %b
+}
diff --git a/test/Transforms/InstSimplify/2011-11-23-MaskedBitsCrash.ll b/test/Transforms/InstSimplify/2011-11-23-MaskedBitsCrash.ll
new file mode 100644
index 0000000..6166536
--- /dev/null
+++ b/test/Transforms/InstSimplify/2011-11-23-MaskedBitsCrash.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -instsimplify
+
+; The mul can be proved to always overflow (turning a negative value
+; into a positive one) and thus results in undefined behaviour. At
+; the same time we were deducing from the nsw flag that that mul could
+; be assumed to have a negative value (since if not it has an undefined
+; value, which can be taken to be negative). We were reporting the mul
+; as being both positive and negative, firing an assertion!
+define i1 @test1(i32 %a) {
+entry:
+ %0 = or i32 %a, 1
+ %1 = shl i32 %0, 31
+ %2 = mul nsw i32 %1, 4
+ %3 = and i32 %2, -4
+ %4 = icmp ne i32 %3, 0
+ ret i1 %4
+}
diff --git a/test/Transforms/InstSimplify/AndOrXor.ll b/test/Transforms/InstSimplify/AndOrXor.ll
new file mode 100644
index 0000000..33a4d6b
--- /dev/null
+++ b/test/Transforms/InstSimplify/AndOrXor.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+define i64 @pow2(i32 %x) {
+; CHECK: @pow2
+ %negx = sub i32 0, %x
+ %x2 = and i32 %x, %negx
+ %e = zext i32 %x2 to i64
+ %nege = sub i64 0, %e
+ %e2 = and i64 %e, %nege
+ ret i64 %e2
+; CHECK: ret i64 %e
+}
+
+define i64 @pow2b(i32 %x) {
+; CHECK: @pow2b
+ %sh = shl i32 2, %x
+ %e = zext i32 %sh to i64
+ %nege = sub i64 0, %e
+ %e2 = and i64 %e, %nege
+ ret i64 %e2
+; CHECK: ret i64 %e
+}
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index 2cbd641..ced74bd 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -10,6 +10,161 @@ define i1 @ptrtoint() {
; CHECK: ret i1 false
}
+define i1 @bitcast() {
+; CHECK: @bitcast
+ %a = alloca i32
+ %b = alloca i64
+ %x = bitcast i32* %a to i8*
+ %y = bitcast i64* %b to i8*
+ %cmp = icmp eq i8* %x, %y
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep() {
+; CHECK: @gep
+ %a = alloca [3 x i8], align 8
+ %x = getelementptr inbounds [3 x i8]* %a, i32 0, i32 0
+ %cmp = icmp eq i8* %x, null
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep2() {
+; CHECK: @gep2
+ %a = alloca [3 x i8], align 8
+ %x = getelementptr inbounds [3 x i8]* %a, i32 0, i32 0
+ %y = getelementptr inbounds [3 x i8]* %a, i32 0, i32 0
+ %cmp = icmp eq i8* %x, %y
+ ret i1 %cmp
+; CHECK-NEXT: ret i1 true
+}
+
+; PR11238
+%gept = type { i32, i32 }
+@gepy = global %gept zeroinitializer, align 8
+@gepz = extern_weak global %gept
+
+define i1 @gep3() {
+; CHECK: @gep3
+ %x = alloca %gept, align 8
+ %a = getelementptr %gept* %x, i64 0, i32 0
+ %b = getelementptr %gept* %x, i64 0, i32 1
+ %equal = icmp eq i32* %a, %b
+ ret i1 %equal
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep4() {
+; CHECK: @gep4
+ %x = alloca %gept, align 8
+ %a = getelementptr %gept* @gepy, i64 0, i32 0
+ %b = getelementptr %gept* @gepy, i64 0, i32 1
+ %equal = icmp eq i32* %a, %b
+ ret i1 %equal
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep5() {
+; CHECK: @gep5
+ %x = alloca %gept, align 8
+ %a = getelementptr inbounds %gept* %x, i64 0, i32 1
+ %b = getelementptr %gept* @gepy, i64 0, i32 0
+ %equal = icmp eq i32* %a, %b
+ ret i1 %equal
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep6(%gept* %x) {
+; Same as @gep3 but potentially null.
+; CHECK: @gep6
+ %a = getelementptr %gept* %x, i64 0, i32 0
+ %b = getelementptr %gept* %x, i64 0, i32 1
+ %equal = icmp eq i32* %a, %b
+ ret i1 %equal
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @gep7(%gept* %x) {
+; CHECK: @gep7
+ %a = getelementptr %gept* %x, i64 0, i32 0
+ %b = getelementptr %gept* @gepz, i64 0, i32 0
+ %equal = icmp eq i32* %a, %b
+ ret i1 %equal
+; CHECK: ret i1 %equal
+}
+
+define i1 @gep8(%gept* %x) {
+; CHECK: @gep8
+ %a = getelementptr %gept* %x, i32 1
+ %b = getelementptr %gept* %x, i32 -1
+ %equal = icmp ugt %gept* %a, %b
+ ret i1 %equal
+; CHECK: ret i1 %equal
+}
+
+define i1 @gep9(i8* %ptr) {
+; CHECK: @gep9
+; CHECK-NOT: ret
+; CHECK: ret i1 true
+
+entry:
+ %first1 = getelementptr inbounds i8* %ptr, i32 0
+ %first2 = getelementptr inbounds i8* %first1, i32 1
+ %first3 = getelementptr inbounds i8* %first2, i32 2
+ %first4 = getelementptr inbounds i8* %first3, i32 4
+ %last1 = getelementptr inbounds i8* %first2, i32 48
+ %last2 = getelementptr inbounds i8* %last1, i32 8
+ %last3 = getelementptr inbounds i8* %last2, i32 -4
+ %last4 = getelementptr inbounds i8* %last3, i32 -4
+ %first.int = ptrtoint i8* %first4 to i32
+ %last.int = ptrtoint i8* %last4 to i32
+ %cmp = icmp ne i32 %last.int, %first.int
+ ret i1 %cmp
+}
+
+define i1 @gep10(i8* %ptr) {
+; CHECK: @gep10
+; CHECK-NOT: ret
+; CHECK: ret i1 true
+
+entry:
+ %first1 = getelementptr inbounds i8* %ptr, i32 -2
+ %first2 = getelementptr inbounds i8* %first1, i32 44
+ %last1 = getelementptr inbounds i8* %ptr, i32 48
+ %last2 = getelementptr inbounds i8* %last1, i32 -6
+ %first.int = ptrtoint i8* %first2 to i32
+ %last.int = ptrtoint i8* %last2 to i32
+ %cmp = icmp eq i32 %last.int, %first.int
+ ret i1 %cmp
+}
+
+define i1 @gep11(i8* %ptr) {
+; CHECK: @gep11
+; CHECK-NOT: ret
+; CHECK: ret i1 true
+
+entry:
+ %first1 = getelementptr inbounds i8* %ptr, i32 -2
+ %last1 = getelementptr inbounds i8* %ptr, i32 48
+ %last2 = getelementptr inbounds i8* %last1, i32 -6
+ %cmp = icmp ult i8* %first1, %last2
+ ret i1 %cmp
+}
+
+define i1 @gep12(i8* %ptr) {
+; CHECK: @gep12
+; CHECK-NOT: ret
+; CHECK: ret i1 %cmp
+
+entry:
+ %first1 = getelementptr inbounds i8* %ptr, i32 -2
+ %last1 = getelementptr inbounds i8* %ptr, i32 48
+ %last2 = getelementptr inbounds i8* %last1, i32 -6
+ %cmp = icmp slt i8* %first1, %last2
+ ret i1 %cmp
+}
+
define i1 @zext(i32 %x) {
; CHECK: @zext
%e1 = zext i32 %x to i64
@@ -204,6 +359,24 @@ define i1 @select4(i1 %cond) {
; CHECK: ret i1 %cond
}
+define i1 @select5(i32 %x) {
+; CHECK: @select5
+ %c = icmp eq i32 %x, 0
+ %s = select i1 %c, i32 1, i32 %x
+ %c2 = icmp eq i32 %s, 0
+ ret i1 %c2
+; CHECK: ret i1 false
+}
+
+define i1 @select6(i32 %x) {
+; CHECK: @select6
+ %c = icmp sgt i32 %x, 0
+ %s = select i1 %c, i32 %x, i32 4
+ %c2 = icmp eq i32 %s, 0
+ ret i1 %c2
+; CHECK: ret i1 %c2
+}
+
define i1 @urem1(i32 %X, i32 %Y) {
; CHECK: @urem1
%A = urem i32 %X, %Y
@@ -300,6 +473,40 @@ define i1 @udiv2(i32 %X, i32 %Y, i32 %Z) {
; CHECK: ret i1 true
}
+define i1 @udiv3(i32 %X, i32 %Y) {
+; CHECK: @udiv3
+ %A = udiv i32 %X, %Y
+ %C = icmp ugt i32 %A, %X
+ ret i1 %C
+; CHECK: ret i1 false
+}
+
+define i1 @udiv4(i32 %X, i32 %Y) {
+; CHECK: @udiv4
+ %A = udiv i32 %X, %Y
+ %C = icmp ule i32 %A, %X
+ ret i1 %C
+; CHECK: ret i1 true
+}
+
+define i1 @udiv5(i32 %X) {
+; CHECK: @udiv5
+ %A = udiv i32 123, %X
+ %C = icmp ugt i32 %A, 124
+ ret i1 %C
+; CHECK: ret i1 false
+}
+
+; PR11340
+define i1 @udiv6(i32 %X) nounwind {
+; CHECK: @udiv6
+ %A = udiv i32 1, %X
+ %C = icmp eq i32 %A, 0
+ ret i1 %C
+; CHECK: ret i1 %C
+}
+
+
define i1 @sdiv1(i32 %X) {
; CHECK: @sdiv1
%A = sdiv i32 %X, 1000000
@@ -323,3 +530,71 @@ define i1 @and1(i32 %X) {
ret i1 %B
; CHECK: ret i1 false
}
+
+define i1 @mul1(i32 %X) {
+; CHECK: @mul1
+; Square of a non-zero number is non-zero if there is no overflow.
+ %Y = or i32 %X, 1
+ %M = mul nuw i32 %Y, %Y
+ %C = icmp eq i32 %M, 0
+ ret i1 %C
+; CHECK: ret i1 false
+}
+
+define i1 @mul2(i32 %X) {
+; CHECK: @mul2
+; Square of a non-zero number is positive if there is no signed overflow.
+ %Y = or i32 %X, 1
+ %M = mul nsw i32 %Y, %Y
+ %C = icmp sgt i32 %M, 0
+ ret i1 %C
+; CHECK: ret i1 true
+}
+
+define i1 @mul3(i32 %X, i32 %Y) {
+; CHECK: @mul3
+; Product of non-negative numbers is non-negative if there is no signed overflow.
+ %XX = mul nsw i32 %X, %X
+ %YY = mul nsw i32 %Y, %Y
+ %M = mul nsw i32 %XX, %YY
+ %C = icmp sge i32 %M, 0
+ ret i1 %C
+; CHECK: ret i1 true
+}
+
+define <2 x i1> @vectorselect1(<2 x i1> %cond) {
+; CHECK: @vectorselect1
+ %invert = xor <2 x i1> %cond, <i1 1, i1 1>
+ %s = select <2 x i1> %invert, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 1, i32 1>
+ %c = icmp ne <2 x i32> %s, <i32 0, i32 0>
+ ret <2 x i1> %c
+; CHECK: ret <2 x i1> %cond
+}
+
+; PR11948
+define <2 x i1> @vectorselectcrash(i32 %arg1) {
+ %tobool40 = icmp ne i32 %arg1, 0
+ %cond43 = select i1 %tobool40, <2 x i16> <i16 -5, i16 66>, <2 x i16> <i16 46, i16 1>
+ %cmp45 = icmp ugt <2 x i16> %cond43, <i16 73, i16 21>
+ ret <2 x i1> %cmp45
+}
+
+; PR12013
+define i1 @alloca_compare(i64 %idx) {
+ %sv = alloca { i32, i32, [124 x i32] }
+ %1 = getelementptr inbounds { i32, i32, [124 x i32] }* %sv, i32 0, i32 2, i64 %idx
+ %2 = icmp eq i32* %1, null
+ ret i1 %2
+ ; CHECK: alloca_compare
+ ; CHECK: ret i1 false
+}
+
+; PR12075
+define i1 @infinite_gep() {
+ ret i1 1
+
+unreachableblock:
+ %X = getelementptr i32 *%X, i32 1
+ %Y = icmp eq i32* %X, null
+ ret i1 %Y
+}
diff --git a/test/Transforms/InstSimplify/dg.exp b/test/Transforms/InstSimplify/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/InstSimplify/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/InstSimplify/lit.local.cfg b/test/Transforms/InstSimplify/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/InstSimplify/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/InstSimplify/phi.ll b/test/Transforms/InstSimplify/phi.ll
new file mode 100644
index 0000000..05cd40d
--- /dev/null
+++ b/test/Transforms/InstSimplify/phi.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+; PR12189
+define i1 @test1(i32 %x) {
+; CHECK: @test1
+ br i1 true, label %a, label %b
+
+a:
+ %aa = or i32 %x, 10
+ br label %c
+
+b:
+ %bb = or i32 %x, 10
+ br label %c
+
+c:
+ %cc = phi i32 [ %bb, %b ], [%aa, %a ]
+ %d = urem i32 %cc, 2
+ %e = icmp eq i32 %d, 0
+ ret i1 %e
+; CHECK: ret i1 %e
+}
diff --git a/test/Transforms/InstSimplify/ptr_diff.ll b/test/Transforms/InstSimplify/ptr_diff.ll
new file mode 100644
index 0000000..1eb1fd4
--- /dev/null
+++ b/test/Transforms/InstSimplify/ptr_diff.ll
@@ -0,0 +1,48 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i64 @ptrdiff1(i8* %ptr) {
+; CHECK: @ptrdiff1
+; CHECK-NEXT: ret i64 42
+
+ %first = getelementptr inbounds i8* %ptr, i32 0
+ %last = getelementptr inbounds i8* %ptr, i32 42
+ %first.int = ptrtoint i8* %first to i64
+ %last.int = ptrtoint i8* %last to i64
+ %diff = sub i64 %last.int, %first.int
+ ret i64 %diff
+}
+
+define i64 @ptrdiff2(i8* %ptr) {
+; CHECK: @ptrdiff2
+; CHECK-NEXT: ret i64 42
+
+ %first1 = getelementptr inbounds i8* %ptr, i32 0
+ %first2 = getelementptr inbounds i8* %first1, i32 1
+ %first3 = getelementptr inbounds i8* %first2, i32 2
+ %first4 = getelementptr inbounds i8* %first3, i32 4
+ %last1 = getelementptr inbounds i8* %first2, i32 48
+ %last2 = getelementptr inbounds i8* %last1, i32 8
+ %last3 = getelementptr inbounds i8* %last2, i32 -4
+ %last4 = getelementptr inbounds i8* %last3, i32 -4
+ %first.int = ptrtoint i8* %first4 to i64
+ %last.int = ptrtoint i8* %last4 to i64
+ %diff = sub i64 %last.int, %first.int
+ ret i64 %diff
+}
+
+define i64 @ptrdiff3(i8* %ptr) {
+; Don't bother with non-inbounds GEPs.
+; CHECK: @ptrdiff3
+; CHECK: getelementptr
+; CHECK: sub
+; CHECK: ret
+
+ %first = getelementptr i8* %ptr, i32 0
+ %last = getelementptr i8* %ptr, i32 42
+ %first.int = ptrtoint i8* %first to i64
+ %last.int = ptrtoint i8* %last to i64
+ %diff = sub i64 %last.int, %first.int
+ ret i64 %diff
+}
diff --git a/test/Transforms/InstSimplify/reassociate.ll b/test/Transforms/InstSimplify/reassociate.ll
index 3c8169e..e659e6f 100644
--- a/test/Transforms/InstSimplify/reassociate.ll
+++ b/test/Transforms/InstSimplify/reassociate.ll
@@ -184,3 +184,12 @@ define i32 @udiv5(i32 %x, i32 %y) {
; CHECK: ret i32 %x
}
+define i16 @trunc1(i32 %x) {
+; CHECK: @trunc1
+ %y = add i32 %x, 1
+ %tx = trunc i32 %x to i16
+ %ty = trunc i32 %y to i16
+ %d = sub i16 %ty, %tx
+ ret i16 %d
+; CHECK: ret i16 1
+}
diff --git a/test/Transforms/InstSimplify/undef.ll b/test/Transforms/InstSimplify/undef.ll
index 8134cc8..23cd50f 100644
--- a/test/Transforms/InstSimplify/undef.ll
+++ b/test/Transforms/InstSimplify/undef.ll
@@ -84,6 +84,13 @@ define i64 @test11() {
ret i64 %r
}
+; @test11b
+; CHECK: ret i64 undef
+define i64 @test11b(i64 %a) {
+ %r = shl i64 %a, undef
+ ret i64 %r
+}
+
; @test12
; CHECK: ret i64 undef
define i64 @test12() {
@@ -91,6 +98,13 @@ define i64 @test12() {
ret i64 %r
}
+; @test12b
+; CHECK: ret i64 undef
+define i64 @test12b(i64 %a) {
+ %r = ashr i64 %a, undef
+ ret i64 %r
+}
+
; @test13
; CHECK: ret i64 undef
define i64 @test13() {
@@ -98,6 +112,13 @@ define i64 @test13() {
ret i64 %r
}
+; @test13b
+; CHECK: ret i64 undef
+define i64 @test13b(i64 %a) {
+ %r = lshr i64 %a, undef
+ ret i64 %r
+}
+
; @test14
; CHECK: ret i1 undef
define i1 @test14() {
@@ -125,3 +146,10 @@ define i64 @test17(i64 %a) {
%r = select i1 undef, i64 undef, i64 %a
ret i64 %r
}
+
+; @test18
+; CHECK: ret i64 undef
+define i64 @test18(i64 %a) {
+ %r = call i64 (i64)* undef(i64 %a)
+ ret i64 %r
+}
diff --git a/test/Transforms/InstSimplify/vector_gep.ll b/test/Transforms/InstSimplify/vector_gep.ll
new file mode 100644
index 0000000..f65260e
--- /dev/null
+++ b/test/Transforms/InstSimplify/vector_gep.ll
@@ -0,0 +1,8 @@
+;RUN: opt -instsimplify %s -disable-output
+declare void @helper(<2 x i8*>)
+define void @test(<2 x i8*> %a) {
+ %A = getelementptr <2 x i8*> %a, <2 x i32> <i32 0, i32 0>
+ call void @helper(<2 x i8*> %A)
+ ret void
+}
+
diff --git a/test/Transforms/Internalize/dg.exp b/test/Transforms/Internalize/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/Internalize/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/Internalize/lit.local.cfg b/test/Transforms/Internalize/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/Internalize/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll b/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll
index 46aaa00..e80bae5 100644
--- a/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll
+++ b/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll
@@ -15,7 +15,7 @@ for.cond1177:
br i1 %cmp1179, label %for.cond1177, label %land.rhs1320
land.rhs1320:
- %tmp1324 = volatile load i64* getelementptr inbounds (%0* @g_338, i64 0, i32 2), align 1, !tbaa !0
+ %tmp1324 = load volatile i64* getelementptr inbounds (%0* @g_338, i64 0, i32 2), align 1, !tbaa !0
br label %if.end.i
if.end.i:
diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll
index 2115dd3..b9c0354 100644
--- a/test/Transforms/JumpThreading/crash.ll
+++ b/test/Transforms/JumpThreading/crash.ll
@@ -399,7 +399,7 @@ if.then237:
br label %lbl_664
lbl_596: ; preds = %lbl_664, %for.end37
- volatile store i64 undef, i64* undef, align 4
+ store volatile i64 undef, i64* undef, align 4
br label %for.cond111
for.cond111: ; preds = %safe_sub_func_int64_t_s_s.exit, %lbl_596
diff --git a/test/Transforms/JumpThreading/dg.exp b/test/Transforms/JumpThreading/dg.exp
deleted file mode 100644
index de42dad..0000000
--- a/test/Transforms/JumpThreading/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.ll]]
diff --git a/test/Transforms/JumpThreading/lit.local.cfg b/test/Transforms/JumpThreading/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/Transforms/JumpThreading/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/test/Transforms/JumpThreading/no-irreducible-loops.ll b/test/Transforms/JumpThreading/no-irreducible-loops.ll
index 7c7fe39..a4914f9 100644
--- a/test/Transforms/JumpThreading/no-irreducible-loops.ll
+++ b/test/Transforms/JumpThreading/no-irreducible-loops.ll
@@ -17,11 +17,11 @@ bb: ; preds = %bb4
br i1 %0, label %bb1, label %bb2
bb1: ; preds = %bb
- volatile store i32 1000, i32* @v1, align 4
+ store volatile i32 1000, i32* @v1, align 4
br label %bb3
bb2: ; preds = %bb
- volatile store i32 1001, i32* @v1, align 4
+ store volatile i32 1001, i32* @v1, align 4
br label %bb3
bb3: ; preds = %bb2, %bb1
diff --git a/test/Transforms/JumpThreading/thread-loads.ll b/test/Transforms/JumpThreading/thread-loads.ll
index cce23ea..78d36e7 100644
--- a/test/Transforms/JumpThreading/thread-loads.ll
+++ b/test/Transforms/JumpThreading/thread-loads.ll
@@ -1,12 +1,12 @@
; RUN: opt < %s -jump-threading -S | FileCheck %s
-; rdar://6402033
-; Test that we can thread through the block with the partially redundant load (%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-darwin7"
-define i32 @foo(i32* %P) nounwind {
-; CHECK: foo
+; Test that we can thread through the block with the partially redundant load (%2).
+; rdar://6402033
+define i32 @test1(i32* %P) nounwind {
+; CHECK: @test1
entry:
%0 = tail call i32 (...)* @f1() nounwind ; <i32> [#uses=1]
%1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
@@ -39,3 +39,43 @@ bb3: ; preds = %bb1
declare i32 @f1(...)
declare i32 @f2(...)
+
+
+;; Check that we preserve TBAA information.
+; rdar://11039258
+
+define i32 @test2(i32* %P) nounwind {
+; CHECK: @test2
+entry:
+ %0 = tail call i32 (...)* @f1() nounwind ; <i32> [#uses=1]
+ %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
+ br i1 %1, label %bb1, label %bb
+
+bb: ; preds = %entry
+; CHECK: bb1.thread:
+; CHECK: store{{.*}}, !tbaa !0
+; CHECK: br label %bb3
+ store i32 42, i32* %P, align 4, !tbaa !0
+ br label %bb1
+
+bb1: ; preds = %entry, %bb
+ %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
+ %2 = load i32* %P, align 4, !tbaa !0
+ %3 = icmp sgt i32 %2, 36
+ br i1 %3, label %bb3, label %bb2
+
+bb2: ; preds = %bb1
+ %4 = tail call i32 (...)* @f2() nounwind
+ ret i32 %res.0
+
+bb3: ; preds = %bb1
+; CHECK: bb3:
+; CHECK: %res.01 = phi i32 [ 1, %bb1.thread ], [ 0, %bb1 ]
+; CHECK: ret i32 %res.01
+ ret i32 %res.0
+}
+
+!0 = metadata !{metadata !"int", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
+
diff --git a/test/Transforms/LCSSA/dg.exp b/test/Transforms/LCSSA/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LCSSA/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/LCSSA/lit.local.cfg b/test/Transforms/LCSSA/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LCSSA/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LICM/2007-05-22-VolatileSink.ll b/test/Transforms/LICM/2007-05-22-VolatileSink.ll
index 17383c2..4df6ea7 100644
--- a/test/Transforms/LICM/2007-05-22-VolatileSink.ll
+++ b/test/Transforms/LICM/2007-05-22-VolatileSink.ll
@@ -10,7 +10,7 @@ entry:
br label %bb6
bb: ; preds = %bb6
- %tmp2 = volatile load i32* %DataIn ; <i32> [#uses=1]
+ %tmp2 = load volatile i32* %DataIn ; <i32> [#uses=1]
%tmp3 = getelementptr [64 x i32]* %buffer, i32 0, i32 %i.0 ; <i32*> [#uses=1]
store i32 %tmp2, i32* %tmp3
%tmp5 = add i32 %i.0, 1 ; <i32> [#uses=1]
@@ -28,7 +28,7 @@ bb12: ; preds = %bb22
%tmp16 = add i32 %tmp14, %i.1 ; <i32> [#uses=1]
%tmp17 = getelementptr [64 x i32]* %buffer, i32 0, i32 %tmp16 ; <i32*> [#uses=1]
%tmp18 = load i32* %tmp17 ; <i32> [#uses=1]
- volatile store i32 %tmp18, i32* %DataOut
+ store volatile i32 %tmp18, i32* %DataOut
%tmp21 = add i32 %j.1, 1 ; <i32> [#uses=1]
br label %bb22
diff --git a/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll b/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll
index fd114f4..2bbc6ab 100644
--- a/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll
+++ b/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll
@@ -19,7 +19,7 @@ for.body4.lr.ph:
for.body4:
%l_612.11 = phi i32* [ undef, %for.body4.lr.ph ], [ %call19, %for.body4 ]
- %tmp7 = volatile load i16* @g_39, align 2
+ %tmp7 = load volatile i16* @g_39, align 2
%call = call i32** @func_108(i32*** undef)
%call19 = call i32* @func_84(i32** %call)
br i1 false, label %for.body4, label %for.cond.loopexit
diff --git a/test/Transforms/LICM/crash.ll b/test/Transforms/LICM/crash.ll
index ff7fa0b..de41d00 100644
--- a/test/Transforms/LICM/crash.ll
+++ b/test/Transforms/LICM/crash.ll
@@ -68,7 +68,7 @@ define void @test4() noreturn nounwind {
br label %1
; <label>:1 ; preds = %1, %0
- volatile store i32* @g_47, i32** undef, align 8
+ store volatile i32* @g_47, i32** undef, align 8
store i32 undef, i32* @g_47, align 4
br label %1
}
diff --git a/test/Transforms/LICM/dg.exp b/test/Transforms/LICM/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LICM/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/LICM/hoist-invariant-load.ll b/test/Transforms/LICM/hoist-invariant-load.ll
new file mode 100644
index 0000000..4e100d3
--- /dev/null
+++ b/test/Transforms/LICM/hoist-invariant-load.ll
@@ -0,0 +1,39 @@
+; RUN: opt < %s -licm -stats -S |& grep "1 licm"
+
+@"\01L_OBJC_METH_VAR_NAME_" = internal global [4 x i8] c"foo\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
+@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
+@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*)], section "llvm.metadata"
+
+define void @test(i8* %x) uwtable ssp {
+entry:
+ %x.addr = alloca i8*, align 8
+ %i = alloca i32, align 4
+ store i8* %x, i8** %x.addr, align 8
+ store i32 0, i32* %i, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %0 = load i32* %i, align 4
+ %cmp = icmp ult i32 %0, 10000
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i8** %x.addr, align 8
+ %2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", !invariant.load !0
+ %call = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %1, i8* %2)
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %3 = load i32* %i, align 4
+ %inc = add i32 %3, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
+
+!0 = metadata !{}
diff --git a/test/Transforms/LICM/lit.local.cfg b/test/Transforms/LICM/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LICM/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LICM/scalar_promote.ll b/test/Transforms/LICM/scalar_promote.ll
index 9aefc4f8..05a64d6 100644
--- a/test/Transforms/LICM/scalar_promote.ll
+++ b/test/Transforms/LICM/scalar_promote.ll
@@ -59,7 +59,7 @@ define void @test3(i32 %i) {
br label %Loop
Loop:
; Should not promote this to a register
- %x = volatile load i32* @X
+ %x = load volatile i32* @X
%x2 = add i32 %x, 1
store i32 %x2, i32* @X
br i1 true, label %Out, label %Loop
@@ -133,7 +133,7 @@ Loop: ; preds = %Loop, %0
%x2 = add i32 %x, 1 ; <i32> [#uses=1]
store i32 %x2, i32* @X
- volatile store i32* @X, i32** %P2
+ store volatile i32* @X, i32** %P2
%Next = add i32 %j, 1 ; <i32> [#uses=2]
%cond = icmp eq i32 %Next, 0 ; <i1> [#uses=1]
diff --git a/test/Transforms/LICM/speculate.ll b/test/Transforms/LICM/speculate.ll
new file mode 100644
index 0000000..507b193
--- /dev/null
+++ b/test/Transforms/LICM/speculate.ll
@@ -0,0 +1,167 @@
+; RUN: opt -S -licm < %s | FileCheck %s
+
+; UDiv is safe to speculate if the denominator is known non-zero.
+
+; CHECK: @safe_udiv
+; CHECK: %div = udiv i64 %x, %or
+; CHECK-NEXT: br label %for.body
+
+define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
+entry:
+ %or = or i64 %m, 1
+ br label %for.body
+
+for.body: ; preds = %entry, %for.inc
+ %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
+ %0 = load i32* %arrayidx, align 4
+ %tobool = icmp eq i32 %0, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %div = udiv i64 %x, %or
+ %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
+ store i64 %div, i64* %arrayidx1, align 8
+ br label %for.inc
+
+for.inc: ; preds = %if.then, %for.body
+ %inc = add i64 %i.02, 1
+ %cmp = icmp slt i64 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.inc, %entry
+ ret void
+}
+
+; UDiv is unsafe to speculate if the denominator is not known non-zero.
+
+; CHECK: @unsafe_udiv
+; CHECK-NOT: udiv
+; CHECK: for.body:
+
+define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
+entry:
+ br label %for.body
+
+for.body: ; preds = %entry, %for.inc
+ %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
+ %0 = load i32* %arrayidx, align 4
+ %tobool = icmp eq i32 %0, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %div = udiv i64 %x, %m
+ %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
+ store i64 %div, i64* %arrayidx1, align 8
+ br label %for.inc
+
+for.inc: ; preds = %if.then, %for.body
+ %inc = add i64 %i.02, 1
+ %cmp = icmp slt i64 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.inc, %entry
+ ret void
+}
+
+; SDiv is safe to speculate if the denominator is known non-zero and
+; known to have at least one zero bit.
+
+; CHECK: @safe_sdiv
+; CHECK: %div = sdiv i64 %x, %or
+; CHECK-NEXT: br label %for.body
+
+define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
+entry:
+ %and = and i64 %m, -3
+ %or = or i64 %and, 1
+ br label %for.body
+
+for.body: ; preds = %entry, %for.inc
+ %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
+ %0 = load i32* %arrayidx, align 4
+ %tobool = icmp eq i32 %0, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %div = sdiv i64 %x, %or
+ %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
+ store i64 %div, i64* %arrayidx1, align 8
+ br label %for.inc
+
+for.inc: ; preds = %if.then, %for.body
+ %inc = add i64 %i.02, 1
+ %cmp = icmp slt i64 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.inc, %entry
+ ret void
+}
+
+; SDiv is unsafe to speculate if the denominator is not known non-zero.
+
+; CHECK: @unsafe_sdiv_a
+; CHECK-NOT: sdiv
+; CHECK: for.body:
+
+define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
+entry:
+ %or = or i64 %m, 1
+ br label %for.body
+
+for.body: ; preds = %entry, %for.inc
+ %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
+ %0 = load i32* %arrayidx, align 4
+ %tobool = icmp eq i32 %0, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %div = sdiv i64 %x, %or
+ %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
+ store i64 %div, i64* %arrayidx1, align 8
+ br label %for.inc
+
+for.inc: ; preds = %if.then, %for.body
+ %inc = add i64 %i.02, 1
+ %cmp = icmp slt i64 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.inc, %entry
+ ret void
+}
+
+; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
+
+; CHECK: @unsafe_sdiv_b
+; CHECK-NOT: sdiv
+; CHECK: for.body:
+
+define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
+entry:
+ %and = and i64 %m, -3
+ br label %for.body
+
+for.body: ; preds = %entry, %for.inc
+ %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
+ %0 = load i32* %arrayidx, align 4
+ %tobool = icmp eq i32 %0, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then: ; preds = %for.body
+ %div = sdiv i64 %x, %and
+ %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
+ store i64 %div, i64* %arrayidx1, align 8
+ br label %for.inc
+
+for.inc: ; preds = %if.then, %for.body
+ %inc = add i64 %i.02, 1
+ %cmp = icmp slt i64 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.inc, %entry
+ ret void
+}
diff --git a/test/Transforms/LoopDeletion/dg.exp b/test/Transforms/LoopDeletion/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopDeletion/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/LoopDeletion/lit.local.cfg b/test/Transforms/LoopDeletion/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopDeletion/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LoopIdiom/dg.exp b/test/Transforms/LoopIdiom/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopIdiom/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/LoopIdiom/lit.local.cfg b/test/Transforms/LoopIdiom/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopIdiom/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LoopRotate/alloca.ll b/test/Transforms/LoopRotate/alloca.ll
new file mode 100644
index 0000000..fd217ea
--- /dev/null
+++ b/test/Transforms/LoopRotate/alloca.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -loop-rotate -S | FileCheck %s
+
+; Test alloca in -loop-rotate.
+
+; We expect a different value for %ptr each iteration (according to the
+; definition of alloca). I.e. each @use must be paired with an alloca.
+
+; CHECK: call void @use(i8* %
+; CHECK: %ptr = alloca i8
+
+@e = global i16 10
+
+declare void @use(i8*)
+
+define void @test() {
+entry:
+ %end = load i16* @e
+ br label %loop
+
+loop:
+ %n.phi = phi i16 [ %n, %loop.fin ], [ 0, %entry ]
+ %ptr = alloca i8
+ %cond = icmp eq i16 %n.phi, %end
+ br i1 %cond, label %exit, label %loop.fin
+
+loop.fin:
+ %n = add i16 %n.phi, 1
+ call void @use(i8* %ptr)
+ br label %loop
+
+exit:
+ ret void
+}
diff --git a/test/Transforms/LoopRotate/dbgvalue.ll b/test/Transforms/LoopRotate/dbgvalue.ll
index 9287178..b32ee82 100644
--- a/test/Transforms/LoopRotate/dbgvalue.ll
+++ b/test/Transforms/LoopRotate/dbgvalue.ll
@@ -1,11 +1,13 @@
; RUN: opt -S -loop-rotate %s | FileCheck %s
-; CHECK: entry
-; CHECK-NEXT: call void @llvm.dbg.value(metadata !{i32 %x}
-
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
define i32 @tak(i32 %x, i32 %y, i32 %z) nounwind ssp {
+; CHECK: define i32 @tak
+; CHECK: entry
+; CHECK-NEXT: call void @llvm.dbg.value(metadata !{i32 %x}
+
entry:
br label %tailrecurse
@@ -35,7 +37,45 @@ return: ; preds = %if.end
ret i32 %z.tr, !dbg !17
}
-declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
+@channelColumns = external global i64
+@horzPlane = external global i8*, align 8
+
+define void @FindFreeHorzSeg(i64 %startCol, i64 %row, i64* %rowStart) {
+; Ensure that the loop increment basic block is rotated into the tail of the
+; body, even though it contains a debug intrinsic call.
+; CHECK: define void @FindFreeHorzSeg
+; CHECK: %dec = add
+; CHECK-NEXT: tail call void @llvm.dbg.value
+; CHECK-NEXT: br i1 %tobool, label %for.cond, label %for.end
+
+entry:
+ br label %for.cond
+
+for.cond:
+ %i.0 = phi i64 [ %startCol, %entry ], [ %dec, %for.inc ]
+ %cmp = icmp eq i64 %i.0, 0
+ br i1 %cmp, label %for.end, label %for.body
+
+for.body:
+ %0 = load i64* @channelColumns, align 8
+ %mul = mul i64 %0, %row
+ %add = add i64 %mul, %i.0
+ %1 = load i8** @horzPlane, align 8
+ %arrayidx = getelementptr inbounds i8* %1, i64 %add
+ %2 = load i8* %arrayidx, align 1
+ %tobool = icmp eq i8 %2, 0
+ br i1 %tobool, label %for.inc, label %for.end
+
+for.inc:
+ %dec = add i64 %i.0, -1
+ tail call void @llvm.dbg.value(metadata !{i64 %dec}, i64 0, metadata undef)
+ br label %for.cond
+
+for.end:
+ %add1 = add i64 %i.0, 1
+ store i64 %add1, i64* %rowStart, align 8
+ ret void
+}
!llvm.dbg.sp = !{!0}
diff --git a/test/Transforms/LoopRotate/dg.exp b/test/Transforms/LoopRotate/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopRotate/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/LoopRotate/lit.local.cfg b/test/Transforms/LoopRotate/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopRotate/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LoopRotate/simplifylatch.ll b/test/Transforms/LoopRotate/simplifylatch.ll
new file mode 100644
index 0000000..f422724
--- /dev/null
+++ b/test/Transforms/LoopRotate/simplifylatch.ll
@@ -0,0 +1,39 @@
+; RUN: opt -S < %s -loop-rotate -verify-dom-info -verify-loop-info | FileCheck %s
+; PR2624 unroll multiple exits
+
+@mode_table = global [4 x i32] zeroinitializer ; <[4 x i32]*> [#uses=1]
+
+; CHECK: @f
+; CHECK-NOT: bb4
+define i8 @f() {
+entry:
+ tail call i32 @fegetround( ) ; <i32>:0 [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb4, %entry
+ %mode.0 = phi i8 [ 0, %entry ], [ %indvar.next, %bb4 ] ; <i8> [#uses=4]
+ zext i8 %mode.0 to i32 ; <i32>:1 [#uses=1]
+ getelementptr [4 x i32]* @mode_table, i32 0, i32 %1 ; <i32*>:2 [#uses=1]
+ load i32* %2, align 4 ; <i32>:3 [#uses=1]
+ icmp eq i32 %3, %0 ; <i1>:4 [#uses=1]
+ br i1 %4, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ ret i8 %mode.0
+
+bb2: ; preds = %bb
+ icmp eq i8 %mode.0, 1 ; <i1>:5 [#uses=1]
+ br i1 %5, label %bb5, label %bb4
+
+bb4: ; preds = %bb2
+ %indvar.next = add i8 %mode.0, 1 ; <i8> [#uses=1]
+ br label %bb
+
+bb5: ; preds = %bb2
+ tail call void @raise_exception( ) noreturn
+ unreachable
+}
+
+declare i32 @fegetround()
+
+declare void @raise_exception() noreturn
diff --git a/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll b/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll
new file mode 100644
index 0000000..173a582
--- /dev/null
+++ b/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -loop-simplify -S | FileCheck %s
+; PR11575
+
+@catchtypeinfo = external unnamed_addr constant { i8*, i8*, i8* }
+
+define void @main() uwtable ssp {
+entry:
+ invoke void @f1()
+ to label %try.cont19 unwind label %catch
+
+; CHECK: catch.preheader:
+; CHECK-NEXT: landingpad
+; CHECK: br label %catch
+
+; CHECK: catch.split-lp:
+; CHECK-NEXT: landingpad
+; CHECK: br label %catch
+
+catch: ; preds = %if.else, %entry
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* bitcast ({ i8*, i8*, i8* }* @catchtypeinfo to i8*)
+ invoke void @f3()
+ to label %if.else unwind label %eh.resume
+
+if.else: ; preds = %catch
+ invoke void @f2()
+ to label %try.cont19 unwind label %catch
+
+try.cont19: ; preds = %if.else, %entry
+ ret void
+
+eh.resume: ; preds = %catch
+ %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ catch i8* bitcast ({ i8*, i8*, i8* }* @catchtypeinfo to i8*)
+ resume { i8*, i32 } undef
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+declare void @f1()
+
+declare void @f2()
+
+declare void @f3()
diff --git a/test/Transforms/LoopSimplify/2012-03-20-indirectbr.ll b/test/Transforms/LoopSimplify/2012-03-20-indirectbr.ll
new file mode 100644
index 0000000..9c805da
--- /dev/null
+++ b/test/Transforms/LoopSimplify/2012-03-20-indirectbr.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -loop-simplify -S | FileCheck %s
+
+; Make sure the preheader exists.
+; CHECK: sw.bb103:
+; CHECK: indirectbr {{.*}}label %while.cond112
+; CHECK: while.cond112:
+; But the tail is not split.
+; CHECK: for.body:
+; CHECK: indirectbr {{.*}}label %while.cond112
+define fastcc void @build_regex_nfa() nounwind uwtable ssp {
+entry:
+ indirectbr i8* blockaddress(@build_regex_nfa, %while.cond), [label %while.cond]
+
+while.cond: ; preds = %if.then439, %entry
+ indirectbr i8* blockaddress(@build_regex_nfa, %sw.bb103), [label %do.body785, label %sw.bb103]
+
+sw.bb103: ; preds = %while.body
+ indirectbr i8* blockaddress(@build_regex_nfa, %while.cond112), [label %while.cond112]
+
+while.cond112: ; preds = %for.body, %for.cond.preheader, %sw.bb103
+ %pc.0 = phi i8 [ -1, %sw.bb103 ], [ 0, %for.body ], [ %pc.0, %for.cond.preheader ]
+ indirectbr i8* blockaddress(@build_regex_nfa, %Lsetdone), [label %sw.bb118, label %Lsetdone]
+
+sw.bb118: ; preds = %while.cond112
+ indirectbr i8* blockaddress(@build_regex_nfa, %for.cond.preheader), [label %Lerror.loopexit, label %for.cond.preheader]
+
+for.cond.preheader: ; preds = %sw.bb118
+ indirectbr i8* blockaddress(@build_regex_nfa, %for.body), [label %while.cond112, label %for.body]
+
+for.body: ; preds = %for.body, %for.cond.preheader
+ indirectbr i8* blockaddress(@build_regex_nfa, %for.body), [label %while.cond112, label %for.body]
+
+Lsetdone: ; preds = %while.cond112
+ unreachable
+
+do.body785: ; preds = %while.cond, %while.body
+ ret void
+
+Lerror.loopexit: ; preds = %sw.bb118
+ unreachable
+}
diff --git a/test/Transforms/LoopSimplify/dg.exp b/test/Transforms/LoopSimplify/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopSimplify/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/LoopSimplify/lit.local.cfg b/test/Transforms/LoopSimplify/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopSimplify/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll b/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll
index 90477d1..ce56bd3 100644
--- a/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll
+++ b/test/Transforms/LoopStrengthReduce/2008-08-13-CmpStride.ll
@@ -10,7 +10,7 @@ entry:
bb: ; preds = %bb, %entry
%l_2.0.reg2mem.0 = phi i16 [ 0, %entry ], [ %t1, %bb ] ; <i16> [#uses=2]
%t0 = shl i16 %l_2.0.reg2mem.0, 1 ; <i16>:0 [#uses=1]
- volatile store i16 %t0, i16* @g_3, align 2
+ store volatile i16 %t0, i16* @g_3, align 2
%t1 = add i16 %l_2.0.reg2mem.0, -3 ; <i16>:1 [#uses=2]
%t2 = icmp slt i16 %t1, 1 ; <i1>:2 [#uses=1]
br i1 %t2, label %bb, label %return
@@ -22,7 +22,7 @@ return: ; preds = %bb
define i32 @main() nounwind {
entry:
tail call void @func_1( ) nounwind
- volatile load i16* @g_3, align 2 ; <i16>:0 [#uses=1]
+ load volatile i16* @g_3, align 2 ; <i16>:0 [#uses=1]
zext i16 %0 to i32 ; <i32>:1 [#uses=1]
tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i32 %1 ) nounwind ; <i32>:2 [#uses=0]
ret i32 0
diff --git a/test/Transforms/LoopStrengthReduce/2011-12-19-PostincQuadratic.ll b/test/Transforms/LoopStrengthReduce/2011-12-19-PostincQuadratic.ll
new file mode 100644
index 0000000..392a8bc
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2011-12-19-PostincQuadratic.ll
@@ -0,0 +1,39 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; PR11571: handle a postinc user outside of for.body7 that requires
+; recursive expansion of a quadratic recurrence within for.body7. LSR
+; needs to forget that for.body7 is a postinc loop during expansion.
+
+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:32:32-n8:16:32-S128"
+target triple = "i386-unknown-freebsd10.0"
+
+@b = external global [121 x i32]
+
+; CHECK: @vb
+; Outer recurrence:
+; CHECK: %lsr.iv1 = phi [121 x i32]*
+; Inner recurrence:
+; CHECK: %lsr.iv = phi i32
+; Outer step (relative to inner recurrence):
+; CHECK: %scevgep = getelementptr i1* %{{.*}}, i32 %lsr.iv
+; Outer use:
+; CHECK: %lsr.iv3 = phi [121 x i32]* [ %lsr.iv1, %for.body43.preheader ]
+define void @vb() nounwind {
+for.cond.preheader:
+ br label %for.body7
+
+for.body7:
+ %indvars.iv77 = phi i32 [ %indvars.iv.next78, %for.body7 ], [ 1, %for.cond.preheader ]
+ %bf.072 = phi i32 [ %t1, %for.body7 ], [ 0, %for.cond.preheader ]
+ %t1 = add i32 %bf.072, %indvars.iv77
+ %indvars.iv.next78 = add i32 %indvars.iv77, 1
+ br i1 undef, label %for.body43, label %for.body7
+
+for.body43:
+ %bf.459 = phi i32 [ %inc44, %for.body43 ], [ %t1, %for.body7 ]
+ %inc44 = add nsw i32 %bf.459, 1
+ %arrayidx45 = getelementptr inbounds [121 x i32]* @b, i32 0, i32 %bf.459
+ %t2 = load i32* %arrayidx45, align 4
+ br label %for.body43
+}
+
diff --git a/test/Transforms/LoopStrengthReduce/2012-01-02-nopreheader.ll b/test/Transforms/LoopStrengthReduce/2012-01-02-nopreheader.ll
new file mode 100644
index 0000000..d7f5723
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2012-01-02-nopreheader.ll
@@ -0,0 +1,88 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; <rdar://10619599> "SelectionDAGBuilder shouldn't visit PHI nodes!" assert.
+; <rdar://10655343> SCEVExpander segfault on simple test case
+
+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-f128:128:128-n8:16:32"
+target triple = "i386-apple-darwin"
+
+; LSR should convert the inner loop (bb7.us) IV (j.01.us) into float*.
+; This involves a nested AddRec, the outer AddRec's loop invariant components
+; cannot find a preheader, so they should be expanded in the loop header
+; (bb7.lr.ph.us) below the existing phi i.12.us.
+; Currently, LSR won't kick in on such loops.
+; CHECK: @nopreheader
+; CHECK: bb7.us:
+; CHECK-NOT: phi float*
+; CHECK: %j.01.us = phi i32
+; CHECK-NOT: phi float*
+define void @nopreheader(float* nocapture %a, i32 %n) nounwind {
+entry:
+ %0 = sdiv i32 %n, undef
+ indirectbr i8* undef, [label %bb10.preheader]
+
+bb10.preheader: ; preds = %bb4
+ indirectbr i8* undef, [label %bb8.preheader.lr.ph, label %return]
+
+bb8.preheader.lr.ph: ; preds = %bb10.preheader
+ indirectbr i8* null, [label %bb7.lr.ph.us, label %bb9]
+
+bb7.lr.ph.us: ; preds = %bb9.us, %bb8.preheader.lr.ph
+ %i.12.us = phi i32 [ %2, %bb9.us ], [ 0, %bb8.preheader.lr.ph ]
+ %tmp30 = mul i32 %0, %i.12.us
+ indirectbr i8* undef, [label %bb7.us]
+
+bb7.us: ; preds = %bb7.lr.ph.us, %bb7.us
+ %j.01.us = phi i32 [ 0, %bb7.lr.ph.us ], [ %1, %bb7.us ]
+ %tmp31 = add i32 %tmp30, %j.01.us
+ %scevgep9 = getelementptr float* %a, i32 %tmp31
+ store float undef, float* %scevgep9, align 1
+ %1 = add nsw i32 %j.01.us, 1
+ indirectbr i8* undef, [label %bb9.us, label %bb7.us]
+
+bb9.us: ; preds = %bb7.us
+ %2 = add nsw i32 %i.12.us, 1
+ indirectbr i8* undef, [label %bb7.lr.ph.us, label %return]
+
+bb9: ; preds = %bb9, %bb8.preheader.lr.ph
+ indirectbr i8* undef, [label %bb9, label %return]
+
+return: ; preds = %bb9, %bb9.us, %bb10.preheader
+ ret void
+}
+
+; In this case, SCEVExpander simply cannot materialize the AddRecExpr
+; that LSR picks. We must detect that %bb8.preheader does not have a
+; preheader and avoid performing LSR on %bb7.
+; CHECK: @nopreheader2
+; CHECK: bb7:
+; CHECK: %indvar = phi i32
+define fastcc void @nopreheader2([200 x i32]* nocapture %Array2) nounwind {
+entry:
+ indirectbr i8* undef, [label %bb]
+
+bb: ; preds = %bb, %entry
+ indirectbr i8* undef, [label %bb3, label %bb]
+
+bb3: ; preds = %bb3, %bb
+ indirectbr i8* undef, [label %bb8.preheader, label %bb3]
+
+bb8.preheader: ; preds = %bb9, %bb3
+ %indvar5 = phi i32 [ %indvar.next6, %bb9 ], [ 0, %bb3 ]
+ %tmp26 = add i32 %indvar5, 13
+ indirectbr i8* null, [label %bb7]
+
+bb7: ; preds = %bb8.preheader, %bb7
+ %indvar = phi i32 [ 0, %bb8.preheader ], [ %indvar.next, %bb7 ]
+ %scevgep = getelementptr [200 x i32]* %Array2, i32 %tmp26, i32 %indvar
+ store i32 undef, i32* %scevgep, align 4
+ %indvar.next = add i32 %indvar, 1
+ indirectbr i8* undef, [label %bb9, label %bb7]
+
+bb9: ; preds = %bb7
+ %indvar.next6 = add i32 %indvar5, 1
+ indirectbr i8* undef, [label %return, label %bb8.preheader]
+
+return: ; preds = %bb9
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/2012-01-16-nopreheader.ll b/test/Transforms/LoopStrengthReduce/2012-01-16-nopreheader.ll
new file mode 100644
index 0000000..3036a7e
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2012-01-16-nopreheader.ll
@@ -0,0 +1,113 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; <rdar://10701050> "Cannot split an edge from an IndirectBrInst" assert.
+
+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"
+
+; while.cond197 is a dominates the simplified loop while.cond238 but
+; has no with no preheader.
+;
+; CHECK: @nopreheader
+; CHECK: %while.cond238
+; CHECK: phi i64
+; CHECK-NOT: phi
+; CHECK: indirectbr
+define void @nopreheader(i8* %end) nounwind {
+entry:
+ br label %while.cond179
+
+while.cond179: ; preds = %if.end434, %if.end369, %if.end277, %if.end165
+ %s.1 = phi i8* [ undef, %if.end434 ], [ %incdec.ptr356, %if.end348 ], [ undef, %entry ]
+ indirectbr i8* undef, [label %land.rhs184, label %while.end453]
+
+land.rhs184: ; preds = %while.cond179
+ indirectbr i8* undef, [label %while.end453, label %while.cond197]
+
+while.cond197: ; preds = %land.rhs202, %land.rhs184
+ %0 = phi i64 [ %indvar.next11, %land.rhs202 ], [ 0, %land.rhs184 ]
+ indirectbr i8* undef, [label %land.rhs202, label %while.end215]
+
+land.rhs202: ; preds = %while.cond197
+ %indvar.next11 = add i64 %0, 1
+ indirectbr i8* undef, [label %while.end215, label %while.cond197]
+
+while.end215: ; preds = %land.rhs202, %while.cond197
+ indirectbr i8* undef, [label %PREMATURE, label %if.end221]
+
+if.end221: ; preds = %while.end215
+ indirectbr i8* undef, [label %while.cond238.preheader, label %lor.lhs.false227]
+
+lor.lhs.false227: ; preds = %if.end221
+ indirectbr i8* undef, [label %while.cond238.preheader, label %if.else]
+
+while.cond238.preheader: ; preds = %lor.lhs.false227, %if.end221
+ %tmp16 = add i64 %0, 2
+ indirectbr i8* undef, [label %while.cond238]
+
+while.cond238: ; preds = %land.rhs243, %while.cond238.preheader
+ %1 = phi i64 [ %indvar.next15, %land.rhs243 ], [ 0, %while.cond238.preheader ]
+ %tmp36 = add i64 %tmp16, %1
+ %s.3 = getelementptr i8* %s.1, i64 %tmp36
+ %cmp241 = icmp ult i8* %s.3, %end
+ indirectbr i8* undef, [label %land.rhs243, label %while.end256]
+
+land.rhs243: ; preds = %while.cond238
+ %indvar.next15 = add i64 %1, 1
+ indirectbr i8* undef, [label %while.end256, label %while.cond238]
+
+while.end256: ; preds = %land.rhs243, %while.cond238
+ indirectbr i8* undef, [label %PREMATURE]
+
+if.else: ; preds = %lor.lhs.false227
+ indirectbr i8* undef, [label %if.then297, label %if.else386]
+
+if.then297: ; preds = %if.else
+ indirectbr i8* undef, [label %PREMATURE, label %if.end307]
+
+if.end307: ; preds = %if.then297
+ indirectbr i8* undef, [label %if.end314, label %FAIL]
+
+if.end314: ; preds = %if.end307
+ indirectbr i8* undef, [label %if.end340]
+
+if.end340: ; preds = %while.end334
+ indirectbr i8* undef, [label %PREMATURE, label %if.end348]
+
+if.end348: ; preds = %if.end340
+ %incdec.ptr356 = getelementptr inbounds i8* undef, i64 2
+ indirectbr i8* undef, [label %while.cond179]
+
+if.else386: ; preds = %if.else
+ indirectbr i8* undef, [label %while.end453, label %if.end434]
+
+if.end434: ; preds = %if.then428, %if.end421
+ indirectbr i8* undef, [label %while.cond179]
+
+while.end453: ; preds = %if.else386, %land.rhs184, %while.cond179
+ indirectbr i8* undef, [label %PREMATURE, label %if.end459]
+
+if.end459: ; preds = %while.end453
+ indirectbr i8* undef, [label %if.then465, label %FAIL]
+
+if.then465: ; preds = %if.end459
+ indirectbr i8* undef, [label %return, label %if.then479]
+
+if.then479: ; preds = %if.then465
+ indirectbr i8* undef, [label %return]
+
+FAIL: ; preds = %if.end459, %if.end307, %land.lhs.true142, %land.lhs.true131, %while.end
+ indirectbr i8* undef, [label %DECL_FAIL]
+
+PREMATURE: ; preds = %while.end453, %while.end415, %if.end340, %while.end334, %if.then297, %while.end256, %while.end215
+ indirectbr i8* undef, [label %return, label %if.then495]
+
+if.then495: ; preds = %PREMATURE
+ indirectbr i8* undef, [label %return]
+
+DECL_FAIL: ; preds = %if.then488, %FAIL, %land.lhs.true99, %lor.lhs.false, %if.end83, %if.then39, %if.end
+ indirectbr i8* undef, [label %return]
+
+return: ; preds = %if.then512, %if.end504, %DECL_FAIL, %if.then495, %PREMATURE, %if.then479, %if.then465, %if.then69, %if.end52, %if.end19, %if.then
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/2012-03-15-nopreheader.ll b/test/Transforms/LoopStrengthReduce/2012-03-15-nopreheader.ll
new file mode 100644
index 0000000..0172492
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2012-03-15-nopreheader.ll
@@ -0,0 +1,155 @@
+; RUN: opt -loop-reduce -S < %s | FileCheck %s
+;
+; <rdar://problem/11049788> Segmentation fault: 11 in LoopStrengthReduce
+
+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"
+
+; IVUsers should not consider tmp128 a valid user because it is not in a
+; simplified loop nest.
+; CHECK: @nopreheader
+; CHECK: for.cond:
+; CHECK: %tmp128 = add i64 %0, %indvar65
+define void @nopreheader(i8* %cmd) nounwind ssp {
+entry:
+ indirectbr i8* undef, [label %while.cond]
+
+while.cond: ; preds = %while.body, %entry
+ %0 = phi i64 [ %indvar.next48, %while.body ], [ 0, %entry ]
+ indirectbr i8* undef, [label %while.end, label %while.body]
+
+while.body: ; preds = %lor.rhs, %lor.lhs.false17, %lor.lhs.false11, %lor.lhs.false, %land.rhs
+ %indvar.next48 = add i64 %0, 1
+ indirectbr i8* undef, [label %while.cond]
+
+while.end: ; preds = %lor.rhs, %while.cond
+ indirectbr i8* undef, [label %if.end152]
+
+if.end152: ; preds = %lor.lhs.false144, %if.end110
+ indirectbr i8* undef, [label %lor.lhs.false184, label %for.cond]
+
+lor.lhs.false184: ; preds = %lor.lhs.false177
+ indirectbr i8* undef, [label %return, label %for.cond]
+
+for.cond: ; preds = %for.inc, %lor.lhs.false184, %if.end152
+ %indvar65 = phi i64 [ %indvar.next66, %for.inc ], [ 0, %lor.lhs.false184 ], [ 0, %if.end152 ]
+ %tmp128 = add i64 %0, %indvar65
+ %s.4 = getelementptr i8* %cmd, i64 %tmp128
+ %tmp195 = load i8* %s.4, align 1
+ indirectbr i8* undef, [label %return, label %land.rhs198]
+
+land.rhs198: ; preds = %for.cond
+ indirectbr i8* undef, [label %return, label %for.inc]
+
+for.inc: ; preds = %lor.rhs234, %land.lhs.true228, %land.lhs.true216, %land.lhs.true204
+ %indvar.next66 = add i64 %indvar65, 1
+ indirectbr i8* undef, [label %for.cond]
+
+return: ; preds = %if.end677, %doshell, %if.then96
+ ret void
+}
+
+; Another case with a dominating loop that does not contain the IV
+; User. Just make sure it doesn't assert.
+define void @nopreheader2() nounwind ssp {
+entry:
+ indirectbr i8* undef, [label %while.cond, label %return]
+
+while.cond: ; preds = %while.cond.backedge, %entry
+ indirectbr i8* undef, [label %while.cond.backedge, label %lor.rhs]
+
+lor.rhs: ; preds = %while.cond
+ indirectbr i8* undef, [label %while.cond.backedge, label %while.end]
+
+while.cond.backedge: ; preds = %lor.rhs, %while.cond
+ indirectbr i8* undef, [label %while.cond]
+
+while.end: ; preds = %lor.rhs
+ indirectbr i8* undef, [label %if.then18, label %return]
+
+if.then18: ; preds = %while.end
+ indirectbr i8* undef, [label %if.end35, label %lor.lhs.false]
+
+lor.lhs.false: ; preds = %if.then18
+ indirectbr i8* undef, [label %if.end35, label %return]
+
+if.end35: ; preds = %lor.lhs.false, %if.then18
+ indirectbr i8* undef, [label %while.cond36]
+
+while.cond36: ; preds = %while.body49, %if.end35
+ %0 = phi i64 [ %indvar.next13, %while.body49 ], [ 0, %if.end35 ]
+ indirectbr i8* undef, [label %while.body49, label %lor.rhs42]
+
+lor.rhs42: ; preds = %while.cond36
+ indirectbr i8* undef, [label %while.body49, label %while.end52]
+
+while.body49: ; preds = %lor.rhs42, %while.cond36
+ %indvar.next13 = add i64 %0, 1
+ indirectbr i8* undef, [label %while.cond36]
+
+while.end52: ; preds = %lor.rhs42
+ indirectbr i8* undef, [label %land.lhs.true, label %return]
+
+land.lhs.true: ; preds = %while.end52
+ indirectbr i8* undef, [label %while.cond66.preheader, label %return]
+
+while.cond66.preheader: ; preds = %land.lhs.true
+ indirectbr i8* undef, [label %while.cond66]
+
+while.cond66: ; preds = %while.body77, %while.cond66.preheader
+ indirectbr i8* undef, [label %land.rhs, label %while.cond81.preheader]
+
+land.rhs: ; preds = %while.cond66
+ indirectbr i8* undef, [label %while.body77, label %while.cond81.preheader]
+
+while.cond81.preheader: ; preds = %land.rhs, %while.cond66
+ %tmp45 = add i64 undef, %0
+ %tmp46 = add i64 %tmp45, undef
+ indirectbr i8* undef, [label %while.cond81]
+
+while.body77: ; preds = %land.rhs
+ indirectbr i8* undef, [label %while.cond66]
+
+while.cond81: ; preds = %while.body94, %while.cond81.preheader
+ %tmp25 = add i64 %tmp46, undef
+ indirectbr i8* undef, [label %while.body94, label %lor.rhs87]
+
+lor.rhs87: ; preds = %while.cond81
+ indirectbr i8* undef, [label %while.body94, label %return]
+
+while.body94: ; preds = %lor.rhs87, %while.cond81
+ indirectbr i8* undef, [label %while.cond81]
+
+return: ; preds = %if.end216, %land.lhs.true183, %land.lhs.true, %while.end52, %lor.lhs.false, %while.end, %entry
+ ret void
+}
+
+; Test a phi operand IV User dominated by a no-preheader loop.
+define void @nopreheader3() nounwind uwtable ssp align 2 {
+entry:
+ indirectbr i8* blockaddress(@nopreheader3, %if.end10), [label %if.end22, label %if.end10]
+
+if.end10: ; preds = %entry
+ indirectbr i8* blockaddress(@nopreheader3, %if.end6.i), [label %if.end22, label %if.end6.i]
+
+if.end6.i: ; preds = %if.end10
+ indirectbr i8* blockaddress(@nopreheader3, %while.cond2.preheader.i.i), [label %if.then12, label %while.cond2.preheader.i.i]
+
+while.cond2.preheader.i.i: ; preds = %while.end.i18.i, %if.end6.i
+ indirectbr i8* blockaddress(@nopreheader3, %while.cond2.i.i), [label %while.cond2.i.i]
+
+while.cond2.i.i: ; preds = %while.cond2.i.i, %while.cond2.preheader.i.i
+ %i1.1.i14.i = phi i32 [ %add.i15.i, %while.cond2.i.i ], [ undef, %while.cond2.preheader.i.i ]
+ %add.i15.i = add nsw i32 %i1.1.i14.i, undef
+ indirectbr i8* blockaddress(@nopreheader3, %while.end.i18.i), [label %while.cond2.i.i, label %while.end.i18.i]
+
+while.end.i18.i: ; preds = %while.cond2.i.i
+ indirectbr i8* blockaddress(@nopreheader3, %while.cond2.preheader.i.i), [label %if.then12, label %while.cond2.preheader.i.i]
+
+if.then12: ; preds = %while.end.i18.i, %if.end6.i
+ %i1.0.lcssa.i.i = phi i32 [ undef, %if.end6.i ], [ %i1.1.i14.i, %while.end.i18.i ]
+ indirectbr i8* blockaddress(@nopreheader3, %if.end22), [label %if.end22]
+
+if.end22: ; preds = %if.then12, %if.end10, %entry
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/2012-03-26-constexpr.ll b/test/Transforms/LoopStrengthReduce/2012-03-26-constexpr.ll
new file mode 100644
index 0000000..c9b11a9
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/2012-03-26-constexpr.ll
@@ -0,0 +1,49 @@
+; RUN: opt < %s -loop-reduce -S
+; PR11950: isHighCostExpansion crashes on ConstExpr
+;
+; The crash happened during IVChain analysis (CollectChains). We don't
+; really care how LSR decides to transform this loop, so we don't
+; check it. As long as the analysis doesn't crash we're ok.
+target datalayout = "e-p:64:64:64-n32:64"
+
+%struct.this_structure_s.0.5 = type { [6144 x [8 x i32]], [6144 x [8 x i32]], [6147 x [4 x i32]], [8 x i32], [2 x i8*], [2 x i8*], [6144 x i8], [6144 x i32], [6144 x i32], [4 x [4 x i8]] }
+
+define internal fastcc void @someFunction(%struct.this_structure_s.0.5* nocapture %scratch, i32 %stage, i32 %cbSize) nounwind {
+entry:
+ %0 = getelementptr inbounds %struct.this_structure_s.0.5* %scratch, i32 0, i32 4, i32 %stage
+ %1 = load i8** %0, align 4
+ %2 = getelementptr inbounds %struct.this_structure_s.0.5* %scratch, i32 0, i32 5, i32 %stage
+ %3 = load i8** %2, align 4
+ %4 = getelementptr inbounds %struct.this_structure_s.0.5* %scratch, i32 0, i32 2, i32 0, i32 0
+ %tmp11 = shl i32 %stage, 1
+ %tmp1325 = or i32 %tmp11, 1
+ br label %__label_D_1608
+
+__label_D_1608: ; preds = %__label_D_1608, %entry
+ %i.12 = phi i32 [ 0, %entry ], [ %10, %__label_D_1608 ]
+ %tmp = shl i32 %i.12, 2
+ %lvar_g.13 = getelementptr i32* %4, i32 %tmp
+ %tmp626 = or i32 %tmp, 1
+ %scevgep = getelementptr i32* %4, i32 %tmp626
+ %tmp727 = or i32 %tmp, 2
+ %scevgep8 = getelementptr i32* %4, i32 %tmp727
+ %tmp928 = or i32 %tmp, 3
+ %scevgep10 = getelementptr i32* %4, i32 %tmp928
+ %scevgep12 = getelementptr %struct.this_structure_s.0.5* %scratch, i32 0, i32 9, i32 %tmp11, i32 %i.12
+ %scevgep14 = getelementptr %struct.this_structure_s.0.5* %scratch, i32 0, i32 9, i32 %tmp1325, i32 %i.12
+ %5 = load i8* %scevgep12, align 1
+ %6 = sext i8 %5 to i32
+ %7 = load i8* %scevgep14, align 1
+ %8 = sext i8 %7 to i32
+ store i32 0, i32* %lvar_g.13, align 4
+ store i32 %8, i32* %scevgep, align 4
+ store i32 %6, i32* %scevgep8, align 4
+ %9 = add nsw i32 %8, %6
+ store i32 %9, i32* %scevgep10, align 4
+ %10 = add nsw i32 %i.12, 1
+ %exitcond = icmp eq i32 %10, 3
+ br i1 %exitcond, label %return, label %__label_D_1608
+
+return: ; preds = %__label_D_1608
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll b/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll
new file mode 100644
index 0000000..9189d79
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll
@@ -0,0 +1,292 @@
+; RUN: llc < %s -O3 -march=thumb -mcpu=cortex-a9 | FileCheck %s -check-prefix=A9
+
+; @simple is the most basic chain of address induction variables. Chaining
+; saves at least one register and avoids complex addressing and setup
+; code.
+;
+; A9: @simple
+; no expensive address computation in the preheader
+; A9: lsl
+; A9-NOT: lsl
+; A9: %loop
+; no complex address modes
+; A9-NOT: lsl
+define i32 @simple(i32* %a, i32* %b, i32 %x) nounwind {
+entry:
+ br label %loop
+loop:
+ %iv = phi i32* [ %a, %entry ], [ %iv4, %loop ]
+ %s = phi i32 [ 0, %entry ], [ %s4, %loop ]
+ %v = load i32* %iv
+ %iv1 = getelementptr inbounds i32* %iv, i32 %x
+ %v1 = load i32* %iv1
+ %iv2 = getelementptr inbounds i32* %iv1, i32 %x
+ %v2 = load i32* %iv2
+ %iv3 = getelementptr inbounds i32* %iv2, i32 %x
+ %v3 = load i32* %iv3
+ %s1 = add i32 %s, %v
+ %s2 = add i32 %s1, %v1
+ %s3 = add i32 %s2, %v2
+ %s4 = add i32 %s3, %v3
+ %iv4 = getelementptr inbounds i32* %iv3, i32 %x
+ %cmp = icmp eq i32* %iv4, %b
+ br i1 %cmp, label %exit, label %loop
+exit:
+ ret i32 %s4
+}
+
+; @user is not currently chained because the IV is live across memory ops.
+;
+; A9: @user
+; stride multiples computed in the preheader
+; A9: lsl
+; A9: lsl
+; A9: %loop
+; complex address modes
+; A9: lsl
+; A9: lsl
+define i32 @user(i32* %a, i32* %b, i32 %x) nounwind {
+entry:
+ br label %loop
+loop:
+ %iv = phi i32* [ %a, %entry ], [ %iv4, %loop ]
+ %s = phi i32 [ 0, %entry ], [ %s4, %loop ]
+ %v = load i32* %iv
+ %iv1 = getelementptr inbounds i32* %iv, i32 %x
+ %v1 = load i32* %iv1
+ %iv2 = getelementptr inbounds i32* %iv1, i32 %x
+ %v2 = load i32* %iv2
+ %iv3 = getelementptr inbounds i32* %iv2, i32 %x
+ %v3 = load i32* %iv3
+ %s1 = add i32 %s, %v
+ %s2 = add i32 %s1, %v1
+ %s3 = add i32 %s2, %v2
+ %s4 = add i32 %s3, %v3
+ %iv4 = getelementptr inbounds i32* %iv3, i32 %x
+ store i32 %s4, i32* %iv
+ %cmp = icmp eq i32* %iv4, %b
+ br i1 %cmp, label %exit, label %loop
+exit:
+ ret i32 %s4
+}
+
+; @extrastride is a slightly more interesting case of a single
+; complete chain with multiple strides. The test case IR is what LSR
+; used to do, and exactly what we don't want to do. LSR's new IV
+; chaining feature should now undo the damage.
+;
+; A9: extrastride:
+; no spills
+; A9-NOT: str
+; only one stride multiple in the preheader
+; A9: lsl
+; A9-NOT: {{str r|lsl}}
+; A9: %for.body{{$}}
+; no complex address modes or reloads
+; A9-NOT: {{ldr .*[sp]|lsl}}
+define void @extrastride(i8* nocapture %main, i32 %main_stride, i32* nocapture %res, i32 %x, i32 %y, i32 %z) nounwind {
+entry:
+ %cmp8 = icmp eq i32 %z, 0
+ br i1 %cmp8, label %for.end, label %for.body.lr.ph
+
+for.body.lr.ph: ; preds = %entry
+ %add.ptr.sum = shl i32 %main_stride, 1 ; s*2
+ %add.ptr1.sum = add i32 %add.ptr.sum, %main_stride ; s*3
+ %add.ptr2.sum = add i32 %x, %main_stride ; s + x
+ %add.ptr4.sum = shl i32 %main_stride, 2 ; s*4
+ %add.ptr3.sum = add i32 %add.ptr2.sum, %add.ptr4.sum ; total IV stride = s*5+x
+ br label %for.body
+
+for.body: ; preds = %for.body.lr.ph, %for.body
+ %main.addr.011 = phi i8* [ %main, %for.body.lr.ph ], [ %add.ptr6, %for.body ]
+ %i.010 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+ %res.addr.09 = phi i32* [ %res, %for.body.lr.ph ], [ %add.ptr7, %for.body ]
+ %0 = bitcast i8* %main.addr.011 to i32*
+ %1 = load i32* %0, align 4
+ %add.ptr = getelementptr inbounds i8* %main.addr.011, i32 %main_stride
+ %2 = bitcast i8* %add.ptr to i32*
+ %3 = load i32* %2, align 4
+ %add.ptr1 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr.sum
+ %4 = bitcast i8* %add.ptr1 to i32*
+ %5 = load i32* %4, align 4
+ %add.ptr2 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr1.sum
+ %6 = bitcast i8* %add.ptr2 to i32*
+ %7 = load i32* %6, align 4
+ %add.ptr3 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr4.sum
+ %8 = bitcast i8* %add.ptr3 to i32*
+ %9 = load i32* %8, align 4
+ %add = add i32 %3, %1
+ %add4 = add i32 %add, %5
+ %add5 = add i32 %add4, %7
+ %add6 = add i32 %add5, %9
+ store i32 %add6, i32* %res.addr.09, align 4
+ %add.ptr6 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr3.sum
+ %add.ptr7 = getelementptr inbounds i32* %res.addr.09, i32 %y
+ %inc = add i32 %i.010, 1
+ %cmp = icmp eq i32 %inc, %z
+ br i1 %cmp, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
+
+; @foldedidx is an unrolled variant of this loop:
+; for (unsigned long i = 0; i < len; i += s) {
+; c[i] = a[i] + b[i];
+; }
+; where 's' can be folded into the addressing mode.
+; Consequently, we should *not* form any chains.
+;
+; A9: foldedidx:
+; A9: ldrb.w {{r[0-9]|lr}}, [{{r[0-9]|lr}}, #3]
+define void @foldedidx(i8* nocapture %a, i8* nocapture %b, i8* nocapture %c) nounwind ssp {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %i.07 = phi i32 [ 0, %entry ], [ %inc.3, %for.body ]
+ %arrayidx = getelementptr inbounds i8* %a, i32 %i.07
+ %0 = load i8* %arrayidx, align 1
+ %conv5 = zext i8 %0 to i32
+ %arrayidx1 = getelementptr inbounds i8* %b, i32 %i.07
+ %1 = load i8* %arrayidx1, align 1
+ %conv26 = zext i8 %1 to i32
+ %add = add nsw i32 %conv26, %conv5
+ %conv3 = trunc i32 %add to i8
+ %arrayidx4 = getelementptr inbounds i8* %c, i32 %i.07
+ store i8 %conv3, i8* %arrayidx4, align 1
+ %inc1 = or i32 %i.07, 1
+ %arrayidx.1 = getelementptr inbounds i8* %a, i32 %inc1
+ %2 = load i8* %arrayidx.1, align 1
+ %conv5.1 = zext i8 %2 to i32
+ %arrayidx1.1 = getelementptr inbounds i8* %b, i32 %inc1
+ %3 = load i8* %arrayidx1.1, align 1
+ %conv26.1 = zext i8 %3 to i32
+ %add.1 = add nsw i32 %conv26.1, %conv5.1
+ %conv3.1 = trunc i32 %add.1 to i8
+ %arrayidx4.1 = getelementptr inbounds i8* %c, i32 %inc1
+ store i8 %conv3.1, i8* %arrayidx4.1, align 1
+ %inc.12 = or i32 %i.07, 2
+ %arrayidx.2 = getelementptr inbounds i8* %a, i32 %inc.12
+ %4 = load i8* %arrayidx.2, align 1
+ %conv5.2 = zext i8 %4 to i32
+ %arrayidx1.2 = getelementptr inbounds i8* %b, i32 %inc.12
+ %5 = load i8* %arrayidx1.2, align 1
+ %conv26.2 = zext i8 %5 to i32
+ %add.2 = add nsw i32 %conv26.2, %conv5.2
+ %conv3.2 = trunc i32 %add.2 to i8
+ %arrayidx4.2 = getelementptr inbounds i8* %c, i32 %inc.12
+ store i8 %conv3.2, i8* %arrayidx4.2, align 1
+ %inc.23 = or i32 %i.07, 3
+ %arrayidx.3 = getelementptr inbounds i8* %a, i32 %inc.23
+ %6 = load i8* %arrayidx.3, align 1
+ %conv5.3 = zext i8 %6 to i32
+ %arrayidx1.3 = getelementptr inbounds i8* %b, i32 %inc.23
+ %7 = load i8* %arrayidx1.3, align 1
+ %conv26.3 = zext i8 %7 to i32
+ %add.3 = add nsw i32 %conv26.3, %conv5.3
+ %conv3.3 = trunc i32 %add.3 to i8
+ %arrayidx4.3 = getelementptr inbounds i8* %c, i32 %inc.23
+ store i8 %conv3.3, i8* %arrayidx4.3, align 1
+ %inc.3 = add nsw i32 %i.07, 4
+ %exitcond.3 = icmp eq i32 %inc.3, 400
+ br i1 %exitcond.3, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; @testNeon is an important example of the nead for ivchains.
+;
+; Currently we have three extra add.w's that keep the store address
+; live past the next increment because ISEL is unfortunately undoing
+; the store chain. ISEL also fails to convert the stores to
+; post-increment addressing. However, the loads should use
+; post-increment addressing, no add's or add.w's beyond the three
+; mentioned. Most importantly, there should be no spills or reloads!
+;
+; CHECK: testNeon:
+; CHECK: %.lr.ph
+; CHECK-NOT: lsl.w
+; CHECK-NOT: {{ldr|str|adds|add r}}
+; CHECK: add.w r
+; CHECK-NOT: {{ldr|str|adds|add r}}
+; CHECK: add.w r
+; CHECK-NOT: {{ldr|str|adds|add r}}
+; CHECK: add.w r
+; CHECK-NOT: {{ldr|str|adds|add r}}
+; CHECK-NOT: add.w r
+; CHECK: bne
+define hidden void @testNeon(i8* %ref_data, i32 %ref_stride, i32 %limit, <16 x i8>* nocapture %data) nounwind optsize {
+ %1 = icmp sgt i32 %limit, 0
+ br i1 %1, label %.lr.ph, label %45
+
+.lr.ph: ; preds = %0
+ %2 = shl nsw i32 %ref_stride, 1
+ %3 = mul nsw i32 %ref_stride, 3
+ %4 = shl nsw i32 %ref_stride, 2
+ %5 = mul nsw i32 %ref_stride, 5
+ %6 = mul nsw i32 %ref_stride, 6
+ %7 = mul nsw i32 %ref_stride, 7
+ %8 = shl nsw i32 %ref_stride, 3
+ %9 = sub i32 0, %8
+ %10 = mul i32 %limit, -64
+ br label %11
+
+; <label>:11 ; preds = %11, %.lr.ph
+ %.05 = phi i8* [ %ref_data, %.lr.ph ], [ %42, %11 ]
+ %counter.04 = phi i32 [ 0, %.lr.ph ], [ %44, %11 ]
+ %result.03 = phi <16 x i8> [ zeroinitializer, %.lr.ph ], [ %41, %11 ]
+ %.012 = phi <16 x i8>* [ %data, %.lr.ph ], [ %43, %11 ]
+ %12 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %.05, i32 1) nounwind
+ %13 = getelementptr inbounds i8* %.05, i32 %ref_stride
+ %14 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %13, i32 1) nounwind
+ %15 = shufflevector <1 x i64> %12, <1 x i64> %14, <2 x i32> <i32 0, i32 1>
+ %16 = bitcast <2 x i64> %15 to <16 x i8>
+ %17 = getelementptr inbounds <16 x i8>* %.012, i32 1
+ store <16 x i8> %16, <16 x i8>* %.012, align 4
+ %18 = getelementptr inbounds i8* %.05, i32 %2
+ %19 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %18, i32 1) nounwind
+ %20 = getelementptr inbounds i8* %.05, i32 %3
+ %21 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %20, i32 1) nounwind
+ %22 = shufflevector <1 x i64> %19, <1 x i64> %21, <2 x i32> <i32 0, i32 1>
+ %23 = bitcast <2 x i64> %22 to <16 x i8>
+ %24 = getelementptr inbounds <16 x i8>* %.012, i32 2
+ store <16 x i8> %23, <16 x i8>* %17, align 4
+ %25 = getelementptr inbounds i8* %.05, i32 %4
+ %26 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %25, i32 1) nounwind
+ %27 = getelementptr inbounds i8* %.05, i32 %5
+ %28 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %27, i32 1) nounwind
+ %29 = shufflevector <1 x i64> %26, <1 x i64> %28, <2 x i32> <i32 0, i32 1>
+ %30 = bitcast <2 x i64> %29 to <16 x i8>
+ %31 = getelementptr inbounds <16 x i8>* %.012, i32 3
+ store <16 x i8> %30, <16 x i8>* %24, align 4
+ %32 = getelementptr inbounds i8* %.05, i32 %6
+ %33 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %32, i32 1) nounwind
+ %34 = getelementptr inbounds i8* %.05, i32 %7
+ %35 = tail call <1 x i64> @llvm.arm.neon.vld1.v1i64(i8* %34, i32 1) nounwind
+ %36 = shufflevector <1 x i64> %33, <1 x i64> %35, <2 x i32> <i32 0, i32 1>
+ %37 = bitcast <2 x i64> %36 to <16 x i8>
+ store <16 x i8> %37, <16 x i8>* %31, align 4
+ %38 = add <16 x i8> %16, %23
+ %39 = add <16 x i8> %38, %30
+ %40 = add <16 x i8> %39, %37
+ %41 = add <16 x i8> %result.03, %40
+ %42 = getelementptr i8* %.05, i32 %9
+ %43 = getelementptr inbounds <16 x i8>* %.012, i32 -64
+ %44 = add nsw i32 %counter.04, 1
+ %exitcond = icmp eq i32 %44, %limit
+ br i1 %exitcond, label %._crit_edge, label %11
+
+._crit_edge: ; preds = %11
+ %scevgep = getelementptr <16 x i8>* %data, i32 %10
+ br label %45
+
+; <label>:45 ; preds = %._crit_edge, %0
+ %result.0.lcssa = phi <16 x i8> [ %41, %._crit_edge ], [ zeroinitializer, %0 ]
+ %.01.lcssa = phi <16 x i8>* [ %scevgep, %._crit_edge ], [ %data, %0 ]
+ store <16 x i8> %result.0.lcssa, <16 x i8>* %.01.lcssa, align 4
+ ret void
+}
+
+declare <1 x i64> @llvm.arm.neon.vld1.v1i64(i8*, i32) nounwind readonly
diff --git a/test/Transforms/LoopStrengthReduce/ARM/lit.local.cfg b/test/Transforms/LoopStrengthReduce/ARM/lit.local.cfg
new file mode 100644
index 0000000..bac2ffa
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/ARM/lit.local.cfg
@@ -0,0 +1,6 @@
+config.suffixes = ['.ll']
+
+targets = set(config.root.targets_to_build.split())
+if not 'ARM' in targets:
+ config.unsupported = True
+
diff --git a/test/Transforms/LoopStrengthReduce/X86/2011-11-29-postincphi.ll b/test/Transforms/LoopStrengthReduce/X86/2011-11-29-postincphi.ll
new file mode 100644
index 0000000..cb23ad0
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/2011-11-29-postincphi.ll
@@ -0,0 +1,36 @@
+; RUN: llc < %s | FileCheck %s
+;
+; PR11431: handle a phi operand that is replaced by a postinc user.
+; LSR first expands %t3 to %t2 in %phi
+; LSR then expands %t2 in %phi into two decrements, one on each loop exit.
+
+target datalayout = "e-p:64:64:64-S128-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"
+
+declare i1 @check() nounwind
+
+; Check that LSR did something close to the behavior at the time of the bug.
+; CHECK: @sqlite3DropTriggerPtr
+; CHECK: incq %rax
+; CHECK: jne
+; CHECK: decq %rax
+; CHECK: ret
+define i64 @sqlite3DropTriggerPtr() nounwind {
+bb:
+ %cmp = call zeroext i1 @check()
+ br label %bb1
+
+bb1: ; preds = %bb4, %bb
+ %t0 = phi i64 [ 0, %bb ], [ %t3, %bb4 ]
+ %t2 = phi i64 [ 1, %bb ], [ %t5, %bb4 ]
+ %t3 = add nsw i64 %t0, 1
+ br i1 %cmp, label %bb4, label %bb8
+
+bb4: ; preds = %bb1
+ %t5 = add nsw i64 %t2, 1
+ br i1 %cmp, label %bb1, label %bb8
+
+bb8: ; preds = %bb8, %bb4
+ %phi = phi i64 [ %t3, %bb1 ], [ %t2, %bb4 ]
+ ret i64 %phi
+}
diff --git a/test/Transforms/LoopStrengthReduce/X86/2011-12-04-loserreg.ll b/test/Transforms/LoopStrengthReduce/X86/2011-12-04-loserreg.ll
new file mode 100644
index 0000000..5108650
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/2011-12-04-loserreg.ll
@@ -0,0 +1,96 @@
+; RUN: llc < %s | FileCheck %s
+;
+; Test LSR's ability to prune formulae that refer to nonexistant
+; AddRecs in other loops.
+;
+; Unable to reduce this case further because it requires LSR to exceed
+; ComplexityLimit.
+;
+; We really just want to ensure that LSR can process this loop without
+; finding an unsatisfactory solution and bailing out. I've added
+; dummyout, an obvious candidate for postinc replacement so we can
+; verify that LSR removes it.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-darwin"
+
+; CHECK: @test
+; CHECK: # %for.body{{$}}
+; dummyiv copy should be removed
+; CHECK-NOT: movq
+; CHECK: # %for.cond19.preheader
+; dummycnt should be removed
+; CHECK-NOT: incq
+; CHECK: # %for.body23{{$}}
+define i64 @test(i64 %count, float* nocapture %srcrow, i32* nocapture %destrow) nounwind uwtable ssp {
+entry:
+ %cmp34 = icmp eq i64 %count, 0
+ br i1 %cmp34, label %for.end29, label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %dummyiv = phi i64 [ %dummycnt, %for.body ], [ 0, %entry ]
+ %indvars.iv39 = phi i64 [ %indvars.iv.next40, %for.body ], [ 0, %entry ]
+ %dp.036 = phi i32* [ %add.ptr, %for.body ], [ %destrow, %entry ]
+ %p.035 = phi float* [ %incdec.ptr4, %for.body ], [ %srcrow, %entry ]
+ %incdec.ptr = getelementptr inbounds float* %p.035, i64 1
+ %0 = load float* %incdec.ptr, align 4
+ %incdec.ptr2 = getelementptr inbounds float* %p.035, i64 2
+ %1 = load float* %incdec.ptr2, align 4
+ %incdec.ptr3 = getelementptr inbounds float* %p.035, i64 3
+ %2 = load float* %incdec.ptr3, align 4
+ %incdec.ptr4 = getelementptr inbounds float* %p.035, i64 4
+ %3 = load float* %incdec.ptr4, align 4
+ %4 = load i32* %dp.036, align 4
+ %conv5 = fptoui float %0 to i32
+ %or = or i32 %4, %conv5
+ %arrayidx6 = getelementptr inbounds i32* %dp.036, i64 1
+ %5 = load i32* %arrayidx6, align 4
+ %conv7 = fptoui float %1 to i32
+ %or8 = or i32 %5, %conv7
+ %arrayidx9 = getelementptr inbounds i32* %dp.036, i64 2
+ %6 = load i32* %arrayidx9, align 4
+ %conv10 = fptoui float %2 to i32
+ %or11 = or i32 %6, %conv10
+ %arrayidx12 = getelementptr inbounds i32* %dp.036, i64 3
+ %7 = load i32* %arrayidx12, align 4
+ %conv13 = fptoui float %3 to i32
+ %or14 = or i32 %7, %conv13
+ store i32 %or, i32* %dp.036, align 4
+ store i32 %or8, i32* %arrayidx6, align 4
+ store i32 %or11, i32* %arrayidx9, align 4
+ store i32 %or14, i32* %arrayidx12, align 4
+ %add.ptr = getelementptr inbounds i32* %dp.036, i64 4
+ %indvars.iv.next40 = add i64 %indvars.iv39, 4
+ %dummycnt = add i64 %dummyiv, 1
+ %cmp = icmp ult i64 %indvars.iv.next40, %count
+ br i1 %cmp, label %for.body, label %for.cond19.preheader
+
+for.cond19.preheader: ; preds = %for.body
+ %dummyout = add i64 %dummyiv, 1
+ %rem = and i64 %count, 3
+ %cmp2130 = icmp eq i64 %rem, 0
+ br i1 %cmp2130, label %for.end29, label %for.body23.lr.ph
+
+for.body23.lr.ph: ; preds = %for.cond19.preheader
+ %8 = and i64 %count, 3
+ br label %for.body23
+
+for.body23: ; preds = %for.body23, %for.body23.lr.ph
+ %indvars.iv = phi i64 [ 0, %for.body23.lr.ph ], [ %indvars.iv.next, %for.body23 ]
+ %dp.132 = phi i32* [ %add.ptr, %for.body23.lr.ph ], [ %incdec.ptr28, %for.body23 ]
+ %p.131 = phi float* [ %incdec.ptr4, %for.body23.lr.ph ], [ %incdec.ptr24, %for.body23 ]
+ %incdec.ptr24 = getelementptr inbounds float* %p.131, i64 1
+ %9 = load float* %incdec.ptr24, align 4
+ %10 = load i32* %dp.132, align 4
+ %conv25 = fptoui float %9 to i32
+ %or26 = or i32 %10, %conv25
+ store i32 %or26, i32* %dp.132, align 4
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %incdec.ptr28 = getelementptr inbounds i32* %dp.132, i64 1
+ %exitcond = icmp eq i64 %indvars.iv.next, %8
+ br i1 %exitcond, label %for.end29, label %for.body23
+
+for.end29: ; preds = %entry, %for.body23, %for.cond19.preheader
+ %result = phi i64 [ 0, %entry ], [ %dummyout, %for.body23 ], [ %dummyout, %for.cond19.preheader ]
+ ret i64 %result
+}
diff --git a/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll b/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
new file mode 100644
index 0000000..2dcaab8
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll
@@ -0,0 +1,92 @@
+; RUN: llc < %s -O3 -march=x86-64 -mcpu=core2 | FileCheck %s
+
+declare i1 @check() nounwind
+declare i1 @foo(i8*, i8*, i8*) nounwind
+
+; Check that redundant phi elimination ran
+; CHECK: @test
+; CHECK: %while.body.i
+; CHECK: movs
+; CHECK-NOT: movs
+; CHECK: %for.end.i
+define i32 @test(i8* %base) nounwind uwtable ssp {
+entry:
+ br label %while.body.lr.ph.i
+
+while.body.lr.ph.i: ; preds = %cond.true.i
+ br label %while.body.i
+
+while.body.i: ; preds = %cond.true29.i, %while.body.lr.ph.i
+ %indvars.iv7.i = phi i64 [ 16, %while.body.lr.ph.i ], [ %indvars.iv.next8.i, %cond.true29.i ]
+ %i.05.i = phi i64 [ 0, %while.body.lr.ph.i ], [ %indvars.iv7.i, %cond.true29.i ]
+ %sext.i = shl i64 %i.05.i, 32
+ %idx.ext.i = ashr exact i64 %sext.i, 32
+ %add.ptr.sum.i = add i64 %idx.ext.i, 16
+ br label %for.body.i
+
+for.body.i: ; preds = %for.body.i, %while.body.i
+ %indvars.iv.i = phi i64 [ 0, %while.body.i ], [ %indvars.iv.next.i, %for.body.i ]
+ %add.ptr.sum = add i64 %add.ptr.sum.i, %indvars.iv.i
+ %arrayidx22.i = getelementptr inbounds i8* %base, i64 %add.ptr.sum
+ %0 = load i8* %arrayidx22.i, align 1
+ %indvars.iv.next.i = add i64 %indvars.iv.i, 1
+ %cmp = call i1 @check() nounwind
+ br i1 %cmp, label %for.end.i, label %for.body.i
+
+for.end.i: ; preds = %for.body.i
+ %add.ptr.i144 = getelementptr inbounds i8* %base, i64 %add.ptr.sum.i
+ %cmp2 = tail call i1 @foo(i8* %add.ptr.i144, i8* %add.ptr.i144, i8* undef) nounwind
+ br i1 %cmp2, label %cond.true29.i, label %cond.false35.i
+
+cond.true29.i: ; preds = %for.end.i
+ %indvars.iv.next8.i = add i64 %indvars.iv7.i, 16
+ br i1 false, label %exit, label %while.body.i
+
+cond.false35.i: ; preds = %for.end.i
+ unreachable
+
+exit: ; preds = %cond.true29.i, %cond.true.i
+ ret i32 0
+}
+
+%struct.anon.7.91.199.307.415.475.559.643.751.835.943.1003.1111.1219.1351.1375.1399.1435.1471.1483.1519.1531.1651.1771 = type { i32, i32, i32 }
+
+@tags = external global [5000 x %struct.anon.7.91.199.307.415.475.559.643.751.835.943.1003.1111.1219.1351.1375.1399.1435.1471.1483.1519.1531.1651.1771], align 16
+
+; PR11782: SCEVExpander assert
+;
+; Test phi reuse after LSR that requires SCEVExpander to hoist an
+; interesting GEP.
+;
+; CHECK: @test2
+; CHECK: %entry
+; CHECK-NOT: mov
+; CHECK: jne
+define void @test2(i32 %n) nounwind uwtable {
+entry:
+ br i1 undef, label %while.end, label %for.cond468
+
+for.cond468: ; preds = %if.then477, %entry
+ %indvars.iv1163 = phi i64 [ %indvars.iv.next1164, %if.then477 ], [ 1, %entry ]
+ %k.0.in = phi i32* [ %last, %if.then477 ], [ getelementptr inbounds ([5000 x %struct.anon.7.91.199.307.415.475.559.643.751.835.943.1003.1111.1219.1351.1375.1399.1435.1471.1483.1519.1531.1651.1771]* @tags, i64 0, i64 0, i32 2), %entry ]
+ %k.0 = load i32* %k.0.in, align 4
+ %0 = trunc i64 %indvars.iv1163 to i32
+ %cmp469 = icmp slt i32 %0, %n
+ br i1 %cmp469, label %for.body471, label %for.inc498
+
+for.body471: ; preds = %for.cond468
+ %first = getelementptr inbounds [5000 x %struct.anon.7.91.199.307.415.475.559.643.751.835.943.1003.1111.1219.1351.1375.1399.1435.1471.1483.1519.1531.1651.1771]* @tags, i64 0, i64 %indvars.iv1163, i32 1
+ %1 = load i32* %first, align 4
+ br i1 undef, label %if.then477, label %for.inc498
+
+if.then477: ; preds = %for.body471
+ %last = getelementptr inbounds [5000 x %struct.anon.7.91.199.307.415.475.559.643.751.835.943.1003.1111.1219.1351.1375.1399.1435.1471.1483.1519.1531.1651.1771]* @tags, i64 0, i64 %indvars.iv1163, i32 2
+ %indvars.iv.next1164 = add i64 %indvars.iv1163, 1
+ br label %for.cond468
+
+for.inc498: ; preds = %for.inc498, %for.body471, %for.cond468
+ br label %for.inc498
+
+while.end: ; preds = %entry
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/X86/dg.exp b/test/Transforms/LoopStrengthReduce/X86/dg.exp
deleted file mode 100644
index 7b7bd4e..0000000
--- a/test/Transforms/LoopStrengthReduce/X86/dg.exp
+++ /dev/null
@@ -1,5 +0,0 @@
-load_lib llvm.exp
-
-if { [llvm_supports_target X86] } {
- RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
-}
diff --git a/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll b/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll
new file mode 100644
index 0000000..e42b67f
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll
@@ -0,0 +1,300 @@
+; RUN: llc < %s -O3 -march=x86-64 -mcpu=core2 | FileCheck %s -check-prefix=X64
+; RUN: llc < %s -O3 -march=x86 -mcpu=core2 | FileCheck %s -check-prefix=X32
+
+; @simple is the most basic chain of address induction variables. Chaining
+; saves at least one register and avoids complex addressing and setup
+; code.
+;
+; X64: @simple
+; %x * 4
+; X64: shlq $2
+; no other address computation in the preheader
+; X64-NEXT: xorl
+; X64-NEXT: .align
+; X64: %loop
+; no complex address modes
+; X64-NOT: (%{{[^)]+}},%{{[^)]+}},
+;
+; X32: @simple
+; no expensive address computation in the preheader
+; X32-NOT: imul
+; X32: %loop
+; no complex address modes
+; X32-NOT: (%{{[^)]+}},%{{[^)]+}},
+define i32 @simple(i32* %a, i32* %b, i32 %x) nounwind {
+entry:
+ br label %loop
+loop:
+ %iv = phi i32* [ %a, %entry ], [ %iv4, %loop ]
+ %s = phi i32 [ 0, %entry ], [ %s4, %loop ]
+ %v = load i32* %iv
+ %iv1 = getelementptr inbounds i32* %iv, i32 %x
+ %v1 = load i32* %iv1
+ %iv2 = getelementptr inbounds i32* %iv1, i32 %x
+ %v2 = load i32* %iv2
+ %iv3 = getelementptr inbounds i32* %iv2, i32 %x
+ %v3 = load i32* %iv3
+ %s1 = add i32 %s, %v
+ %s2 = add i32 %s1, %v1
+ %s3 = add i32 %s2, %v2
+ %s4 = add i32 %s3, %v3
+ %iv4 = getelementptr inbounds i32* %iv3, i32 %x
+ %cmp = icmp eq i32* %iv4, %b
+ br i1 %cmp, label %exit, label %loop
+exit:
+ ret i32 %s4
+}
+
+; @user is not currently chained because the IV is live across memory ops.
+;
+; X64: @user
+; X64: shlq $4
+; X64: lea
+; X64: lea
+; X64: %loop
+; complex address modes
+; X64: (%{{[^)]+}},%{{[^)]+}},
+;
+; X32: @user
+; expensive address computation in the preheader
+; X32: imul
+; X32: %loop
+; complex address modes
+; X32: (%{{[^)]+}},%{{[^)]+}},
+define i32 @user(i32* %a, i32* %b, i32 %x) nounwind {
+entry:
+ br label %loop
+loop:
+ %iv = phi i32* [ %a, %entry ], [ %iv4, %loop ]
+ %s = phi i32 [ 0, %entry ], [ %s4, %loop ]
+ %v = load i32* %iv
+ %iv1 = getelementptr inbounds i32* %iv, i32 %x
+ %v1 = load i32* %iv1
+ %iv2 = getelementptr inbounds i32* %iv1, i32 %x
+ %v2 = load i32* %iv2
+ %iv3 = getelementptr inbounds i32* %iv2, i32 %x
+ %v3 = load i32* %iv3
+ %s1 = add i32 %s, %v
+ %s2 = add i32 %s1, %v1
+ %s3 = add i32 %s2, %v2
+ %s4 = add i32 %s3, %v3
+ %iv4 = getelementptr inbounds i32* %iv3, i32 %x
+ store i32 %s4, i32* %iv
+ %cmp = icmp eq i32* %iv4, %b
+ br i1 %cmp, label %exit, label %loop
+exit:
+ ret i32 %s4
+}
+
+; @extrastride is a slightly more interesting case of a single
+; complete chain with multiple strides. The test case IR is what LSR
+; used to do, and exactly what we don't want to do. LSR's new IV
+; chaining feature should now undo the damage.
+;
+; X64: extrastride:
+; We currently don't handle this on X64 because the sexts cause
+; strange increment expressions like this:
+; IV + ((sext i32 (2 * %s) to i64) + (-1 * (sext i32 %s to i64)))
+;
+; X32: extrastride:
+; no spills in the preheader
+; X32-NOT: mov{{.*}}(%esp){{$}}
+; X32: %for.body{{$}}
+; no complex address modes
+; X32-NOT: (%{{[^)]+}},%{{[^)]+}},
+; no reloads
+; X32-NOT: (%esp)
+define void @extrastride(i8* nocapture %main, i32 %main_stride, i32* nocapture %res, i32 %x, i32 %y, i32 %z) nounwind {
+entry:
+ %cmp8 = icmp eq i32 %z, 0
+ br i1 %cmp8, label %for.end, label %for.body.lr.ph
+
+for.body.lr.ph: ; preds = %entry
+ %add.ptr.sum = shl i32 %main_stride, 1 ; s*2
+ %add.ptr1.sum = add i32 %add.ptr.sum, %main_stride ; s*3
+ %add.ptr2.sum = add i32 %x, %main_stride ; s + x
+ %add.ptr4.sum = shl i32 %main_stride, 2 ; s*4
+ %add.ptr3.sum = add i32 %add.ptr2.sum, %add.ptr4.sum ; total IV stride = s*5+x
+ br label %for.body
+
+for.body: ; preds = %for.body.lr.ph, %for.body
+ %main.addr.011 = phi i8* [ %main, %for.body.lr.ph ], [ %add.ptr6, %for.body ]
+ %i.010 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+ %res.addr.09 = phi i32* [ %res, %for.body.lr.ph ], [ %add.ptr7, %for.body ]
+ %0 = bitcast i8* %main.addr.011 to i32*
+ %1 = load i32* %0, align 4
+ %add.ptr = getelementptr inbounds i8* %main.addr.011, i32 %main_stride
+ %2 = bitcast i8* %add.ptr to i32*
+ %3 = load i32* %2, align 4
+ %add.ptr1 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr.sum
+ %4 = bitcast i8* %add.ptr1 to i32*
+ %5 = load i32* %4, align 4
+ %add.ptr2 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr1.sum
+ %6 = bitcast i8* %add.ptr2 to i32*
+ %7 = load i32* %6, align 4
+ %add.ptr3 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr4.sum
+ %8 = bitcast i8* %add.ptr3 to i32*
+ %9 = load i32* %8, align 4
+ %add = add i32 %3, %1
+ %add4 = add i32 %add, %5
+ %add5 = add i32 %add4, %7
+ %add6 = add i32 %add5, %9
+ store i32 %add6, i32* %res.addr.09, align 4
+ %add.ptr6 = getelementptr inbounds i8* %main.addr.011, i32 %add.ptr3.sum
+ %add.ptr7 = getelementptr inbounds i32* %res.addr.09, i32 %y
+ %inc = add i32 %i.010, 1
+ %cmp = icmp eq i32 %inc, %z
+ br i1 %cmp, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
+
+; @foldedidx is an unrolled variant of this loop:
+; for (unsigned long i = 0; i < len; i += s) {
+; c[i] = a[i] + b[i];
+; }
+; where 's' can be folded into the addressing mode.
+; Consequently, we should *not* form any chains.
+;
+; X64: foldedidx:
+; X64: movzbl -3(
+;
+; X32: foldedidx:
+; X32: movzbl -3(
+define void @foldedidx(i8* nocapture %a, i8* nocapture %b, i8* nocapture %c) nounwind ssp {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %i.07 = phi i32 [ 0, %entry ], [ %inc.3, %for.body ]
+ %arrayidx = getelementptr inbounds i8* %a, i32 %i.07
+ %0 = load i8* %arrayidx, align 1
+ %conv5 = zext i8 %0 to i32
+ %arrayidx1 = getelementptr inbounds i8* %b, i32 %i.07
+ %1 = load i8* %arrayidx1, align 1
+ %conv26 = zext i8 %1 to i32
+ %add = add nsw i32 %conv26, %conv5
+ %conv3 = trunc i32 %add to i8
+ %arrayidx4 = getelementptr inbounds i8* %c, i32 %i.07
+ store i8 %conv3, i8* %arrayidx4, align 1
+ %inc1 = or i32 %i.07, 1
+ %arrayidx.1 = getelementptr inbounds i8* %a, i32 %inc1
+ %2 = load i8* %arrayidx.1, align 1
+ %conv5.1 = zext i8 %2 to i32
+ %arrayidx1.1 = getelementptr inbounds i8* %b, i32 %inc1
+ %3 = load i8* %arrayidx1.1, align 1
+ %conv26.1 = zext i8 %3 to i32
+ %add.1 = add nsw i32 %conv26.1, %conv5.1
+ %conv3.1 = trunc i32 %add.1 to i8
+ %arrayidx4.1 = getelementptr inbounds i8* %c, i32 %inc1
+ store i8 %conv3.1, i8* %arrayidx4.1, align 1
+ %inc.12 = or i32 %i.07, 2
+ %arrayidx.2 = getelementptr inbounds i8* %a, i32 %inc.12
+ %4 = load i8* %arrayidx.2, align 1
+ %conv5.2 = zext i8 %4 to i32
+ %arrayidx1.2 = getelementptr inbounds i8* %b, i32 %inc.12
+ %5 = load i8* %arrayidx1.2, align 1
+ %conv26.2 = zext i8 %5 to i32
+ %add.2 = add nsw i32 %conv26.2, %conv5.2
+ %conv3.2 = trunc i32 %add.2 to i8
+ %arrayidx4.2 = getelementptr inbounds i8* %c, i32 %inc.12
+ store i8 %conv3.2, i8* %arrayidx4.2, align 1
+ %inc.23 = or i32 %i.07, 3
+ %arrayidx.3 = getelementptr inbounds i8* %a, i32 %inc.23
+ %6 = load i8* %arrayidx.3, align 1
+ %conv5.3 = zext i8 %6 to i32
+ %arrayidx1.3 = getelementptr inbounds i8* %b, i32 %inc.23
+ %7 = load i8* %arrayidx1.3, align 1
+ %conv26.3 = zext i8 %7 to i32
+ %add.3 = add nsw i32 %conv26.3, %conv5.3
+ %conv3.3 = trunc i32 %add.3 to i8
+ %arrayidx4.3 = getelementptr inbounds i8* %c, i32 %inc.23
+ store i8 %conv3.3, i8* %arrayidx4.3, align 1
+ %inc.3 = add nsw i32 %i.07, 4
+ %exitcond.3 = icmp eq i32 %inc.3, 400
+ br i1 %exitcond.3, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; @multioper tests instructions with multiple IV user operands. We
+; should be able to chain them independent of each other.
+;
+; X64: @multioper
+; X64: %for.body
+; X64: movl %{{.*}},4)
+; X64-NEXT: leal 1(
+; X64-NEXT: movl %{{.*}},4)
+; X64-NEXT: leal 2(
+; X64-NEXT: movl %{{.*}},4)
+; X64-NEXT: leal 3(
+; X64-NEXT: movl %{{.*}},4)
+;
+; X32: @multioper
+; X32: %for.body
+; X32: movl %{{.*}},4)
+; X32-NEXT: leal 1(
+; X32-NEXT: movl %{{.*}},4)
+; X32-NEXT: leal 2(
+; X32-NEXT: movl %{{.*}},4)
+; X32-NEXT: leal 3(
+; X32-NEXT: movl %{{.*}},4)
+define void @multioper(i32* %a, i32 %n) nounwind {
+entry:
+ br label %for.body
+
+for.body:
+ %p = phi i32* [ %p.next, %for.body ], [ %a, %entry ]
+ %i = phi i32 [ %inc4, %for.body ], [ 0, %entry ]
+ store i32 %i, i32* %p, align 4
+ %inc1 = or i32 %i, 1
+ %add.ptr.i1 = getelementptr inbounds i32* %p, i32 1
+ store i32 %inc1, i32* %add.ptr.i1, align 4
+ %inc2 = add nsw i32 %i, 2
+ %add.ptr.i2 = getelementptr inbounds i32* %p, i32 2
+ store i32 %inc2, i32* %add.ptr.i2, align 4
+ %inc3 = add nsw i32 %i, 3
+ %add.ptr.i3 = getelementptr inbounds i32* %p, i32 3
+ store i32 %inc3, i32* %add.ptr.i3, align 4
+ %p.next = getelementptr inbounds i32* %p, i32 4
+ %inc4 = add nsw i32 %i, 4
+ %cmp = icmp slt i32 %inc4, %n
+ br i1 %cmp, label %for.body, label %exit
+
+exit:
+ ret void
+}
+
+; @testCmpZero has a ICmpZero LSR use that should not be hidden from
+; LSR. Profitable chains should have more than one nonzero increment
+; anyway.
+;
+; X32: @testCmpZero
+; X32: %for.body82.us
+; X32: dec
+; X32: jne
+define void @testCmpZero(i8* %src, i8* %dst, i32 %srcidx, i32 %dstidx, i32 %len) nounwind ssp {
+entry:
+ %dest0 = getelementptr inbounds i8* %src, i32 %srcidx
+ %source0 = getelementptr inbounds i8* %dst, i32 %dstidx
+ %add.ptr79.us.sum = add i32 %srcidx, %len
+ %lftr.limit = getelementptr i8* %src, i32 %add.ptr79.us.sum
+ br label %for.body82.us
+
+for.body82.us:
+ %dest = phi i8* [ %dest0, %entry ], [ %incdec.ptr91.us, %for.body82.us ]
+ %source = phi i8* [ %source0, %entry ], [ %add.ptr83.us, %for.body82.us ]
+ %0 = bitcast i8* %source to i32*
+ %1 = load i32* %0, align 4
+ %trunc = trunc i32 %1 to i8
+ %add.ptr83.us = getelementptr inbounds i8* %source, i32 4
+ %incdec.ptr91.us = getelementptr inbounds i8* %dest, i32 1
+ store i8 %trunc, i8* %dest, align 1
+ %exitcond = icmp eq i8* %incdec.ptr91.us, %lftr.limit
+ br i1 %exitcond, label %return, label %for.body82.us
+
+return:
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/X86/ivchain-stress-X86.ll b/test/Transforms/LoopStrengthReduce/X86/ivchain-stress-X86.ll
new file mode 100644
index 0000000..d8e0aa9
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/ivchain-stress-X86.ll
@@ -0,0 +1,96 @@
+; REQUIRES: asserts
+; RUN: llc < %s -O3 -march=x86-64 -mcpu=core2 -stress-ivchain | FileCheck %s -check-prefix=X64
+; RUN: llc < %s -O3 -march=x86 -mcpu=core2 -stress-ivchain | FileCheck %s -check-prefix=X32
+
+; @sharedidx is an unrolled variant of this loop:
+; for (unsigned long i = 0; i < len; i += s) {
+; c[i] = a[i] + b[i];
+; }
+; where 's' cannot be folded into the addressing mode.
+;
+; This is not quite profitable to chain. But with -stress-ivchain, we
+; can form three address chains in place of the shared induction
+; variable.
+
+; X64: sharedidx:
+; X64: %for.body.preheader
+; X64-NOT: leal ({{.*}},4)
+; X64: %for.body.1
+
+; X32: sharedidx:
+; X32: %for.body.2
+; X32: add
+; X32: add
+; X32: add
+; X32: add
+; X32: add
+; X32: %for.body.3
+define void @sharedidx(i8* nocapture %a, i8* nocapture %b, i8* nocapture %c, i32 %s, i32 %len) nounwind ssp {
+entry:
+ %cmp8 = icmp eq i32 %len, 0
+ br i1 %cmp8, label %for.end, label %for.body
+
+for.body: ; preds = %entry, %for.body.3
+ %i.09 = phi i32 [ %add5.3, %for.body.3 ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i8* %a, i32 %i.09
+ %0 = load i8* %arrayidx, align 1
+ %conv6 = zext i8 %0 to i32
+ %arrayidx1 = getelementptr inbounds i8* %b, i32 %i.09
+ %1 = load i8* %arrayidx1, align 1
+ %conv27 = zext i8 %1 to i32
+ %add = add nsw i32 %conv27, %conv6
+ %conv3 = trunc i32 %add to i8
+ %arrayidx4 = getelementptr inbounds i8* %c, i32 %i.09
+ store i8 %conv3, i8* %arrayidx4, align 1
+ %add5 = add i32 %i.09, %s
+ %cmp = icmp ult i32 %add5, %len
+ br i1 %cmp, label %for.body.1, label %for.end
+
+for.end: ; preds = %for.body, %for.body.1, %for.body.2, %for.body.3, %entry
+ ret void
+
+for.body.1: ; preds = %for.body
+ %arrayidx.1 = getelementptr inbounds i8* %a, i32 %add5
+ %2 = load i8* %arrayidx.1, align 1
+ %conv6.1 = zext i8 %2 to i32
+ %arrayidx1.1 = getelementptr inbounds i8* %b, i32 %add5
+ %3 = load i8* %arrayidx1.1, align 1
+ %conv27.1 = zext i8 %3 to i32
+ %add.1 = add nsw i32 %conv27.1, %conv6.1
+ %conv3.1 = trunc i32 %add.1 to i8
+ %arrayidx4.1 = getelementptr inbounds i8* %c, i32 %add5
+ store i8 %conv3.1, i8* %arrayidx4.1, align 1
+ %add5.1 = add i32 %add5, %s
+ %cmp.1 = icmp ult i32 %add5.1, %len
+ br i1 %cmp.1, label %for.body.2, label %for.end
+
+for.body.2: ; preds = %for.body.1
+ %arrayidx.2 = getelementptr inbounds i8* %a, i32 %add5.1
+ %4 = load i8* %arrayidx.2, align 1
+ %conv6.2 = zext i8 %4 to i32
+ %arrayidx1.2 = getelementptr inbounds i8* %b, i32 %add5.1
+ %5 = load i8* %arrayidx1.2, align 1
+ %conv27.2 = zext i8 %5 to i32
+ %add.2 = add nsw i32 %conv27.2, %conv6.2
+ %conv3.2 = trunc i32 %add.2 to i8
+ %arrayidx4.2 = getelementptr inbounds i8* %c, i32 %add5.1
+ store i8 %conv3.2, i8* %arrayidx4.2, align 1
+ %add5.2 = add i32 %add5.1, %s
+ %cmp.2 = icmp ult i32 %add5.2, %len
+ br i1 %cmp.2, label %for.body.3, label %for.end
+
+for.body.3: ; preds = %for.body.2
+ %arrayidx.3 = getelementptr inbounds i8* %a, i32 %add5.2
+ %6 = load i8* %arrayidx.3, align 1
+ %conv6.3 = zext i8 %6 to i32
+ %arrayidx1.3 = getelementptr inbounds i8* %b, i32 %add5.2
+ %7 = load i8* %arrayidx1.3, align 1
+ %conv27.3 = zext i8 %7 to i32
+ %add.3 = add nsw i32 %conv27.3, %conv6.3
+ %conv3.3 = trunc i32 %add.3 to i8
+ %arrayidx4.3 = getelementptr inbounds i8* %c, i32 %add5.2
+ store i8 %conv3.3, i8* %arrayidx4.3, align 1
+ %add5.3 = add i32 %add5.2, %s
+ %cmp.3 = icmp ult i32 %add5.3, %len
+ br i1 %cmp.3, label %for.body, label %for.end
+}
diff --git a/test/Transforms/LoopStrengthReduce/X86/lit.local.cfg b/test/Transforms/LoopStrengthReduce/X86/lit.local.cfg
new file mode 100644
index 0000000..da2db5a
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/lit.local.cfg
@@ -0,0 +1,6 @@
+config.suffixes = ['.ll']
+
+targets = set(config.root.targets_to_build.split())
+if not 'X86' in targets:
+ config.unsupported = True
+
diff --git a/test/Transforms/IndVarSimplify/addrec-gep.ll b/test/Transforms/LoopStrengthReduce/addrec-gep.ll
index b62d093..3e4e369 100644
--- a/test/Transforms/IndVarSimplify/addrec-gep.ll
+++ b/test/Transforms/LoopStrengthReduce/addrec-gep.ll
@@ -1,13 +1,17 @@
-; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
-; CHECK: getelementptr
-; CHECK: mul {{.*}}, 37
-; CHECK: add {{.*}}, 5203
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+; CHECK: bb1:
+; CHECK: load double* [[IV:%[^,]+]]
+; CHECK: store double {{.*}}, double* [[IV]]
+; CHECK: getelementptr double*
; CHECK-NOT: cast
+; CHECK: br {{.*}} label %bb1
; 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.
+; We only check that the inner loop (bb1-bb2) is "reduced" because LSR
+; currently only operates on inner loops.
target datalayout = "e-p:64:64:64-n32:64"
diff --git a/test/Transforms/LoopStrengthReduce/dg.exp b/test/Transforms/LoopStrengthReduce/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopStrengthReduce/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/LoopStrengthReduce/dominate-assert.ll b/test/Transforms/LoopStrengthReduce/dominate-assert.ll
new file mode 100644
index 0000000..b87bf62
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/dominate-assert.ll
@@ -0,0 +1,70 @@
+; RUN: opt -loop-reduce %s
+; we used to crash on this one
+
+declare i8* @_Znwm()
+declare i32 @__gxx_personality_v0(...)
+declare void @g()
+define void @f() {
+bb0:
+ br label %bb1
+bb1:
+ %v0 = phi i64 [ 0, %bb0 ], [ %v1, %bb1 ]
+ %v1 = add nsw i64 %v0, 1
+ br i1 undef, label %bb2, label %bb1
+bb2:
+ %v2 = icmp eq i64 %v0, 0
+ br i1 %v2, label %bb6, label %bb3
+bb3:
+ %v3 = invoke noalias i8* @_Znwm()
+ to label %bb5 unwind label %bb4
+bb4:
+ %v4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ br label %bb9
+bb5:
+ %v5 = bitcast i8* %v3 to i32**
+ %add.ptr.i = getelementptr inbounds i32** %v5, i64 %v0
+ br label %bb6
+bb6:
+ %v6 = phi i32** [ null, %bb2 ], [ %add.ptr.i, %bb5 ]
+ invoke void @g()
+ to label %bb7 unwind label %bb8
+bb7:
+ unreachable
+bb8:
+ %v7 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ br label %bb9
+bb9:
+ resume { i8*, i32 } zeroinitializer
+}
+
+
+define void @h() {
+bb1:
+ invoke void @g() optsize
+ to label %bb2 unwind label %bb5
+bb2:
+ %arrayctor.cur = phi i8* [ undef, %bb1 ], [ %arrayctor.next, %bb3 ]
+ invoke void @g() optsize
+ to label %bb3 unwind label %bb6
+bb3:
+ %arrayctor.next = getelementptr inbounds i8* %arrayctor.cur, i64 1
+ br label %bb2
+bb4:
+ ret void
+bb5:
+ %tmp = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ invoke void @g() optsize
+ to label %bb4 unwind label %bb7
+bb6:
+ %tmp1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ %arraydestroy.isempty = icmp eq i8* undef, %arrayctor.cur
+ ret void
+bb7:
+ %lpad.nonloopexit = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
+ ret void
+}
diff --git a/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll b/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll
index abbfda6..ad4959b 100644
--- a/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll
+++ b/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll
@@ -9,7 +9,7 @@ entry:
br label %no_exit
no_exit: ; preds = %no_exit, %entry
%indvar = phi i32 [ 0, %entry ], [ %indvar.next, %no_exit ] ; <i32> [#uses=1]
- volatile store float 0.000000e+00, float* %D
+ store volatile float 0.000000e+00, float* %D
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2]
; CHECK: icmp
; CHECK-NEXT: br i1
diff --git a/test/Transforms/LoopStrengthReduce/ivchain.ll b/test/Transforms/LoopStrengthReduce/ivchain.ll
new file mode 100644
index 0000000..ce7ad19
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/ivchain.ll
@@ -0,0 +1,43 @@
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+;
+; PR11782: bad cast to AddRecExpr.
+; A sign extend feeds an IVUser and cannot be hoisted into the AddRec.
+; CollectIVChains should bailout on this case.
+
+%struct = type { i8*, i8*, i16, i64, i16, i16, i16, i64, i64, i16, i8*, i64, i64, i64 }
+
+; CHECK: @test
+; CHECK: for.body:
+; CHECK: lsr.iv = phi %struct
+; CHECK: br
+define i32 @test(i8* %h, i32 %more) nounwind uwtable {
+entry:
+ br i1 undef, label %land.end238, label %return
+
+land.end238: ; preds = %if.end229
+ br label %for.body
+
+for.body: ; preds = %sw.epilog, %land.end238
+ %fbh.0 = phi %struct* [ undef, %land.end238 ], [ %incdec.ptr, %sw.epilog ]
+ %column_n.0 = phi i16 [ 0, %land.end238 ], [ %inc601, %sw.epilog ]
+ %conv250 = sext i16 %column_n.0 to i32
+ %add257 = add nsw i32 %conv250, 1
+ %conv258 = trunc i32 %add257 to i16
+ %cmp263 = icmp ult i16 undef, 2
+ br label %if.end388
+
+if.end388: ; preds = %if.then380, %if.else356
+ %ColLength = getelementptr inbounds %struct* %fbh.0, i64 0, i32 7
+ %call405 = call signext i16 @SQLColAttribute(i8* undef, i16 zeroext %conv258, i16 zeroext 1003, i8* null, i16 signext 0, i16* null, i64* %ColLength) nounwind
+ br label %sw.epilog
+
+sw.epilog: ; preds = %sw.bb542, %sw.bb523, %if.end475
+ %inc601 = add i16 %column_n.0, 1
+ %incdec.ptr = getelementptr inbounds %struct* %fbh.0, i64 1
+ br label %for.body
+
+return: ; preds = %entry
+ ret i32 1
+}
+
+declare signext i16 @SQLColAttribute(i8*, i16 zeroext, i16 zeroext, i8*, i16 signext, i16*, i64*)
diff --git a/test/Transforms/LoopStrengthReduce/lit.local.cfg b/test/Transforms/LoopStrengthReduce/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll b/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll
index 2760915..96904c6 100644
--- a/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll
+++ b/test/Transforms/LoopStrengthReduce/post-inc-icmpzero.ll
@@ -1,15 +1,15 @@
; RUN: opt -loop-reduce -S < %s | FileCheck %s
; PR9939
-; LSR should property handle the post-inc offset when folding the
+; LSR should properly handle the post-inc offset when folding the
; non-IV operand of an icmp into the IV.
-; 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: %4 = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
+; CHECK: %5 = lshr i64 %4, 1
+; CHECK: %6 = mul i64 %5, 2
; CHECK: br label %for.body
; CHECK: for.body:
-; CHECK: %lsr.iv2 = phi i64 [ %lsr.iv.next, %for.body ], [ %7, %for.body.lr.ph ]
+; CHECK: %lsr.iv2 = phi i64 [ %lsr.iv.next, %for.body ], [ %6, %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
diff --git a/test/Transforms/LoopStrengthReduce/pr12018.ll b/test/Transforms/LoopStrengthReduce/pr12018.ll
new file mode 100644
index 0000000..ee7b1e8
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/pr12018.ll
@@ -0,0 +1,38 @@
+; RUN: opt < %s -loop-reduce
+
+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-S128"
+
+%struct.nsTArray = type { i8 }
+%struct.nsTArrayHeader = type { i32 }
+
+define void @_Z6foobarR8nsTArray(%struct.nsTArray* %aValues, i32 %foo, %struct.nsTArrayHeader* %bar) nounwind {
+entry:
+ br label %for.body
+
+for.body: ; preds = %_ZN8nsTArray9ElementAtEi.exit, %entry
+ %i.06 = phi i32 [ %add, %_ZN8nsTArray9ElementAtEi.exit ], [ 0, %entry ]
+ %call.i = call %struct.nsTArrayHeader* @_ZN8nsTArray4Hdr2Ev() nounwind
+ %add.ptr.i = getelementptr inbounds %struct.nsTArrayHeader* %call.i, i32 1
+ %tmp = bitcast %struct.nsTArrayHeader* %add.ptr.i to %struct.nsTArray*
+ %arrayidx = getelementptr inbounds %struct.nsTArray* %tmp, i32 %i.06
+ %add = add nsw i32 %i.06, 1
+ call void @llvm.dbg.value(metadata !{%struct.nsTArray* %aValues}, i64 0, metadata !0) nounwind
+ br label %_ZN8nsTArray9ElementAtEi.exit
+
+_ZN8nsTArray9ElementAtEi.exit: ; preds = %for.body
+ %arrayidx.i = getelementptr inbounds %struct.nsTArray* %tmp, i32 %add
+ call void @_ZN11nsTArray15ComputeDistanceERKS_Rd(%struct.nsTArray* %arrayidx, %struct.nsTArray* %arrayidx.i) nounwind
+ %cmp = icmp slt i32 %add, %foo
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %_ZN8nsTArray9ElementAtEi.exit
+ ret void
+}
+
+declare void @_ZN11nsTArray15ComputeDistanceERKS_Rd(%struct.nsTArray*, %struct.nsTArray*)
+
+declare %struct.nsTArrayHeader* @_ZN8nsTArray4Hdr2Ev()
+
+declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
+
+!0 = metadata !{i32 786689} ; [ DW_TAG_arg_variable ]
diff --git a/test/Transforms/LoopStrengthReduce/pr12048.ll b/test/Transforms/LoopStrengthReduce/pr12048.ll
new file mode 100644
index 0000000..7e0f2ad
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/pr12048.ll
@@ -0,0 +1,38 @@
+; RUN: opt < %s -loop-reduce
+
+define void @resolve_name() nounwind uwtable ssp {
+ br label %while.cond40.preheader
+while.cond132.while.cond.loopexit_crit_edge:
+ br label %while.cond40.preheader
+while.cond40.preheader:
+ br label %while.cond40
+while.cond40:
+ %indvars.iv194 = phi i8* [ null, %while.cond40.preheader ], [ %scevgep, %while.body51 ]
+ %tmp.1 = phi i8* [ undef, %while.cond40.preheader ], [ %incdec.ptr, %while.body51 ]
+ switch i8 undef, label %while.body51 [
+ i8 0, label %if.then59
+ ]
+while.body51: ; preds = %land.end50
+ %incdec.ptr = getelementptr inbounds i8* %tmp.1, i64 1
+ %scevgep = getelementptr i8* %indvars.iv194, i64 1
+ br label %while.cond40
+if.then59: ; preds = %while.end
+ br i1 undef, label %if.then64, label %if.end113
+if.then64: ; preds = %if.then59
+ %incdec.ptr88.tmp.2 = select i1 undef, i8* undef, i8* undef
+ br label %if.end113
+if.end113: ; preds = %if.then64, %if.then59
+ %tmp.4 = phi i8* [ %incdec.ptr88.tmp.2, %if.then64 ], [ undef, %if.then59 ]
+ %tmp.4195 = ptrtoint i8* %tmp.4 to i64
+ br label %while.cond132.preheader
+while.cond132.preheader: ; preds = %if.end113
+ %cmp133173 = icmp eq i8* %tmp.1, %tmp.4
+ br i1 %cmp133173, label %while.cond40.preheader, label %while.body139.lr.ph
+while.body139.lr.ph: ; preds = %while.cond132.preheader
+ %scevgep198 = getelementptr i8* %indvars.iv194, i64 0
+ %scevgep198199 = ptrtoint i8* %scevgep198 to i64
+ br label %while.body139
+while.body139: ; preds = %while.body139, %while.body139.lr.ph
+ %start_of_var.0177 = phi i8* [ %tmp.1, %while.body139.lr.ph ], [ null, %while.body139 ]
+ br i1 undef, label %while.cond132.while.cond.loopexit_crit_edge, label %while.body139
+}
diff --git a/test/Transforms/LoopStrengthReduce/pr3399.ll b/test/Transforms/LoopStrengthReduce/pr3399.ll
index b809007..26c5002 100644
--- a/test/Transforms/LoopStrengthReduce/pr3399.ll
+++ b/test/Transforms/LoopStrengthReduce/pr3399.ll
@@ -13,7 +13,7 @@ bb: ; preds = %bb5, %bb5.thread
bb1: ; preds = %bb
%l_2.0.reg2mem.0 = sub i32 0, %indvar ; <i32> [#uses=1]
- %0 = volatile load i32* @g_53, align 4 ; <i32> [#uses=1]
+ %0 = load volatile i32* @g_53, align 4 ; <i32> [#uses=1]
%1 = trunc i32 %l_2.0.reg2mem.0 to i16 ; <i16> [#uses=1]
%2 = trunc i32 %0 to i16 ; <i16> [#uses=1]
%3 = mul i16 %2, %1 ; <i16> [#uses=1]
diff --git a/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll b/test/Transforms/LoopStrengthReduce/preserve-gep-loop-variant.ll
index 251d34e..f90d030 100644
--- a/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll
+++ b/test/Transforms/LoopStrengthReduce/preserve-gep-loop-variant.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -indvars -S -enable-iv-rewrite | FileCheck %s
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
; CHECK-NOT: {{inttoptr|ptrtoint}}
; CHECK: scevgep
; CHECK-NOT: {{inttoptr|ptrtoint}}
diff --git a/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll b/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll
index 59551d5..a43a4ff 100644
--- a/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll
+++ b/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S < %s -loop-unroll -unroll-count=4 -enable-iv-rewrite=false | FileCheck %s
+; RUN: opt -S < %s -loop-unroll -unroll-count=4 | FileCheck %s
;
; Test induction variable simplify after loop unrolling. It should
; expose nice opportunities for GVN.
diff --git a/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll b/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll
new file mode 100644
index 0000000..8946a23
--- /dev/null
+++ b/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -S -loop-unroll -simplifycfg | FileCheck %s
+; PR12513: Loop unrolling breaks with indirect branches.
+; If loop unrolling attempts to transform this loop, it replaces the
+; indirectbr successors. SimplifyCFG then considers them to be unreachable.
+declare void @subtract() nounwind uwtable
+
+; CHECK-NOT: unreachable
+define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable {
+entry:
+ %vals19 = alloca [5 x i32], align 16
+ %x20 = alloca i32, align 4
+ store i32 135, i32* %x20, align 4
+ br label %for.body
+
+for.body: ; preds = ; %call2_termjoin, %call3_termjoin
+ %indvars.iv = phi i64 [ 0, %entry ], [ %joinphi15.in.in, %call2_termjoin ]
+ %a6 = call coldcc i8* @funca(i8* blockaddress(@main, %for.body_code), i8*
+blockaddress(@main, %for.body_codeprime)) nounwind
+ indirectbr i8* %a6, [label %for.body_code, label %for.body_codeprime]
+
+for.body_code: ; preds = %for.body
+ call void @subtract()
+ br label %call2_termjoin
+
+call2_termjoin: ; preds = %for.body_codeprime, %for.body_code
+ %joinphi15.in.in = add i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %joinphi15.in.in, 5
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %call2_termjoin
+ ret i32 0
+
+for.body_codeprime: ; preds = %for.body
+ call void @subtract_v2(i64 %indvars.iv)
+ br label %call2_termjoin
+}
+
+declare coldcc i8* @funca(i8*, i8*) readonly
+
+declare void @subtract_v2(i64) nounwind uwtable
diff --git a/test/Transforms/LoopUnroll/dg.exp b/test/Transforms/LoopUnroll/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopUnroll/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/LoopUnroll/lit.local.cfg b/test/Transforms/LoopUnroll/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopUnroll/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LoopUnroll/partial-unroll-optsize.ll b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
new file mode 100644
index 0000000..3179d55e
--- /dev/null
+++ b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -S -loop-unroll -unroll-allow-partial | FileCheck %s
+; Loop size = 3, when the function has the optsize attribute, the
+; OptSizeUnrollThreshold, i.e. 50, is used, hence the loop should be unrolled
+; by 16 times because 3 * 16 < 50.
+define void @unroll_opt_for_size() nounwind optsize {
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %inc, %loop ]
+ %inc = add i32 %iv, 1
+ %exitcnd = icmp uge i32 %inc, 1024
+ br i1 %exitcnd, label %exit, label %loop
+
+exit:
+ ret void
+}
+
+; CHECK: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: icmp
diff --git a/test/Transforms/LoopUnroll/pr11361.ll b/test/Transforms/LoopUnroll/pr11361.ll
new file mode 100644
index 0000000..7ce7f5f
--- /dev/null
+++ b/test/Transforms/LoopUnroll/pr11361.ll
@@ -0,0 +1,42 @@
+; RUN: opt -loop-unroll -disable-output
+; PR11361
+
+; This tests for an iterator invalidation issue.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @func_1() nounwind uwtable {
+entry:
+ br label %for.cond8.preheader
+
+for.cond8.preheader: ; preds = %for.inc15, %entry
+ %l_1264.04 = phi i32 [ 0, %entry ], [ %add.i, %for.inc15 ]
+ %l_1330.0.03 = phi i80 [ undef, %entry ], [ %ins.lcssa, %for.inc15 ]
+ br label %for.body9
+
+for.body9: ; preds = %for.body9, %for.cond8.preheader
+ %l_1330.0.12 = phi i80 [ %l_1330.0.03, %for.cond8.preheader ], [ %ins, %for.body9 ]
+ %storemerge1 = phi i32 [ 7, %for.cond8.preheader ], [ %sub, %for.body9 ]
+ %tmp = lshr i80 %l_1330.0.12, 8
+ %tmp1 = trunc i80 %tmp to i8
+ %inc12 = add i8 %tmp1, 1
+ %tmp2 = zext i8 %inc12 to i80
+ %tmp3 = shl nuw nsw i80 %tmp2, 8
+ %mask = and i80 %l_1330.0.12, -65281
+ %ins = or i80 %tmp3, %mask
+ %sub = add nsw i32 %storemerge1, -1
+ %tobool = icmp eq i32 %sub, 0
+ br i1 %tobool, label %for.inc15, label %for.body9
+
+for.inc15: ; preds = %for.body9
+ %ins.lcssa = phi i80 [ %ins, %for.body9 ]
+ %sext = shl i32 %l_1264.04, 24
+ %conv.i = ashr exact i32 %sext, 24
+ %add.i = add nsw i32 %conv.i, 1
+ %cmp = icmp slt i32 %add.i, 3
+ br i1 %cmp, label %for.cond8.preheader, label %for.end16
+
+for.end16: ; preds = %for.inc15
+ ret void
+}
diff --git a/test/Transforms/LoopUnroll/runtime-loop.ll b/test/Transforms/LoopUnroll/runtime-loop.ll
new file mode 100644
index 0000000..d8bbea9
--- /dev/null
+++ b/test/Transforms/LoopUnroll/runtime-loop.ll
@@ -0,0 +1,109 @@
+; RUN: opt < %s -S -loop-unroll -unroll-runtime=true | FileCheck %s
+
+; Tests for unrolling loops with run-time trip counts
+
+; CHECK: unr.cmp{{.*}}:
+; CHECK: for.body.unr{{.*}}:
+; CHECK: for.body:
+; CHECK: br i1 %exitcond.7, label %for.end.loopexit{{.*}}, label %for.body
+
+define i32 @test(i32* nocapture %a, i32 %n) nounwind uwtable readonly {
+entry:
+ %cmp1 = icmp eq i32 %n, 0
+ br i1 %cmp1, label %for.end, label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
+ %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv
+ %0 = load i32* %arrayidx, align 4
+ %add = add nsw i32 %0, %sum.02
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, %n
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ ret i32 %sum.0.lcssa
+}
+
+
+; Still try to completely unroll loops with compile-time trip counts
+; even if the -unroll-runtime is specified
+
+; CHECK: for.body:
+; CHECK-NOT: for.body.unr:
+
+define i32 @test1(i32* nocapture %a) nounwind uwtable readonly {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %sum.01 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv
+ %0 = load i32* %arrayidx, align 4
+ %add = add nsw i32 %0, %sum.01
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, 5
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret i32 %add
+}
+
+; This is test 2007-05-09-UnknownTripCount.ll which can be unrolled now
+; if the -unroll-runtime option is turned on
+
+; CHECK: bb72.2:
+
+define void @foo(i32 %trips) {
+entry:
+ br label %cond_true.outer
+
+cond_true.outer:
+ %indvar1.ph = phi i32 [ 0, %entry ], [ %indvar.next2, %bb72 ]
+ br label %bb72
+
+bb72:
+ %indvar.next2 = add i32 %indvar1.ph, 1
+ %exitcond3 = icmp eq i32 %indvar.next2, %trips
+ br i1 %exitcond3, label %cond_true138, label %cond_true.outer
+
+cond_true138:
+ ret void
+}
+
+
+; Test run-time unrolling for a loop that counts down by -2.
+
+; CHECK: for.body.unr:
+; CHECK: br i1 %cmp.7, label %for.cond.for.end_crit_edge{{.*}}, label %for.body
+
+define zeroext i16 @down(i16* nocapture %p, i32 %len) nounwind uwtable readonly {
+entry:
+ %cmp2 = icmp eq i32 %len, 0
+ br i1 %cmp2, label %for.end, label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %p.addr.05 = phi i16* [ %incdec.ptr, %for.body ], [ %p, %entry ]
+ %len.addr.04 = phi i32 [ %sub, %for.body ], [ %len, %entry ]
+ %res.03 = phi i32 [ %add, %for.body ], [ 0, %entry ]
+ %incdec.ptr = getelementptr inbounds i16* %p.addr.05, i64 1
+ %0 = load i16* %p.addr.05, align 2
+ %conv = zext i16 %0 to i32
+ %add = add i32 %conv, %res.03
+ %sub = add nsw i32 %len.addr.04, -2
+ %cmp = icmp eq i32 %sub, 0
+ br i1 %cmp, label %for.cond.for.end_crit_edge, label %for.body
+
+for.cond.for.end_crit_edge: ; preds = %for.body
+ %phitmp = trunc i32 %add to i16
+ br label %for.end
+
+for.end: ; preds = %for.cond.for.end_crit_edge, %entry
+ %res.0.lcssa = phi i16 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]
+ ret i16 %res.0.lcssa
+}
diff --git a/test/Transforms/LoopUnroll/runtime-loop1.ll b/test/Transforms/LoopUnroll/runtime-loop1.ll
new file mode 100644
index 0000000..ad99b8c
--- /dev/null
+++ b/test/Transforms/LoopUnroll/runtime-loop1.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -S -loop-unroll -unroll-runtime -unroll-count=4 | FileCheck %s
+
+; This tests that setting the unroll count works
+
+; CHECK: unr.cmp:
+; CHECK: for.body.unr:
+; CHECK: for.body:
+; CHECK: br i1 %exitcond.3, label %for.end.loopexit{{.*}}, label %for.body
+; CHECK-NOT: br i1 %exitcond.4, label %for.end.loopexit{{.*}}, label %for.body
+
+define i32 @test(i32* nocapture %a, i32 %n) nounwind uwtable readonly {
+entry:
+ %cmp1 = icmp eq i32 %n, 0
+ br i1 %cmp1, label %for.end, label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
+ %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv
+ %0 = load i32* %arrayidx, align 4
+ %add = add nsw i32 %0, %sum.02
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, %n
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ ret i32 %sum.0.lcssa
+}
diff --git a/test/Transforms/LoopUnroll/runtime-loop2.ll b/test/Transforms/LoopUnroll/runtime-loop2.ll
new file mode 100644
index 0000000..cbc7af5
--- /dev/null
+++ b/test/Transforms/LoopUnroll/runtime-loop2.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -S -loop-unroll -unroll-threshold=50 -unroll-runtime -unroll-count=8 | FileCheck %s
+
+; Choose a smaller, power-of-two, unroll count if the loop is too large.
+; This test makes sure we're not unrolling 'odd' counts
+
+; CHECK: unr.cmp:
+; CHECK: for.body.unr:
+; CHECK: for.body:
+; CHECK: br i1 %exitcond.3, label %for.end.loopexit{{.*}}, label %for.body
+; CHECK-NOT: br i1 %exitcond.4, label %for.end.loopexit{{.*}}, label %for.body
+
+define i32 @test(i32* nocapture %a, i32 %n) nounwind uwtable readonly {
+entry:
+ %cmp1 = icmp eq i32 %n, 0
+ br i1 %cmp1, label %for.end, label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
+ %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv
+ %0 = load i32* %arrayidx, align 4
+ %add = add nsw i32 %0, %sum.02
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, %n
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body, %entry
+ %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ ret i32 %sum.0.lcssa
+}
diff --git a/test/Transforms/LoopUnroll/runtime-loop3.ll b/test/Transforms/LoopUnroll/runtime-loop3.ll
new file mode 100644
index 0000000..55cf223
--- /dev/null
+++ b/test/Transforms/LoopUnroll/runtime-loop3.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -disable-output -stats -loop-unroll -unroll-runtime -unroll-threshold=400 -info-output-file - | FileCheck %s --check-prefix=STATS
+
+; Test that nested loops can be unrolled. We need to increase threshold to do it
+
+; STATS: 2 loop-unroll - Number of loops unrolled (completely or otherwise)
+
+define i32 @nested(i32* nocapture %a, i32 %n, i32 %m) nounwind uwtable readonly {
+entry:
+ %cmp11 = icmp sgt i32 %n, 0
+ br i1 %cmp11, label %for.cond1.preheader.lr.ph, label %for.end7
+
+for.cond1.preheader.lr.ph: ; preds = %entry
+ %cmp28 = icmp sgt i32 %m, 0
+ br label %for.cond1.preheader
+
+for.cond1.preheader: ; preds = %for.inc5, %for.cond1.preheader.lr.ph
+ %indvars.iv16 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next17, %for.inc5 ]
+ %sum.012 = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %sum.1.lcssa, %for.inc5 ]
+ br i1 %cmp28, label %for.body3, label %for.inc5
+
+for.body3: ; preds = %for.cond1.preheader, %for.body3
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 0, %for.cond1.preheader ]
+ %sum.19 = phi i32 [ %add4, %for.body3 ], [ %sum.012, %for.cond1.preheader ]
+ %0 = add nsw i64 %indvars.iv, %indvars.iv16
+ %arrayidx = getelementptr inbounds i32* %a, i64 %0
+ %1 = load i32* %arrayidx, align 4
+ %add4 = add nsw i32 %1, %sum.19
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, %m
+ br i1 %exitcond, label %for.inc5, label %for.body3
+
+for.inc5: ; preds = %for.body3, %for.cond1.preheader
+ %sum.1.lcssa = phi i32 [ %sum.012, %for.cond1.preheader ], [ %add4, %for.body3 ]
+ %indvars.iv.next17 = add i64 %indvars.iv16, 1
+ %lftr.wideiv18 = trunc i64 %indvars.iv.next17 to i32
+ %exitcond19 = icmp eq i32 %lftr.wideiv18, %n
+ br i1 %exitcond19, label %for.end7, label %for.cond1.preheader
+
+for.end7: ; preds = %for.inc5, %entry
+ %sum.0.lcssa = phi i32 [ 0, %entry ], [ %sum.1.lcssa, %for.inc5 ]
+ ret i32 %sum.0.lcssa
+}
+
diff --git a/test/Transforms/LoopUnroll/unloop.ll b/test/Transforms/LoopUnroll/unloop.ll
index 217c8ce..5a9cacd 100644
--- a/test/Transforms/LoopUnroll/unloop.ll
+++ b/test/Transforms/LoopUnroll/unloop.ll
@@ -427,3 +427,44 @@ if.end2413: ; preds = %defchar
return: ; preds = %sw.bb304
ret void
}
+
+; PR11335: the most deeply nested block should be removed from the outer loop.
+; CHECK: @removeSubloopBlocks2
+; CHECK: for.cond3:
+; CHECK-NOT: br
+; CHECK: ret void
+define void @removeSubloopBlocks2() nounwind {
+entry:
+ %tobool.i = icmp ne i32 undef, 0
+ br label %lbl_616
+
+lbl_616.loopexit: ; preds = %for.cond
+ br label %lbl_616
+
+lbl_616: ; preds = %lbl_616.loopexit, %entry
+ br label %for.cond
+
+for.cond: ; preds = %for.cond3, %lbl_616
+ br i1 false, label %for.cond1.preheader, label %lbl_616.loopexit
+
+for.cond1.preheader: ; preds = %for.cond
+ br label %for.cond1
+
+for.cond1.loopexit: ; preds = %for.cond.i
+ br label %for.cond1
+
+for.cond1: ; preds = %for.cond1.loopexit, %for.cond1.preheader
+ br i1 false, label %for.body2, label %for.cond3
+
+for.body2: ; preds = %for.cond1
+ br label %for.cond.i
+
+for.cond.i: ; preds = %for.cond.i, %for.body2
+ br i1 %tobool.i, label %for.cond.i, label %for.cond1.loopexit
+
+for.cond3: ; preds = %for.cond1
+ br i1 false, label %for.cond, label %if.end
+
+if.end: ; preds = %for.cond3
+ ret void
+}
diff --git a/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll b/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll
new file mode 100644
index 0000000..8389fe4
--- /dev/null
+++ b/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll
@@ -0,0 +1,91 @@
+; RUN: opt -loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
+; RUN: opt -S -loop-unswitch -verify-loop-info -verify-dom-info %s | FileCheck %s
+
+; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted
+; STATS: 2 loop-unswitch - Number of switches unswitched
+
+; CHECK: %1 = icmp eq i32 %c, 1
+; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge
+
+; CHECK: ..split_crit_edge: ; preds = %0
+; CHECK-NEXT: br label %.split
+
+; CHECK: .split.us: ; preds = %0
+; CHECK-NEXT: br label %loop_begin.us
+
+; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us
+; CHECK-NEXT: %var_val.us = load i32* %var
+; CHECK-NEXT: switch i32 1, label %default.us-lcssa.us [
+; CHECK-NEXT: i32 1, label %inc.us
+
+; CHECK: inc.us: ; preds = %loop_begin.us
+; CHECK-NEXT: call void @incf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge.us
+
+; CHECK: .split: ; preds = %..split_crit_edge
+; CHECK-NEXT: %2 = icmp eq i32 %c, 2
+; CHECK-NEXT: br i1 %2, label %.split.split.us, label %.split..split.split_crit_edge
+
+; CHECK: .split..split.split_crit_edge: ; preds = %.split
+; CHECK-NEXT: br label %.split.split
+
+; CHECK: .split.split.us: ; preds = %.split
+; CHECK-NEXT: br label %loop_begin.us1
+
+; CHECK: loop_begin.us1: ; preds = %loop_begin.backedge.us5, %.split.split.us
+; CHECK-NEXT: %var_val.us2 = load i32* %var
+; CHECK-NEXT: switch i32 2, label %default.us-lcssa.us-lcssa.us [
+; CHECK-NEXT: i32 1, label %inc.us3
+; CHECK-NEXT: i32 2, label %dec.us4
+; CHECK-NEXT: ]
+
+; CHECK: dec.us4: ; preds = %loop_begin.us1
+; CHECK-NEXT: call void @decf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge.us5
+
+; CHECK: .split.split: ; preds = %.split..split.split_crit_edge
+; CHECK-NEXT: br label %loop_begin
+
+; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split.split
+; CHECK-NEXT: %var_val = load i32* %var
+; CHECK-NEXT: switch i32 %c, label %default.us-lcssa.us-lcssa [
+; CHECK-NEXT: i32 1, label %inc
+; CHECK-NEXT: i32 2, label %dec
+; CHECK-NEXT: ]
+
+; CHECK: inc: ; preds = %loop_begin
+; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc.split
+
+; CHECK: dec: ; preds = %loop_begin
+; CHECK-NEXT: br i1 true, label %us-unreachable6, label %dec.split
+
+define i32 @test(i32* %var) {
+ %mem = alloca i32
+ store i32 2, i32* %mem
+ %c = load i32* %mem
+
+ br label %loop_begin
+
+loop_begin:
+
+ %var_val = load i32* %var
+
+ switch i32 %c, label %default [
+ i32 1, label %inc
+ i32 2, label %dec
+ ]
+
+inc:
+ call void @incf() noreturn nounwind
+ br label %loop_begin
+dec:
+ call void @decf() noreturn nounwind
+ br label %loop_begin
+default:
+ br label %loop_exit
+loop_exit:
+ ret i32 0
+}
+
+declare void @incf() noreturn
+declare void @decf() noreturn
diff --git a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll
new file mode 100644
index 0000000..05d98d5
--- /dev/null
+++ b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll
@@ -0,0 +1,84 @@
+; RUN: opt -loop-unswitch -loop-unswitch-threshold 13 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
+; RUN: opt -S -loop-unswitch -loop-unswitch-threshold 13 -verify-loop-info -verify-dom-info %s | FileCheck %s
+
+; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted
+; STATS: 1 loop-unswitch - Number of switches unswitched
+
+; ModuleID = '../llvm/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll'
+
+; CHECK: %1 = icmp eq i32 %c, 1
+; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge
+
+; CHECK: ..split_crit_edge: ; preds = %0
+; CHECK-NEXT: br label %.split
+
+; CHECK: .split.us: ; preds = %0
+; CHECK-NEXT: br label %loop_begin.us
+
+; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us
+; CHECK: switch i32 1, label %second_switch.us [
+; CHECK-NEXT: i32 1, label %inc.us
+
+; CHECK: inc.us: ; preds = %second_switch.us, %loop_begin.us
+; CHECK-NEXT: call void @incf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge.us
+
+; CHECK: second_switch.us: ; preds = %loop_begin.us
+; CHECK-NEXT: switch i32 %d, label %default.us [
+; CHECK-NEXT: i32 1, label %inc.us
+; CHECK-NEXT: ]
+
+; CHECK: .split: ; preds = %..split_crit_edge
+; CHECK-NEXT: br label %loop_begin
+
+; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split
+; CHECK: switch i32 %c, label %second_switch [
+; CHECK-NEXT: i32 1, label %loop_begin.inc_crit_edge
+; CHECK-NEXT: ]
+
+; CHECK: loop_begin.inc_crit_edge: ; preds = %loop_begin
+; CHECK-NEXT: br i1 true, label %us-unreachable, label %inc
+
+; CHECK: second_switch: ; preds = %loop_begin
+; CHECK-NEXT: switch i32 %d, label %default [
+; CHECK-NEXT: i32 1, label %inc
+; CHECK-NEXT: ]
+
+; CHECK: inc: ; preds = %loop_begin.inc_crit_edge, %second_switch
+; CHECK-NEXT: call void @incf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge
+
+define i32 @test(i32* %var) {
+ %mem = alloca i32
+ store i32 2, i32* %mem
+ %c = load i32* %mem
+ %d = load i32* %mem
+
+ br label %loop_begin
+
+loop_begin:
+
+ %var_val = load i32* %var
+
+ switch i32 %c, label %second_switch [
+ i32 1, label %inc
+ ]
+
+second_switch:
+ switch i32 %d, label %default [
+ i32 1, label %inc
+ ]
+
+inc:
+ call void @incf() noreturn nounwind
+ br label %loop_begin
+
+default:
+ br label %loop_begin
+
+loop_exit:
+ ret i32 0
+}
+
+declare void @incf() noreturn
+declare void @decf() noreturn
diff --git a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll
new file mode 100644
index 0000000..1b186d6
--- /dev/null
+++ b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll
@@ -0,0 +1,138 @@
+; RUN: opt -loop-unswitch -loop-unswitch-threshold 1000 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
+; RUN: opt -S -loop-unswitch -loop-unswitch-threshold 1000 -verify-loop-info -verify-dom-info %s | FileCheck %s
+
+; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted
+; STATS: 3 loop-unswitch - Number of switches unswitched
+
+; CHECK: %1 = icmp eq i32 %c, 1
+; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge
+
+; CHECK: ..split_crit_edge: ; preds = %0
+; CHECK-NEXT: br label %.split
+
+; CHECK: .split.us: ; preds = %0
+; CHECK-NEXT: %2 = icmp eq i32 %d, 1
+; CHECK-NEXT: br i1 %2, label %.split.us.split.us, label %.split.us..split.us.split_crit_edge
+
+; CHECK: .split.us..split.us.split_crit_edge: ; preds = %.split.us
+; CHECK-NEXT: br label %.split.us.split
+
+; CHECK: .split.us.split.us: ; preds = %.split.us
+; CHECK-NEXT: br label %loop_begin.us.us
+
+; CHECK: loop_begin.us.us: ; preds = %loop_begin.backedge.us.us, %.split.us.split.us
+; CHECK-NEXT: %var_val.us.us = load i32* %var
+; CHECK-NEXT: switch i32 1, label %second_switch.us.us [
+; CHECK-NEXT: i32 1, label %inc.us.us
+
+; CHECK: inc.us.us: ; preds = %second_switch.us.us, %loop_begin.us.us
+; CHECK-NEXT: call void @incf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge.us.us
+
+; CHECK: second_switch.us.us: ; preds = %loop_begin.us.us
+; CHECK-NEXT: switch i32 1, label %default.us.us [
+; CHECK-NEXT: i32 1, label %inc.us.us
+
+; CHECK: .split.us.split: ; preds = %.split.us..split.us.split_crit_edge
+; CHECK-NEXT: br label %loop_begin.us
+
+; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us.split
+; CHECK-NEXT: %var_val.us = load i32* %var
+; CHECK-NEXT: switch i32 1, label %second_switch.us [
+; CHECK-NEXT: i32 1, label %inc.us
+
+; CHECK: inc.us: ; preds = %second_switch.us.inc.us_crit_edge, %loop_begin.us
+; CHECK-NEXT: call void @incf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge.us
+
+; CHECK: second_switch.us: ; preds = %loop_begin.us
+; CHECK-NEXT: switch i32 %d, label %default.us [
+; CHECK-NEXT: i32 1, label %second_switch.us.inc.us_crit_edge
+; CHECK-NEXT: ]
+
+; CHECK: second_switch.us.inc.us_crit_edge: ; preds = %second_switch.us
+; CHECK-NEXT: br i1 true, label %us-unreachable8, label %inc.us
+
+; CHECK: .split: ; preds = %..split_crit_edge
+; CHECK-NEXT: %3 = icmp eq i32 %d, 1
+; CHECK-NEXT: br i1 %3, label %.split.split.us, label %.split..split.split_crit_edge
+
+; CHECK: .split..split.split_crit_edge: ; preds = %.split
+; CHECK-NEXT: br label %.split.split
+
+; CHECK: .split.split.us: ; preds = %.split
+; CHECK-NEXT: br label %loop_begin.us1
+
+; CHECK: loop_begin.us1: ; preds = %loop_begin.backedge.us6, %.split.split.us
+; CHECK-NEXT: %var_val.us2 = load i32* %var
+; CHECK-NEXT: switch i32 %c, label %second_switch.us4 [
+; CHECK-NEXT: i32 1, label %loop_begin.inc_crit_edge.us
+; CHECK-NEXT: ]
+
+; CHECK: inc.us3: ; preds = %loop_begin.inc_crit_edge.us, %second_switch.us4
+; CHECK-NEXT: call void @incf() noreturn nounwind
+; CHECK-NEXT: br label %loop_begin.backedge.us6
+
+; CHECK: second_switch.us4: ; preds = %loop_begin.us1
+; CHECK-NEXT: switch i32 1, label %default.us5 [
+; CHECK-NEXT: i32 1, label %inc.us3
+; CHECK-NEXT: ]
+
+; CHECK: loop_begin.inc_crit_edge.us: ; preds = %loop_begin.us1
+; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa.us, label %inc.us3
+
+; CHECK: .split.split: ; preds = %.split..split.split_crit_edge
+; CHECK-NEXT: br label %loop_begin
+
+; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split.split
+; CHECK-NEXT: %var_val = load i32* %var
+; CHECK-NEXT: switch i32 %c, label %second_switch [
+; CHECK-NEXT: i32 1, label %loop_begin.inc_crit_edge
+; CHECK-NEXT: ]
+
+; CHECK: loop_begin.inc_crit_edge: ; preds = %loop_begin
+; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc
+
+; CHECK: second_switch: ; preds = %loop_begin
+; CHECK-NEXT: switch i32 %d, label %default [
+; CHECK-NEXT: i32 1, label %second_switch.inc_crit_edge
+; CHECK-NEXT: ]
+
+; CHECK: second_switch.inc_crit_edge: ; preds = %second_switch
+; CHECK-NEXT: br i1 true, label %us-unreachable7, label %inc
+
+
+define i32 @test(i32* %var) {
+ %mem = alloca i32
+ store i32 2, i32* %mem
+ %c = load i32* %mem
+ %d = load i32* %mem
+
+ br label %loop_begin
+
+loop_begin:
+
+ %var_val = load i32* %var
+
+ switch i32 %c, label %second_switch [
+ i32 1, label %inc
+ ]
+
+second_switch:
+ switch i32 %d, label %default [
+ i32 1, label %inc
+ ]
+
+inc:
+ call void @incf() noreturn nounwind
+ br label %loop_begin
+
+default:
+ br label %loop_begin
+
+loop_exit:
+ ret i32 0
+}
+
+declare void @incf() noreturn
+declare void @decf() noreturn
diff --git a/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll b/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll
new file mode 100644
index 0000000..c92f0a2
--- /dev/null
+++ b/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -S -loop-unswitch -verify-loop-info -verify-dom-info | FileCheck %s
+; PR12343: -loop-unswitch crash on indirect branch
+
+; CHECK: %0 = icmp eq i64 undef, 0
+; CHECK-NEXT: br i1 %0, label %"5", label %"4"
+
+; CHECK: "5": ; preds = %entry
+; CHECK-NEXT: br label %"16"
+
+; CHECK: "16": ; preds = %"22", %"5"
+; CHECK-NEXT: indirectbr i8* undef, [label %"22", label %"33"]
+
+; CHECK: "22": ; preds = %"16"
+; CHECK-NEXT: br i1 %0, label %"16", label %"26"
+
+; CHECK: "26": ; preds = %"22"
+; CHECK-NEXT: unreachable
+
+define void @foo() {
+entry:
+ %0 = icmp eq i64 undef, 0
+ br i1 %0, label %"5", label %"4"
+
+"4": ; preds = %entry
+ unreachable
+
+"5": ; preds = %entry
+ br label %"16"
+
+"16": ; preds = %"22", %"5"
+ indirectbr i8* undef, [label %"22", label %"33"]
+
+"22": ; preds = %"16"
+ br i1 %0, label %"16", label %"26"
+
+"26": ; preds = %"22"
+ unreachable
+
+"33": ; preds = %"16"
+ unreachable
+}
diff --git a/test/Transforms/LoopUnswitch/dg.exp b/test/Transforms/LoopUnswitch/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LoopUnswitch/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/LoopUnswitch/lit.local.cfg b/test/Transforms/LoopUnswitch/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LoopUnswitch/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LowerAtomic/dg.exp b/test/Transforms/LowerAtomic/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LowerAtomic/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/LowerAtomic/lit.local.cfg b/test/Transforms/LowerAtomic/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LowerAtomic/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LowerExpectIntrinsic/dg.exp b/test/Transforms/LowerExpectIntrinsic/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LowerExpectIntrinsic/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/LowerExpectIntrinsic/lit.local.cfg b/test/Transforms/LowerExpectIntrinsic/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/Transforms/LowerExpectIntrinsic/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/test/Transforms/LowerInvoke/dg.exp b/test/Transforms/LowerInvoke/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LowerInvoke/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/LowerInvoke/lit.local.cfg b/test/Transforms/LowerInvoke/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LowerInvoke/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/LowerSwitch/dg.exp b/test/Transforms/LowerSwitch/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/LowerSwitch/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/LowerSwitch/lit.local.cfg b/test/Transforms/LowerSwitch/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/LowerSwitch/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll b/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
index 52a8375..ea0d515 100644
--- a/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
+++ b/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll
@@ -1,6 +1,6 @@
; RUN: opt < %s -std-compile-opts -S | grep volatile | count 3
; PR1520
-; Don't promote volatile loads/stores. This is really needed to handle setjmp/lonjmp properly.
+; Don't promote load volatiles/stores. This is really needed to handle setjmp/lonjmp properly.
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:32:32"
target triple = "i686-pc-linux-gnu"
@@ -14,7 +14,7 @@ entry:
%v = alloca i32, align 4 ; <i32*> [#uses=3]
%tmp = alloca i32, align 4 ; <i32*> [#uses=3]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- volatile store i32 0, i32* %v, align 4
+ store volatile i32 0, i32* %v, align 4
%tmp1 = call i32 @_setjmp( %struct.__jmp_buf_tag* getelementptr ([1 x %struct.__jmp_buf_tag]* @j, i32 0, i32 0) ) ; <i32> [#uses=1]
%tmp2 = icmp ne i32 %tmp1, 0 ; <i1> [#uses=1]
%tmp23 = zext i1 %tmp2 to i8 ; <i8> [#uses=1]
@@ -22,12 +22,12 @@ entry:
br i1 %toBool, label %bb, label %bb5
bb: ; preds = %entry
- %tmp4 = volatile load i32* %v, align 4 ; <i32> [#uses=1]
+ %tmp4 = load volatile i32* %v, align 4 ; <i32> [#uses=1]
store i32 %tmp4, i32* %tmp, align 4
br label %bb6
bb5: ; preds = %entry
- volatile store i32 1, i32* %v, align 4
+ store volatile i32 1, i32* %v, align 4
call void @g( )
store i32 0, i32* %tmp, align 4
br label %bb6
diff --git a/test/Transforms/Mem2Reg/dg.exp b/test/Transforms/Mem2Reg/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/Mem2Reg/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/Mem2Reg/lit.local.cfg b/test/Transforms/Mem2Reg/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/Mem2Reg/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/MemCpyOpt/dg.exp b/test/Transforms/MemCpyOpt/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/MemCpyOpt/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/MemCpyOpt/form-memset.ll b/test/Transforms/MemCpyOpt/form-memset.ll
index 1ac97e9..8832f89 100644
--- a/test/Transforms/MemCpyOpt/form-memset.ll
+++ b/test/Transforms/MemCpyOpt/form-memset.ll
@@ -57,8 +57,8 @@ entry:
declare i32 @bar(...)
+%struct.MV = type { i16, i16 }
- %struct.MV = type { i16, i16 }
define void @test2() nounwind {
entry:
@@ -220,3 +220,31 @@ entry:
; CHECK: call void @llvm.memset.p0i8.i64(i8* %2, i8 0, i64 24, i32 1, i1 false)
}
+; More aggressive heuristic
+; rdar://9892684
+define void @test7(i32* nocapture %c) nounwind optsize {
+ store i32 -1, i32* %c, align 4
+ %1 = getelementptr inbounds i32* %c, i32 1
+ store i32 -1, i32* %1, align 4
+ %2 = getelementptr inbounds i32* %c, i32 2
+ store i32 -1, i32* %2, align 4
+ %3 = getelementptr inbounds i32* %c, i32 3
+ store i32 -1, i32* %3, align 4
+ %4 = getelementptr inbounds i32* %c, i32 4
+ store i32 -1, i32* %4, align 4
+; CHECK: @test7
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %5, i8 -1, i64 20, i32 4, i1 false)
+ ret void
+}
+
+%struct.test8 = type { [4 x i32] }
+
+define void @test8() {
+entry:
+ %memtmp = alloca %struct.test8, align 16
+ %0 = bitcast %struct.test8* %memtmp to <4 x i32>*
+ store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32>* %0, align 16
+ ret void
+; CHECK: @test8
+; CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32>* %0, align 16
+}
diff --git a/test/Transforms/MemCpyOpt/lit.local.cfg b/test/Transforms/MemCpyOpt/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/MemCpyOpt/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/MemCpyOpt/memcpy.ll b/test/Transforms/MemCpyOpt/memcpy.ll
index 71d4d4e..63d0ebf 100644
--- a/test/Transforms/MemCpyOpt/memcpy.ll
+++ b/test/Transforms/MemCpyOpt/memcpy.ll
@@ -59,7 +59,7 @@ define void @test3(%0* noalias sret %agg.result) nounwind {
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %agg.result2, i8* %x.01, i32 32, i32 16, i1 false)
ret void
; CHECK: @test3
-; CHECK-NEXT: %agg.result2 = bitcast
+; CHECK-NEXT: %agg.result1 = bitcast
; CHECK-NEXT: call void @llvm.memcpy
; CHECK-NEXT: ret void
}
@@ -130,3 +130,21 @@ declare i32 @g(%struct.p* byval align 8)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
+; PR11142 - When looking for a memcpy-memcpy dependency, don't get stuck on
+; instructions between the memcpy's that only affect the destination pointer.
+@test8.str = internal constant [7 x i8] c"ABCDEF\00"
+
+define void @test8() {
+; CHECK: test8
+; CHECK-NOT: memcpy
+ %A = tail call i8* @malloc(i32 10)
+ %B = getelementptr inbounds i8* %A, i64 2
+ tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %B, i8* getelementptr inbounds ([7 x i8]* @test8.str, i64 0, i64 0), i32 7, i32 1, i1 false)
+ %C = tail call i8* @malloc(i32 10)
+ %D = getelementptr inbounds i8* %C, i64 2
+ tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %D, i8* %B, i32 7, i32 1, i1 false)
+ ret void
+; CHECK: ret void
+}
+
+declare noalias i8* @malloc(i32)
diff --git a/test/Transforms/MergeFunc/2011-02-08-RemoveEqual.ll b/test/Transforms/MergeFunc/2011-02-08-RemoveEqual.ll
index 201903e..e3e52b4 100644
--- a/test/Transforms/MergeFunc/2011-02-08-RemoveEqual.ll
+++ b/test/Transforms/MergeFunc/2011-02-08-RemoveEqual.ll
@@ -75,10 +75,12 @@ bb2: ; preds = %bb1, %invcont
ret void
lpad: ; preds = %bb
- %eh_ptr = call i8* @llvm.eh.exception()
- store i8* %eh_ptr, i8** %eh_exception
+ %eh_ptr = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ %exn = extractvalue { i8*, i32 } %eh_ptr, 0
+ store i8* %exn, i8** %eh_exception
%eh_ptr4 = load i8** %eh_exception
- %eh_select5 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %eh_ptr4, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0)
+ %eh_select5 = extractvalue { i8*, i32 } %eh_ptr, 1
store i32 %eh_select5, i32* %eh_selector
%eh_select = load i32* %eh_selector
store i32 %eh_select, i32* %save_filt.150, align 4
@@ -199,10 +201,12 @@ bb2: ; preds = %bb1, %invcont
ret void
lpad: ; preds = %bb
- %eh_ptr = call i8* @llvm.eh.exception()
- store i8* %eh_ptr, i8** %eh_exception
+ %eh_ptr = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ %exn = extractvalue { i8*, i32 } %eh_ptr, 0
+ store i8* %exn, i8** %eh_exception
%eh_ptr4 = load i8** %eh_exception
- %eh_select5 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %eh_ptr4, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0)
+ %eh_select5 = extractvalue { i8*, i32 } %eh_ptr, 1
store i32 %eh_select5, i32* %eh_selector
%eh_select = load i32* %eh_selector
store i32 %eh_select, i32* %save_filt.148, align 4
@@ -220,10 +224,6 @@ lpad: ; preds = %bb
unreachable
}
-declare i8* @llvm.eh.exception() nounwind readonly
-
-declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
-
declare i32 @__gxx_personality_v0(...)
declare void @_Unwind_Resume_or_Rethrow()
diff --git a/test/Transforms/MergeFunc/dg.exp b/test/Transforms/MergeFunc/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/MergeFunc/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/MergeFunc/lit.local.cfg b/test/Transforms/MergeFunc/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/MergeFunc/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/ObjCARC/apelim.ll b/test/Transforms/ObjCARC/apelim.ll
new file mode 100644
index 0000000..8c7b5b1
--- /dev/null
+++ b/test/Transforms/ObjCARC/apelim.ll
@@ -0,0 +1,53 @@
+; RUN: opt -S -objc-arc-apelim < %s | FileCheck %s
+; rdar://10227311
+
+@llvm.global_ctors = appending global [2 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_x }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_y }]
+
+@x = global i32 0
+
+declare i32 @bar() nounwind
+
+define i32 @foo() nounwind {
+entry:
+ ret i32 5
+}
+
+define internal void @__cxx_global_var_init() {
+entry:
+ %call = call i32 @foo()
+ store i32 %call, i32* @x, align 4
+ ret void
+}
+
+define internal void @__dxx_global_var_init() {
+entry:
+ %call = call i32 @bar()
+ store i32 %call, i32* @x, align 4
+ ret void
+}
+
+; CHECK: define internal void @_GLOBAL__I_x()
+; CHECK-NOT: @objc
+; CHECK: }
+define internal void @_GLOBAL__I_x() {
+entry:
+ %0 = call i8* @objc_autoreleasePoolPush() nounwind
+ call void @__cxx_global_var_init()
+ call void @objc_autoreleasePoolPop(i8* %0) nounwind
+ ret void
+}
+
+; CHECK: define internal void @_GLOBAL__I_y()
+; CHECK: %0 = call i8* @objc_autoreleasePoolPush() nounwind
+; CHECK: call void @objc_autoreleasePoolPop(i8* %0) nounwind
+; CHECK: }
+define internal void @_GLOBAL__I_y() {
+entry:
+ %0 = call i8* @objc_autoreleasePoolPush() nounwind
+ call void @__dxx_global_var_init()
+ call void @objc_autoreleasePoolPop(i8* %0) nounwind
+ ret void
+}
+
+declare i8* @objc_autoreleasePoolPush()
+declare void @objc_autoreleasePoolPop(i8*)
diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll
index 575cf42..ba2f778 100644
--- a/test/Transforms/ObjCARC/basic.ll
+++ b/test/Transforms/ObjCARC/basic.ll
@@ -3,10 +3,12 @@
target datalayout = "e-p:64:64:64"
declare i8* @objc_retain(i8*)
+declare i8* @objc_retainAutoreleasedReturnValue(i8*)
declare void @objc_release(i8*)
declare i8* @objc_autorelease(i8*)
+declare i8* @objc_autoreleaseReturnValue(i8*)
declare void @objc_autoreleasePoolPop(i8*)
-declare void @objc_autoreleasePoolPush()
+declare i8* @objc_autoreleasePoolPush()
declare i8* @objc_retainBlock(i8*)
declare i8* @objc_retainedObject(i8*)
@@ -86,6 +88,37 @@ alt_return:
ret void
}
+; Don't do partial elimination into two different CFG diamonds.
+
+; CHECK: define void @test1b(
+; CHECK: entry:
+; CHECK: tail call i8* @objc_retain(i8* %x) nounwind
+; CHECK-NOT: @objc_
+; CHECK: if.end5:
+; CHECK: tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test1b(i8* %x, i1 %p, i1 %q) {
+entry:
+ tail call i8* @objc_retain(i8* %x) nounwind
+ br i1 %p, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ tail call void @callee()
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ br i1 %q, label %if.then3, label %if.end5
+
+if.then3: ; preds = %if.end
+ tail call void @use_pointer(i8* %x)
+ br label %if.end5
+
+if.end5: ; preds = %if.then3, %if.end
+ tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
; Like test0 but the pointer is passed to an intervening call,
; so the optimization is not safe.
@@ -136,7 +169,7 @@ entry:
loop:
%c = bitcast i32* %x to i8*
call void @objc_release(i8* %c) nounwind
- %j = volatile load i1* %q
+ %j = load volatile i1* %q
br i1 %j, label %loop, label %return
return:
@@ -159,7 +192,7 @@ entry:
loop:
%a = bitcast i32* %x to i8*
%0 = call i8* @objc_retain(i8* %a) nounwind
- %j = volatile load i1* %q
+ %j = load volatile i1* %q
br i1 %j, label %loop, label %return
return:
@@ -495,7 +528,7 @@ entry:
define void @test13d(i8* %x, i64 %n) {
entry:
call i8* @objc_retain(i8* %x) nounwind
- call void @objc_autoreleasePoolPush()
+ call i8* @objc_autoreleasePoolPush()
call i8* @objc_retain(i8* %x) nounwind
call void @use_pointer(i8* %x)
call void @use_pointer(i8* %x)
@@ -755,7 +788,7 @@ C:
@__block_holder_tmp_1 = external constant %block1
define void @test23() {
entry:
- %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
+ %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind, !clang.arc.copy_on_escape !0
call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
@@ -770,13 +803,28 @@ entry:
; CHECK: }
define void @test23b(i8* %p) {
entry:
- %0 = call i8* @objc_retainBlock(i8* %p) nounwind
+ %0 = call i8* @objc_retainBlock(i8* %p) nounwind, !clang.arc.copy_on_escape !0
call void @callee()
call void @use_pointer(i8* %p)
call void @objc_release(i8* %p) nounwind
ret void
}
+; Don't optimize objc_retainBlock, because there's no copy_on_escape metadata.
+
+; CHECK: define void @test23c(
+; CHECK: @objc_retainBlock
+; CHECK: @objc_release
+; CHECK: }
+define void @test23c() {
+entry:
+ %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
+ call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
+ call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
+ call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
+ ret void
+}
+
; Any call can decrement a retain count.
; CHECK: define void @test24(
@@ -1354,7 +1402,7 @@ entry:
; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
; CHECK-NEXT: call void @use_pointer(i8* %p)
; CHECK-NEXT: call void @use_pointer(i8* %p)
-; CHECK-NEXT: call void @objc_autoreleasePoolPush()
+; CHECK-NEXT: call i8* @objc_autoreleasePoolPush()
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @test43b(i8* %p) {
@@ -1364,7 +1412,7 @@ entry:
call i8* @objc_retain(i8* %p)
call void @use_pointer(i8* %p)
call void @use_pointer(i8* %p)
- call void @objc_autoreleasePoolPush()
+ call i8* @objc_autoreleasePoolPush()
call void @objc_release(i8* %p)
ret void
}
@@ -1497,9 +1545,11 @@ define void @test52(i8** %zz, i8** %pp) {
; Like test52, but the pointer has function type, so it's assumed to
; be not reference counted.
+; Oops. That's wrong. Clang sometimes uses function types gratuitously.
+; See rdar://10551239.
; CHECK: define void @test53(
-; CHECK-NOT: @objc_
+; CHECK: @objc_
; CHECK: }
define void @test53(void ()** %zz, i8** %pp) {
%p = load i8** %pp
@@ -1673,6 +1723,154 @@ define void @test61() {
ret void
}
+; Delete a retain matched by releases when one is inside the loop and the
+; other is outside the loop.
+
+; CHECK: define void @test62(
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test62(i8* %x, i1* %p) nounwind {
+entry:
+ br label %loop
+
+loop:
+ call i8* @objc_retain(i8* %x)
+ %q = load i1* %p
+ br i1 %q, label %loop.more, label %exit
+
+loop.more:
+ call void @objc_release(i8* %x)
+ br label %loop
+
+exit:
+ call void @objc_release(i8* %x)
+ ret void
+}
+
+; Like test62 but with no release in exit.
+; Don't delete anything!
+
+; CHECK: define void @test63(
+; CHECK: loop:
+; CHECK: tail call i8* @objc_retain(i8* %x)
+; CHECK: loop.more:
+; CHECK: call void @objc_release(i8* %x)
+; CHECK: }
+define void @test63(i8* %x, i1* %p) nounwind {
+entry:
+ br label %loop
+
+loop:
+ call i8* @objc_retain(i8* %x)
+ %q = load i1* %p
+ br i1 %q, label %loop.more, label %exit
+
+loop.more:
+ call void @objc_release(i8* %x)
+ br label %loop
+
+exit:
+ ret void
+}
+
+; Like test62 but with no release in loop.more.
+; Don't delete anything!
+
+; CHECK: define void @test64(
+; CHECK: loop:
+; CHECK: tail call i8* @objc_retain(i8* %x)
+; CHECK: exit:
+; CHECK: call void @objc_release(i8* %x)
+; CHECK: }
+define void @test64(i8* %x, i1* %p) nounwind {
+entry:
+ br label %loop
+
+loop:
+ call i8* @objc_retain(i8* %x)
+ %q = load i1* %p
+ br i1 %q, label %loop.more, label %exit
+
+loop.more:
+ br label %loop
+
+exit:
+ call void @objc_release(i8* %x)
+ ret void
+}
+
+; Move an autorelease past a phi with a null.
+
+; CHECK: define i8* @test65(
+; CHECK: if.then:
+; CHECK: call i8* @objc_autorelease(
+; CHECK: return:
+; CHECK-NOT: @objc_autorelease
+; CHECK: }
+define i8* @test65(i1 %x) {
+entry:
+ br i1 %x, label %return, label %if.then
+
+if.then: ; preds = %entry
+ %c = call i8* @returner()
+ %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
+ br label %return
+
+return: ; preds = %if.then, %entry
+ %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
+ %q = call i8* @objc_autorelease(i8* %retval) nounwind
+ ret i8* %retval
+}
+
+; Don't move an autorelease past an autorelease pool boundary.
+
+; CHECK: define i8* @test65b(
+; CHECK: if.then:
+; CHECK-NOT: @objc_autorelease
+; CHECK: return:
+; CHECK: call i8* @objc_autorelease(
+; CHECK: }
+define i8* @test65b(i1 %x) {
+entry:
+ %t = call i8* @objc_autoreleasePoolPush()
+ br i1 %x, label %return, label %if.then
+
+if.then: ; preds = %entry
+ %c = call i8* @returner()
+ %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
+ br label %return
+
+return: ; preds = %if.then, %entry
+ %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
+ call void @objc_autoreleasePoolPop(i8* %t)
+ %q = call i8* @objc_autorelease(i8* %retval) nounwind
+ ret i8* %retval
+}
+
+; Don't move an autoreleaseReuturnValue, which would break
+; the RV optimization.
+
+; CHECK: define i8* @test65c(
+; CHECK: if.then:
+; CHECK-NOT: @objc_autorelease
+; CHECK: return:
+; CHECK: call i8* @objc_autoreleaseReturnValue(
+; CHECK: }
+define i8* @test65c(i1 %x) {
+entry:
+ br i1 %x, label %return, label %if.then
+
+if.then: ; preds = %entry
+ %c = call i8* @returner()
+ %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
+ br label %return
+
+return: ; preds = %if.then, %entry
+ %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
+ %q = call i8* @objc_autoreleaseReturnValue(i8* %retval) nounwind
+ ret i8* %retval
+}
+
declare void @bar(i32 ()*)
; A few real-world testcases.
diff --git a/test/Transforms/ObjCARC/contract-storestrong-ivar.ll b/test/Transforms/ObjCARC/contract-storestrong-ivar.ll
index 4ad78e7..4a9b314 100644
--- a/test/Transforms/ObjCARC/contract-storestrong-ivar.ll
+++ b/test/Transforms/ObjCARC/contract-storestrong-ivar.ll
@@ -1,6 +1,6 @@
; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
-; CHECK: call void @objc_storeStrong(i8**
+; CHECK: tail call void @objc_storeStrong(i8**
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.0"
diff --git a/test/Transforms/ObjCARC/contract-storestrong.ll b/test/Transforms/ObjCARC/contract-storestrong.ll
index 25c93f4..4ff0596 100644
--- a/test/Transforms/ObjCARC/contract-storestrong.ll
+++ b/test/Transforms/ObjCARC/contract-storestrong.ll
@@ -9,7 +9,7 @@ declare void @objc_release(i8*)
; CHECK: define void @test0(
; CHECK: entry:
-; CHECK-NEXT: call void @objc_storeStrong(i8** @x, i8* %p) nounwind
+; CHECK-NEXT: tail call void @objc_storeStrong(i8** @x, i8* %p) nounwind
; CHECK-NEXT: ret void
define void @test0(i8* %p) {
entry:
@@ -33,7 +33,7 @@ entry:
define void @test1(i8* %p) {
entry:
%0 = tail call i8* @objc_retain(i8* %p) nounwind
- %tmp = volatile load i8** @x, align 8
+ %tmp = load volatile i8** @x, align 8
store i8* %0, i8** @x, align 8
tail call void @objc_release(i8* %tmp) nounwind
ret void
@@ -53,7 +53,7 @@ define void @test2(i8* %p) {
entry:
%0 = tail call i8* @objc_retain(i8* %p) nounwind
%tmp = load i8** @x, align 8
- volatile store i8* %0, i8** @x, align 8
+ store volatile i8* %0, i8** @x, align 8
tail call void @objc_release(i8* %tmp) nounwind
ret void
}
diff --git a/test/Transforms/ObjCARC/contract.ll b/test/Transforms/ObjCARC/contract.ll
index 04ae3ca..c48f8a5 100644
--- a/test/Transforms/ObjCARC/contract.ll
+++ b/test/Transforms/ObjCARC/contract.ll
@@ -143,3 +143,21 @@ define i8* @test7(i8* %p) {
%2 = tail call i8* @objc_autoreleaseReturnValue(i8* %p)
ret i8* %p
}
+
+; Do the return value substitution for PHI nodes too.
+
+; CHECK: define i8* @test8(
+; CHECK: %retval = phi i8* [ %p, %if.then ], [ null, %entry ]
+; CHECK: }
+define i8* @test8(i1 %x, i8* %c) {
+entry:
+ br i1 %x, label %return, label %if.then
+
+if.then: ; preds = %entry
+ %p = call i8* @objc_retain(i8* %c) nounwind
+ br label %return
+
+return: ; preds = %if.then, %entry
+ %retval = phi i8* [ %c, %if.then ], [ null, %entry ]
+ ret i8* %retval
+}
diff --git a/test/Transforms/ObjCARC/dg.exp b/test/Transforms/ObjCARC/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/ObjCARC/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/ObjCARC/invoke.ll b/test/Transforms/ObjCARC/invoke.ll
index cf971e4..76e82a5 100644
--- a/test/Transforms/ObjCARC/invoke.ll
+++ b/test/Transforms/ObjCARC/invoke.ll
@@ -2,9 +2,11 @@
declare i8* @objc_retain(i8*)
declare void @objc_release(i8*)
+declare i8* @objc_retainAutoreleasedReturnValue(i8*)
declare i8* @objc_msgSend(i8*, i8*, ...)
declare void @use_pointer(i8*)
declare void @callee()
+declare i8* @returner()
; ARCOpt shouldn't try to move the releases to the block containing the invoke.
@@ -68,6 +70,149 @@ done:
ret void
}
+; The optimizer should ignore invoke unwind paths consistently.
+; PR12265
+
+; CHECK: define void @test2() {
+; CHECK: invoke.cont:
+; CHECK-NEXT: call i8* @objc_retain
+; CHEK-NOT: @objc
+; CHECK: finally.cont:
+; CHECK-NEXT: call void @objc_release
+; CHEK-NOT: @objc
+; CHECK: finally.rethrow:
+; CHEK-NOT: @objc
+; CHECK: }
+define void @test2() {
+entry:
+ %call = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* ()*)()
+ to label %invoke.cont unwind label %finally.rethrow, !clang.arc.no_objc_arc_exceptions !0
+
+invoke.cont: ; preds = %entry
+ %tmp1 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
+ call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void ()*)(), !clang.arc.no_objc_arc_exceptions !0
+ invoke void @use_pointer(i8* %call)
+ to label %finally.cont unwind label %finally.rethrow, !clang.arc.no_objc_arc_exceptions !0
+
+finally.cont: ; preds = %invoke.cont
+ tail call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0
+ ret void
+
+finally.rethrow: ; preds = %invoke.cont, %entry
+ %tmp2 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ catch i8* null
+ unreachable
+}
+
+; Don't try to place code on invoke critical edges.
+
+; CHECK: define void @test3(
+; CHECK: if.end:
+; CHECK-NEXT: call void @objc_release(i8* %p) nounwind
+; CHECK-NEXT: ret void
+define void @test3(i8* %p, i1 %b) {
+entry:
+ %0 = call i8* @objc_retain(i8* %p)
+ call void @callee()
+ br i1 %b, label %if.else, label %if.then
+
+if.then:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+
+if.else:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+
+lpad:
+ %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ ret void
+
+if.end:
+ call void @objc_release(i8* %p)
+ ret void
+}
+
+; Like test3, but with ARC-relevant exception handling.
+
+; CHECK: define void @test4(
+; CHECK: lpad:
+; CHECK-NEXT: %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: call void @objc_release(i8* %p) nounwind
+; CHECK-NEXT: ret void
+; CHECK: if.end:
+; CHECK-NEXT: call void @objc_release(i8* %p) nounwind
+; CHECK-NEXT: ret void
+define void @test4(i8* %p, i1 %b) {
+entry:
+ %0 = call i8* @objc_retain(i8* %p)
+ call void @callee()
+ br i1 %b, label %if.else, label %if.then
+
+if.then:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad
+
+if.else:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad
+
+lpad:
+ %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ call void @objc_release(i8* %p)
+ ret void
+
+if.end:
+ call void @objc_release(i8* %p)
+ ret void
+}
+
+; Don't turn the retainAutoreleaseReturnValue into retain, because it's
+; for an invoke which we can assume codegen will put immediately prior.
+
+; CHECK: define void @test5(
+; CHECK: call i8* @objc_retainAutoreleasedReturnValue(i8* %z)
+; CHECK: }
+define void @test5() {
+entry:
+ %z = invoke i8* @returner()
+ to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+
+lpad:
+ %r13 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ ret void
+
+if.end:
+ call i8* @objc_retainAutoreleasedReturnValue(i8* %z)
+ ret void
+}
+
+; Like test5, but there's intervening code.
+
+; CHECK: define void @test6(
+; CHECK: call i8* @objc_retain(i8* %z)
+; CHECK: }
+define void @test6() {
+entry:
+ %z = invoke i8* @returner()
+ to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+
+lpad:
+ %r13 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ ret void
+
+if.end:
+ call void @callee()
+ call i8* @objc_retainAutoreleasedReturnValue(i8* %z)
+ ret void
+}
+
declare i32 @__gxx_personality_v0(...)
+declare i32 @__objc_personality_v0(...)
!0 = metadata !{}
diff --git a/test/Transforms/ObjCARC/lit.local.cfg b/test/Transforms/ObjCARC/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/ObjCARC/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/ObjCARC/nested.ll b/test/Transforms/ObjCARC/nested.ll
index 9eada8a..a618a21 100644
--- a/test/Transforms/ObjCARC/nested.ll
+++ b/test/Transforms/ObjCARC/nested.ll
@@ -484,12 +484,14 @@ forcoll.empty:
ret void
}
-; Delete a nested retain+release pair.
+; TODO: Delete a nested retain+release pair.
+; The optimizer currently can't do this, because of a split loop backedge.
+; See test9b for the same testcase without a split backedge.
; CHECK: define void @test9(
; CHECK: call i8* @objc_retain
; CHECK: call i8* @objc_retain
-; CHECK-NOT: @objc_retain
+; CHECK: call i8* @objc_retain
; CHECK: }
define void @test9() nounwind {
entry:
@@ -551,13 +553,79 @@ forcoll.empty:
ret void
}
-; Delete a nested retain+release pair.
+; Like test9, but without a split backedge. This we can optimize.
-; CHECK: define void @test10(
+; CHECK: define void @test9b(
; CHECK: call i8* @objc_retain
; CHECK: call i8* @objc_retain
; CHECK-NOT: @objc_retain
; CHECK: }
+define void @test9b() 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 ], [ 0, %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:
+ %phitmp = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %phitmp, %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* %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
+}
+
+; TODO: Delete a nested retain+release pair.
+; The optimizer currently can't do this, because of a split loop backedge.
+; See test10b for the same testcase without a split backedge.
+
+; CHECK: define void @test10(
+; CHECK: call i8* @objc_retain
+; CHECK: call i8* @objc_retain
+; CHECK: call i8* @objc_retain
+; CHECK: }
define void @test10() nounwind {
entry:
%state.ptr = alloca %struct.__objcFastEnumerationState, align 8
@@ -618,3 +686,68 @@ forcoll.empty:
call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
ret void
}
+
+; Like test10, but without a split backedge. This we can optimize.
+
+; CHECK: define void @test10b(
+; CHECK: call i8* @objc_retain
+; CHECK: call i8* @objc_retain
+; CHECK-NOT: @objc_retain
+; CHECK: }
+define void @test10b() 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 ], [ 0, %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:
+ %phitmp = add i64 %forcoll.index, 1
+ %exitcond = icmp eq i64 %phitmp, %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* %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/no-objc-arc-exceptions.ll b/test/Transforms/ObjCARC/no-objc-arc-exceptions.ll
new file mode 100644
index 0000000..9728f6e
--- /dev/null
+++ b/test/Transforms/ObjCARC/no-objc-arc-exceptions.ll
@@ -0,0 +1,122 @@
+; RUN: opt -S -objc-arc < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+%struct.__block_byref_x = type { i8*, %struct.__block_byref_x*, i32, i32, i32 }
+%struct.__block_descriptor = type { i64, i64 }
+@_NSConcreteStackBlock = external global i8*
+@__block_descriptor_tmp = external hidden constant { i64, i64, i8*, i8*, i8*, i8* }
+
+; The optimizer should make use of the !clang.arc.no_objc_arc_exceptions
+; metadata and eliminate the retainBlock+release pair here.
+; rdar://10803830.
+
+; CHECK: define void @test0(
+; CHECK-NOT: @objc
+; CHECK: }
+define void @test0() {
+entry:
+ %x = alloca %struct.__block_byref_x, align 8
+ %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+ %byref.isa = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 0
+ store i8* null, i8** %byref.isa, align 8
+ %byref.forwarding = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 1
+ store %struct.__block_byref_x* %x, %struct.__block_byref_x** %byref.forwarding, align 8
+ %byref.flags = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 2
+ store i32 0, i32* %byref.flags, align 8
+ %byref.size = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 3
+ store i32 32, i32* %byref.size, align 4
+ %block.isa = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %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*, i8* }>* %block, i64 0, i32 1
+ store i32 1107296256, i32* %block.flags, align 8
+ %block.reserved = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %block, i64 0, i32 2
+ store i32 0, i32* %block.reserved, align 4
+ %block.invoke = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %block, i64 0, i32 3
+ store i8* bitcast (void (i8*)* @__foo_block_invoke_0 to i8*), i8** %block.invoke, align 8
+ %block.descriptor = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %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*, i8* }>* %block, i64 0, i32 5
+ %t1 = bitcast %struct.__block_byref_x* %x to i8*
+ store i8* %t1, i8** %block.captured, align 8
+ %t2 = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %block to i8*
+ %t3 = call i8* @objc_retainBlock(i8* %t2) nounwind, !clang.arc.copy_on_escape !4
+ %t4 = getelementptr inbounds i8* %t3, i64 16
+ %t5 = bitcast i8* %t4 to i8**
+ %t6 = load i8** %t5, align 8
+ %t7 = bitcast i8* %t6 to void (i8*)*
+ invoke void %t7(i8* %t3)
+ to label %invoke.cont unwind label %lpad, !clang.arc.no_objc_arc_exceptions !4
+
+invoke.cont: ; preds = %entry
+ call void @objc_release(i8* %t3) nounwind, !clang.imprecise_release !4
+ call void @_Block_object_dispose(i8* %t1, i32 8)
+ ret void
+
+lpad: ; preds = %entry
+ %t8 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ call void @_Block_object_dispose(i8* %t1, i32 8)
+ resume { i8*, i32 } %t8
+}
+
+; There is no !clang.arc.no_objc_arc_exceptions
+; metadata here, so the optimizer shouldn't eliminate anything.
+
+; CHECK: define void @test0_no_metadata(
+; CHECK: call i8* @objc_retainBlock(
+; CHECK: invoke
+; CHECK: call void @objc_release(
+; CHECK: }
+define void @test0_no_metadata() {
+entry:
+ %x = alloca %struct.__block_byref_x, align 8
+ %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+ %byref.isa = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 0
+ store i8* null, i8** %byref.isa, align 8
+ %byref.forwarding = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 1
+ store %struct.__block_byref_x* %x, %struct.__block_byref_x** %byref.forwarding, align 8
+ %byref.flags = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 2
+ store i32 0, i32* %byref.flags, align 8
+ %byref.size = getelementptr inbounds %struct.__block_byref_x* %x, i64 0, i32 3
+ store i32 32, i32* %byref.size, align 4
+ %block.isa = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %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*, i8* }>* %block, i64 0, i32 1
+ store i32 1107296256, i32* %block.flags, align 8
+ %block.reserved = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %block, i64 0, i32 2
+ store i32 0, i32* %block.reserved, align 4
+ %block.invoke = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %block, i64 0, i32 3
+ store i8* bitcast (void (i8*)* @__foo_block_invoke_0 to i8*), i8** %block.invoke, align 8
+ %block.descriptor = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %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*, i8* }>* %block, i64 0, i32 5
+ %t1 = bitcast %struct.__block_byref_x* %x to i8*
+ store i8* %t1, i8** %block.captured, align 8
+ %t2 = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>* %block to i8*
+ %t3 = call i8* @objc_retainBlock(i8* %t2) nounwind, !clang.arc.copy_on_escape !4
+ %t4 = getelementptr inbounds i8* %t3, i64 16
+ %t5 = bitcast i8* %t4 to i8**
+ %t6 = load i8** %t5, align 8
+ %t7 = bitcast i8* %t6 to void (i8*)*
+ invoke void %t7(i8* %t3)
+ to label %invoke.cont unwind label %lpad
+
+invoke.cont: ; preds = %entry
+ call void @objc_release(i8* %t3) nounwind, !clang.imprecise_release !4
+ call void @_Block_object_dispose(i8* %t1, i32 8)
+ ret void
+
+lpad: ; preds = %entry
+ %t8 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ call void @_Block_object_dispose(i8* %t1, i32 8)
+ resume { i8*, i32 } %t8
+}
+
+declare i8* @objc_retainBlock(i8*)
+declare void @objc_release(i8*)
+declare void @_Block_object_dispose(i8*, i32)
+declare i32 @__objc_personality_v0(...)
+declare void @__foo_block_invoke_0(i8* nocapture) uwtable ssp
+
+!4 = metadata !{}
diff --git a/test/Transforms/ObjCARC/pointer-types.ll b/test/Transforms/ObjCARC/pointer-types.ll
new file mode 100644
index 0000000..6abc939
--- /dev/null
+++ b/test/Transforms/ObjCARC/pointer-types.ll
@@ -0,0 +1,31 @@
+; RUN: opt -objc-arc -S < %s | FileCheck %s
+
+; Don't hoist @objc_release past a use of its pointer, even
+; if the use has function type, because clang uses function types
+; in dubious ways.
+; rdar://10551239
+
+; CHECK: define void @test0(
+; CHECK: %otherBlock = phi void ()* [ %b1, %if.then ], [ null, %entry ]
+; CHECK-NEXT: call void @use_fptr(void ()* %otherBlock)
+; CHECK-NEXT: %tmp11 = bitcast void ()* %otherBlock to i8*
+; CHECK-NEXT: call void @objc_release(i8* %tmp11)
+
+define void @test0(i1 %tobool, void ()* %b1) {
+entry:
+ br i1 %tobool, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %otherBlock = phi void ()* [ %b1, %if.then ], [ null, %entry ]
+ call void @use_fptr(void ()* %otherBlock)
+ %tmp11 = bitcast void ()* %otherBlock to i8*
+ call void @objc_release(i8* %tmp11) nounwind
+ ret void
+}
+
+declare void @use_fptr(void ()*)
+declare void @objc_release(i8*)
+
diff --git a/test/Transforms/ObjCARC/pr12270.ll b/test/Transforms/ObjCARC/pr12270.ll
new file mode 100644
index 0000000..1faae5f
--- /dev/null
+++ b/test/Transforms/ObjCARC/pr12270.ll
@@ -0,0 +1,21 @@
+; RUN: opt -disable-output -objc-arc-contract %s
+; test that we don't crash on unreachable code
+%2 = type opaque
+
+define void @_i_Test__foo(%2 *%x) {
+entry:
+ unreachable
+
+return: ; No predecessors!
+ %bar = bitcast %2* %x to i8*
+ %foo = call i8* @objc_autoreleaseReturnValue(i8* %bar) nounwind
+ call void @callee()
+ call void @use_pointer(i8* %foo)
+ call void @objc_release(i8* %foo) nounwind
+ ret void
+}
+
+declare i8* @objc_autoreleaseReturnValue(i8*)
+declare void @objc_release(i8*)
+declare void @callee()
+declare void @use_pointer(i8*)
diff --git a/test/Transforms/ObjCARC/retain-block-alloca.ll b/test/Transforms/ObjCARC/retain-block-alloca.ll
index 468da91..01f2087 100644
--- a/test/Transforms/ObjCARC/retain-block-alloca.ll
+++ b/test/Transforms/ObjCARC/retain-block-alloca.ll
@@ -1,11 +1,6 @@
; 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 }
@@ -13,6 +8,10 @@
@__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"
+; CHECK: define void @test(
+; CHECK: %3 = call i8* @objc_retainBlock(i8* %2) nounwind
+; CHECK: @objc_msgSend
+; CHECK-NEXT: @objc_release(i8* %3)
define void @test(%0* %array) uwtable {
entry:
%block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>, align 8
@@ -41,6 +40,43 @@ entry:
ret void
}
+; Same as test, but the objc_retainBlock has a clang.arc.copy_on_escape
+; tag so it's safe to delete.
+
+; CHECK: define void @test_with_COE(
+; CHECK-NOT: @objc_retainBlock
+; CHECK: @objc_msgSend
+; CHECK: @objc_release
+; CHECK-NOT: @objc_release
+; CHECK: }
+define void @test_with_COE(%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, !clang.arc.copy_on_escape !0
+ %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
diff --git a/test/Transforms/ObjCARC/retain-block-load.ll b/test/Transforms/ObjCARC/retain-block-load.ll
new file mode 100644
index 0000000..a5170e3
--- /dev/null
+++ b/test/Transforms/ObjCARC/retain-block-load.ll
@@ -0,0 +1,51 @@
+; RUN: opt -objc-arc -S < %s | FileCheck %s
+
+; rdar://10803830
+; The optimizer should be able to prove that the block does not
+; "escape", so the retainBlock+release pair can be eliminated.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+%struct.__block_descriptor = type { i64, i64 }
+
+@_NSConcreteStackBlock = external global i8*
+@__block_descriptor_tmp = external global { i64, i64, i8*, i8* }
+
+; CHECK: define void @test() {
+; CHECK-NOT: @objc
+; CHECK: declare i8* @objc_retainBlock(i8*)
+; CHECK: declare void @objc_release(i8*)
+
+define void @test() {
+entry:
+ %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, align 8
+ %block.isa = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %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*, i32 }>* %block, i64 0, i32 1
+ store i32 1073741824, i32* %block.flags, align 8
+ %block.reserved = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %block, i64 0, i32 2
+ store i32 0, i32* %block.reserved, align 4
+ %block.invoke = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %block, i64 0, i32 3
+ store i8* bitcast (i32 (i8*)* @__test_block_invoke_0 to i8*), i8** %block.invoke, align 8
+ %block.descriptor = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %block, i64 0, i32 4
+ store %struct.__block_descriptor* bitcast ({ i64, i64, 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*, i32 }>* %block, i64 0, i32 5
+ store i32 4, i32* %block.captured, align 8
+ %tmp = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %block to i8*
+ %tmp1 = call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+ %tmp2 = getelementptr inbounds i8* %tmp1, i64 16
+ %tmp3 = bitcast i8* %tmp2 to i8**
+ %tmp4 = load i8** %tmp3, align 8
+ %tmp5 = bitcast i8* %tmp4 to i32 (i8*)*
+ %call = call i32 %tmp5(i8* %tmp1)
+ call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+declare i32 @__test_block_invoke_0(i8* nocapture %.block_descriptor) nounwind readonly
+
+declare i8* @objc_retainBlock(i8*)
+
+declare void @objc_release(i8*)
+
+!0 = metadata !{}
diff --git a/test/Transforms/ObjCARC/retain-block.ll b/test/Transforms/ObjCARC/retain-block.ll
new file mode 100644
index 0000000..b3b62d3
--- /dev/null
+++ b/test/Transforms/ObjCARC/retain-block.ll
@@ -0,0 +1,138 @@
+; RUN: opt -objc-arc -S < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64"
+
+!0 = metadata !{}
+
+declare i8* @objc_retain(i8*)
+declare void @callee(i8)
+declare void @use_pointer(i8*)
+declare void @objc_release(i8*)
+declare i8* @objc_retainBlock(i8*)
+declare i8* @objc_autorelease(i8*)
+
+; Basic retainBlock+release elimination.
+
+; CHECK: define void @test0(i8* %tmp) {
+; CHECK-NOT: @objc
+; CHECK: }
+define void @test0(i8* %tmp) {
+entry:
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Same as test0, but there's no copy_on_escape metadata, so there's no
+; optimization possible.
+
+; CHECK: define void @test0_no_metadata(i8* %tmp) {
+; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind
+; CHECK: tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+; CHECK: }
+define void @test0_no_metadata(i8* %tmp) {
+entry:
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Same as test0, but the pointer escapes, so there's no
+; optimization possible.
+
+; CHECK: define void @test0_escape(i8* %tmp, i8** %z) {
+; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+; CHECK: tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+; CHECK: }
+define void @test0_escape(i8* %tmp, i8** %z) {
+entry:
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+ store i8* %tmp2, i8** %z
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Same as test0_escape, but there's no intervening call.
+
+; CHECK: define void @test0_just_escape(i8* %tmp, i8** %z) {
+; CHECK: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+; CHECK: tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+; CHECK: }
+define void @test0_just_escape(i8* %tmp, i8** %z) {
+entry:
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+ store i8* %tmp2, i8** %z
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Basic nested retainBlock+release elimination.
+
+; CHECK: define void @test1(i8* %tmp) {
+; CHECK-NOT: @objc
+; CHECK: tail call i8* @objc_retain(i8* %tmp) nounwind
+; CHECK-NOT: @objc
+; CHECK: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0
+; CHECK-NOT: @objc
+; CHECK: }
+define void @test1(i8* %tmp) {
+entry:
+ %tmp1 = tail call i8* @objc_retain(i8* %tmp) nounwind
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Same as test1, but there's no copy_on_escape metadata, so there's no
+; retainBlock+release optimization possible. But we can still eliminate
+; the outer retain+release.
+
+; CHECK: define void @test1_no_metadata(i8* %tmp) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: tail call i8* @objc_retainBlock(i8* %tmp) nounwind
+; CHECK-NEXT: @use_pointer(i8* %tmp2)
+; CHECK-NEXT: @use_pointer(i8* %tmp2)
+; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0
+; CHECK-NOT: @objc
+; CHECK: }
+define void @test1_no_metadata(i8* %tmp) {
+entry:
+ %tmp1 = tail call i8* @objc_retain(i8* %tmp) nounwind
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0
+ ret void
+}
+
+; Same as test1, but the pointer escapes, so there's no
+; retainBlock+release optimization possible. But we can still eliminate
+; the outer retain+release
+
+; CHECK: define void @test1_escape(i8* %tmp, i8** %z) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+; CHECK-NEXT: store i8* %tmp2, i8** %z
+; CHECK-NEXT: @use_pointer(i8* %tmp2)
+; CHECK-NEXT: @use_pointer(i8* %tmp2)
+; CHECK-NEXT: tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0
+; CHECK-NOT: @objc
+; CHECK: }
+define void @test1_escape(i8* %tmp, i8** %z) {
+entry:
+ %tmp1 = tail call i8* @objc_retain(i8* %tmp) nounwind
+ %tmp2 = tail call i8* @objc_retainBlock(i8* %tmp) nounwind, !clang.arc.copy_on_escape !0
+ store i8* %tmp2, i8** %z
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @use_pointer(i8* %tmp2)
+ tail call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+ tail call void @objc_release(i8* %tmp) nounwind, !clang.imprecise_release !0
+ ret void
+}
diff --git a/test/Transforms/ObjCARC/retain-not-declared.ll b/test/Transforms/ObjCARC/retain-not-declared.ll
index 41bde01..f876e51 100644
--- a/test/Transforms/ObjCARC/retain-not-declared.ll
+++ b/test/Transforms/ObjCARC/retain-not-declared.ll
@@ -30,7 +30,7 @@ entry:
; CHECK: @test1(
; CHECK: @objc_retain(
-; CHECK: @objc_retain(
+; CHECK: @objc_retainAutoreleasedReturnValue(
; CHECK: @objc_release(
; CHECK: @objc_release(
; CHECK: }
diff --git a/test/Transforms/PhaseOrdering/dg.exp b/test/Transforms/PhaseOrdering/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/PhaseOrdering/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/PhaseOrdering/lit.local.cfg b/test/Transforms/PhaseOrdering/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/PhaseOrdering/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/PruneEH/dg.exp b/test/Transforms/PruneEH/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/PruneEH/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/PruneEH/lit.local.cfg b/test/Transforms/PruneEH/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/PruneEH/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/Reassociate/dg.exp b/test/Transforms/Reassociate/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/Reassociate/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/Reassociate/lit.local.cfg b/test/Transforms/Reassociate/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/Reassociate/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll b/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll
index cd6cf97..63f41db 100644
--- a/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll
+++ b/test/Transforms/SCCP/2008-05-23-UndefCallFold.ll
@@ -6,9 +6,9 @@ target triple = "i686-pc-linux-gnu"
define i32 @x(i32 %b) {
entry:
- %val = call i32 @llvm.cttz.i32(i32 undef)
+ %val = call i32 @llvm.cttz.i32(i32 undef, i1 true)
ret i32 %val
}
-declare i32 @llvm.cttz.i32(i32)
+declare i32 @llvm.cttz.i32(i32, i1)
diff --git a/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll b/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
index 7546bf5..f62ed70 100644
--- a/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
+++ b/test/Transforms/SCCP/2009-01-14-IPSCCP-Invoke.ll
@@ -21,10 +21,6 @@ define internal i32 @f() {
declare i8* @__cxa_begin_catch(i8*) nounwind
-declare i8* @llvm.eh.exception() nounwind
-
-declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind
-
declare void @__cxa_end_catch()
declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SCCP/dg.exp b/test/Transforms/SCCP/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/SCCP/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/SCCP/lit.local.cfg b/test/Transforms/SCCP/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/SCCP/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/SCCP/phitest.ll b/test/Transforms/SCCP/phitest.ll
deleted file mode 100644
index 4c5c3dc..0000000
--- a/test/Transforms/SCCP/phitest.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; RUN: opt < %s -sccp -dce -simplifycfg -S | not grep br
-
-define i32 @test(i32 %param) {
-entry:
- %tmp.1 = icmp ne i32 %param, 0 ; <i1> [#uses=1]
- br i1 %tmp.1, label %endif.0, label %else
-else: ; preds = %entry
- br label %endif.0
-endif.0: ; preds = %else, %entry
- %a.0 = phi i32 [ 2, %else ], [ 3, %entry ] ; <i32> [#uses=1]
- %b.0 = phi i32 [ 3, %else ], [ 2, %entry ] ; <i32> [#uses=1]
- %tmp.5 = add i32 %a.0, %b.0 ; <i32> [#uses=1]
- %tmp.7 = icmp ne i32 %tmp.5, 5 ; <i1> [#uses=1]
- br i1 %tmp.7, label %UnifiedReturnBlock, label %endif.1
-endif.1: ; preds = %endif.0
- ret i32 0
-UnifiedReturnBlock: ; preds = %endif.0
- ret i32 2
-}
-
diff --git a/test/Transforms/ScalarRepl/2009-03-05-Aggre2Scalar-dbg.ll b/test/Transforms/ScalarRepl/2009-03-05-Aggre2Scalar-dbg.ll
deleted file mode 100644
index d71bcb9..0000000
--- a/test/Transforms/ScalarRepl/2009-03-05-Aggre2Scalar-dbg.ll
+++ /dev/null
@@ -1,184 +0,0 @@
-; RUN: opt < %s -scalarrepl -disable-output -stats |& grep "Number of aggregates converted to scalar"
-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.6"
- %0 = type { } ; type %0
- %1 = type { i8*, i32, i32, i16, i16, %2, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %2, %3*, i32, [3 x i8], [1 x i8], %2, i32, i64 } ; type %1
- %2 = type { i8*, i32 } ; type %2
- %3 = type opaque ; type %3
- %4 = type { i32 } ; type %4
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, %0*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0*, %0*, i32 }
- %llvm.dbg.derivedtype.type = type { i32, %0*, i8*, %0*, i32, i64, i64, i64, i32, %0* }
- %llvm.dbg.subprogram.type = type { i32, %0*, %0*, i8*, i8*, i8*, %0*, i32, %0*, i1, i1 }
- %llvm.dbg.subrange.type = type { i32, i64, i64 }
- %llvm.dbg.variable.type = type { i32, %0*, i8*, %0*, i32, %0* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-internal constant [8 x i8] c"PR491.c\00", section "llvm.metadata" ; <[8 x i8]*>:0 [#uses=1]
-internal constant [77 x i8] c"/Volumes/Nanpura/mainline/llvm/projects/llvm-test/SingleSource/Regression/C/\00", section "llvm.metadata" ; <[77 x i8]*>:1 [#uses=1]
-internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*>:2 [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to %0*), i32 1, i8* getelementptr ([8 x i8]* @0, i32 0, i32 0), i8* getelementptr ([77 x i8]* @1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 0 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*>:3 [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([4 x i8]* @3, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*>:4 [#uses=1]
-@llvm.dbg.basictype5 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @4, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458790, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype6 = internal constant %llvm.dbg.derivedtype.type { i32 458767, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-internal constant [13 x i8] c"unsigned int\00", section "llvm.metadata" ; <[13 x i8]*>:5 [#uses=1]
-@llvm.dbg.basictype8 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([13 x i8]* @5, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 7 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [3 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype8 to %0*)], section "llvm.metadata" ; <[3 x %0*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([3 x %0*]* @llvm.dbg.array to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-internal constant [12 x i8] c"assert_fail\00", section "llvm.metadata" ; <[12 x i8]*>:6 [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([12 x i8]* @6, i32 0, i32 0), i8* getelementptr ([12 x i8]* @6, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 4, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to %0*), i1 true, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=0]
-internal constant [2 x i8] c"l\00", section "llvm.metadata" ; <[2 x i8]*>:7 [#uses=1]
-@__stderrp = external global %1* ; <%1**> [#uses=4]
-internal constant [35 x i8] c"assertion failed in line %u: '%s'\0A\00", section "__TEXT,__cstring,cstring_literals" ; <[35 x i8]*>:8 [#uses=1]
-@llvm.dbg.array13 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*), %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite14 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array13 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-internal constant [5 x i8] c"test\00", section "llvm.metadata" ; <[5 x i8]*>:9 [#uses=1]
-@llvm.dbg.subprogram16 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @9, i32 0, i32 0), i8* getelementptr ([5 x i8]* @9, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 10, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite14 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-internal constant [9 x i8] c"long int\00", section "llvm.metadata" ; <[9 x i8]*>:10 [#uses=1]
-@llvm.dbg.basictype21 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([9 x i8]* @10, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.derivedtype22 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to %0*), i8* getelementptr ([2 x i8]* @7, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 20, i64 32, i64 32, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype21 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 3 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1]
-@llvm.dbg.array23 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-internal constant [14 x i8] c"unsigned char\00", section "llvm.metadata" ; <[14 x i8]*>:11 [#uses=1]
-@llvm.dbg.basictype25 = internal constant %llvm.dbg.basictype.type { i32 458788, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([14 x i8]* @11, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 8 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.composite26 = internal constant %llvm.dbg.composite.type { i32 458753, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 32, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype25 to %0*), %0* bitcast ([1 x %0*]* @llvm.dbg.array23 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-internal constant [2 x i8] c"c\00", section "llvm.metadata" ; <[2 x i8]*>:12 [#uses=1]
-@llvm.dbg.derivedtype28 = internal constant %llvm.dbg.derivedtype.type { i32 458765, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to %0*), i8* getelementptr ([2 x i8]* @12, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 20, i64 32, i64 8, i64 0, i32 0, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite26 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array29 = internal constant [2 x %0*] [%0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype22 to %0*), %0* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype28 to %0*)], section "llvm.metadata" ; <[2 x %0*]*> [#uses=1]
-@llvm.dbg.composite30 = internal constant %llvm.dbg.composite.type { i32 458775, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 20, i64 32, i64 32, i64 0, i32 0, %0* null, %0* bitcast ([2 x %0*]* @llvm.dbg.array29 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-internal constant [2 x i8] c"u\00", section "llvm.metadata" ; <[2 x i8]*>:13 [#uses=1]
-@llvm.dbg.variable32 = internal constant %llvm.dbg.variable.type { i32 459008, %0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to %0*), i8* getelementptr ([2 x i8]* @13, i32 0, i32 0), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 20, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite30 to %0*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-internal constant [11 x i8] c"u.l == 128\00", section "__TEXT,__cstring,cstring_literals" ; <[11 x i8]*>:14 [#uses=1]
-internal constant [8 x i8] c"u.l < 0\00", section "__TEXT,__cstring,cstring_literals" ; <[8 x i8]*>:15 [#uses=1]
-@llvm.dbg.array35 = internal constant [1 x %0*] [%0* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to %0*)], section "llvm.metadata" ; <[1 x %0*]*> [#uses=1]
-@llvm.dbg.composite36 = internal constant %llvm.dbg.composite.type { i32 458773, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 0, i64 0, i64 0, i64 0, i32 0, %0* null, %0* bitcast ([1 x %0*]* @llvm.dbg.array35 to %0*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*>:16 [#uses=1]
-@llvm.dbg.subprogram38 = internal constant %llvm.dbg.subprogram.type { i32 458798, %0* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to %0*), %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i8* getelementptr ([5 x i8]* @16, i32 0, i32 0), i8* getelementptr ([5 x i8]* @16, i32 0, i32 0), i8* null, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*), i32 28, %0* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite36 to %0*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-
-declare void @llvm.dbg.func.start(%0*) nounwind readnone
-
-declare void @llvm.dbg.declare(%0*, %0*) nounwind readnone
-
-declare void @llvm.dbg.stoppoint(i32, i32, %0*) nounwind readnone
-
-declare i32 @fprintf(%1* nocapture, i8* nocapture, ...) nounwind
-
-declare void @llvm.dbg.region.end(%0*) nounwind readnone
-
-define i32 @test(i32) nounwind {
-; <label>:1
- %2 = alloca %4, align 8 ; <%4*> [#uses=7]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to %0*))
- %3 = bitcast %4* %2 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %3, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable32 to %0*))
- call void @llvm.dbg.stoppoint(i32 21, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %4 = getelementptr %4* %2, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %4, align 8
- %5 = bitcast %4* %2 to i8* ; <i8*> [#uses=1]
- store i8 -128, i8* %5, align 8
- call void @llvm.dbg.stoppoint(i32 22, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %6 = getelementptr %4* %2, i32 0, i32 0 ; <i32*> [#uses=1]
- %7 = load i32* %6, align 8 ; <i32> [#uses=1]
- %8 = icmp eq i32 %7, 128 ; <i1> [#uses=1]
- br i1 %8, label %12, label %9
-
-; <label>:9 ; preds = %1
- call void @llvm.dbg.stoppoint(i32 5, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %10 = load %1** @__stderrp, align 4 ; <%1*> [#uses=1]
- %11 = call i32 (%1*, i8*, ...)* @fprintf(%1* %10, i8* getelementptr ([35 x i8]* @8, i32 0, i32 0), i32 22, i8* getelementptr ([11 x i8]* @14, i32 0, i32 0)) nounwind ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 6, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- br label %12
-
-; <label>:12 ; preds = %9, %1
- %.0 = phi i32 [ 0, %9 ], [ 1, %1 ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 22, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %13 = and i32 %.0, %0 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 23, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %14 = getelementptr %4* %2, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %14, align 8
- %15 = bitcast %4* %2 to [4 x i8]* ; <[4 x i8]*> [#uses=1]
- %16 = getelementptr [4 x i8]* %15, i32 0, i32 3 ; <i8*> [#uses=1]
- store i8 -128, i8* %16, align 1
- call void @llvm.dbg.stoppoint(i32 24, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %17 = getelementptr %4* %2, i32 0, i32 0 ; <i32*> [#uses=1]
- %18 = load i32* %17, align 8 ; <i32> [#uses=1]
- %19 = icmp slt i32 %18, 0 ; <i1> [#uses=1]
- br i1 %19, label %23, label %20
-
-; <label>:20 ; preds = %12
- call void @llvm.dbg.stoppoint(i32 5, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %21 = load %1** @__stderrp, align 4 ; <%1*> [#uses=1]
- %22 = call i32 (%1*, i8*, ...)* @fprintf(%1* %21, i8* getelementptr ([35 x i8]* @8, i32 0, i32 0), i32 24, i8* getelementptr ([8 x i8]* @15, i32 0, i32 0)) nounwind ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 6, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- br label %23
-
-; <label>:23 ; preds = %20, %12
- %.01 = phi i32 [ 0, %20 ], [ 1, %12 ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 24, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %24 = and i32 %.01, %13 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 25, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to %0*))
- ret i32 %24
-}
-
-define i32 @main() nounwind {
-; <label>:0
- %1 = alloca %4, align 8 ; <%4*> [#uses=7]
- call void @llvm.dbg.func.start(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram38 to %0*))
- call void @llvm.dbg.stoppoint(i32 29, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- %2 = bitcast %4* %1 to %0* ; <%0*> [#uses=1]
- call void @llvm.dbg.declare(%0* %2, %0* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable32 to %0*)) nounwind
- call void @llvm.dbg.stoppoint(i32 21, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %3 = getelementptr %4* %1, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %3, align 8
- %4 = bitcast %4* %1 to i8* ; <i8*> [#uses=1]
- store i8 -128, i8* %4, align 8
- call void @llvm.dbg.stoppoint(i32 22, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %5 = getelementptr %4* %1, i32 0, i32 0 ; <i32*> [#uses=1]
- %6 = load i32* %5, align 8 ; <i32> [#uses=1]
- %7 = icmp eq i32 %6, 128 ; <i1> [#uses=1]
- br i1 %7, label %11, label %8
-
-; <label>:8 ; preds = %0
- call void @llvm.dbg.stoppoint(i32 5, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %9 = load %1** @__stderrp, align 4 ; <%1*> [#uses=1]
- %10 = call i32 (%1*, i8*, ...)* @fprintf(%1* %9, i8* getelementptr ([35 x i8]* @8, i32 0, i32 0), i32 22, i8* getelementptr ([11 x i8]* @14, i32 0, i32 0)) nounwind ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 6, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- br label %11
-
-; <label>:11 ; preds = %8, %0
- %.0.i = phi i32 [ 0, %8 ], [ 1, %0 ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 23, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %12 = getelementptr %4* %1, i32 0, i32 0 ; <i32*> [#uses=1]
- store i32 0, i32* %12, align 8
- %13 = bitcast %4* %1 to [4 x i8]* ; <[4 x i8]*> [#uses=1]
- %14 = getelementptr [4 x i8]* %13, i32 0, i32 3 ; <i8*> [#uses=1]
- store i8 -128, i8* %14, align 1
- call void @llvm.dbg.stoppoint(i32 24, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %15 = getelementptr %4* %1, i32 0, i32 0 ; <i32*> [#uses=1]
- %16 = load i32* %15, align 8 ; <i32> [#uses=1]
- %17 = icmp slt i32 %16, 0 ; <i1> [#uses=1]
- br i1 %17, label %test.exit, label %18
-
-; <label>:18 ; preds = %11
- call void @llvm.dbg.stoppoint(i32 5, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %19 = load %1** @__stderrp, align 4 ; <%1*> [#uses=1]
- %20 = call i32 (%1*, i8*, ...)* @fprintf(%1* %19, i8* getelementptr ([35 x i8]* @8, i32 0, i32 0), i32 24, i8* getelementptr ([8 x i8]* @15, i32 0, i32 0)) nounwind ; <i32> [#uses=0]
- call void @llvm.dbg.stoppoint(i32 6, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- br label %test.exit
-
-test.exit: ; preds = %18, %11
- %.01.i = phi i32 [ 0, %18 ], [ 1, %11 ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 24, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %21 = and i32 %.01.i, %.0.i ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 25, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*)) nounwind
- %tmp = xor i32 %21, 1 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 29, i32 0, %0* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to %0*))
- call void @llvm.dbg.region.end(%0* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram38 to %0*))
- ret i32 %tmp
-}
diff --git a/test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll b/test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll
new file mode 100644
index 0000000..cd21ff5
--- /dev/null
+++ b/test/Transforms/ScalarRepl/2011-10-22-VectorCrash.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -S -scalarrepl | FileCheck %s
+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"
+
+%union.anon = type { <4 x float> }
+
+; CHECK: @test
+; CHECK-NOT: alloca
+
+define void @test() nounwind {
+entry:
+ %u = alloca %union.anon, align 16
+ %u164 = bitcast %union.anon* %u to [4 x i32]*
+ %arrayidx165 = getelementptr inbounds [4 x i32]* %u164, i32 0, i32 0
+ store i32 undef, i32* %arrayidx165, align 4
+ %v186 = bitcast %union.anon* %u to <4 x float>*
+ store <4 x float> undef, <4 x float>* %v186, align 16
+ ret void
+}
diff --git a/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll b/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll
new file mode 100644
index 0000000..da707b7
--- /dev/null
+++ b/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll
@@ -0,0 +1,26 @@
+; 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-S128"
+
+%struct.S = type { [2 x %struct.anon], double }
+%struct.anon = type {}
+
+; CHECK: @test()
+; CHECK-NOT: alloca
+; CHECK: ret double 1.0
+
+define double @test() nounwind uwtable ssp {
+entry:
+ %retval = alloca %struct.S, align 8
+ %ret = alloca %struct.S, align 8
+ %b = getelementptr inbounds %struct.S* %ret, i32 0, i32 1
+ store double 1.000000e+00, double* %b, align 8
+ %0 = bitcast %struct.S* %retval to i8*
+ %1 = bitcast %struct.S* %ret to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 8, i32 8, i1 false)
+ %2 = bitcast %struct.S* %retval to double*
+ %3 = load double* %2, align 1
+ ret double %3
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
diff --git a/test/Transforms/ScalarRepl/debuginfo.ll b/test/Transforms/ScalarRepl/debuginfo.ll
deleted file mode 100644
index ae2c6cc..0000000
--- a/test/Transforms/ScalarRepl/debuginfo.ll
+++ /dev/null
@@ -1,107 +0,0 @@
-; RUN: opt < %s -scalarrepl -S | not grep alloca
-; RUN: opt < %s -scalarrepl-ssa -S | not grep alloca
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
- %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
- %struct.Sphere = type { %struct.Vec }
- %struct.Vec = type { i32, i32, i32 }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [6 x i8] c"r.cpp\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 4, i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"Vec\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str5 = internal constant [2 x i8] c"x\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str6 = internal constant [2 x i8] c"y\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype7 = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str6, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, i64 32, i64 32, i64 32, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str8 = internal constant [2 x i8] c"z\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype9 = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str8, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, i64 32, i64 32, i64 64, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype10 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype11 = internal constant %llvm.dbg.derivedtype.type { i32 458790, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 96, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype12 = internal constant %llvm.dbg.derivedtype.type { i32 458768, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [3 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype10 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1]
-@llvm.dbg.composite13 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite13 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array14 = internal constant [5 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype10 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[5 x { }*]*> [#uses=1]
-@llvm.dbg.composite15 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([5 x { }*]* @llvm.dbg.array14 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram16 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 5, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite15 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array17 = internal constant [5 x { }*] [ { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype7 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype9 to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram16 to { }*) ], section "llvm.metadata" ; <[5 x { }*]*> [#uses=1]
-@llvm.dbg.composite18 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, i64 96, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([5 x { }*]* @llvm.dbg.array17 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype19 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array20 = internal constant [5 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype19 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[5 x { }*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([5 x { }*]* @llvm.dbg.array20 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str21 = internal constant [13 x i8] c"__comp_ctor \00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1]
-@.str22 = internal constant [14 x i8] c"_ZN3VecC1Eiii\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@llvm.dbg.array32 = internal constant [3 x { }*] [ { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1]
-@llvm.dbg.composite33 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array32 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str34 = internal constant [10 x i8] c"operator-\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str35 = internal constant [14 x i8] c"_ZmiRK3VecS1_\00", section "llvm.metadata" ; <[14 x i8]*> [#uses=1]
-@.str41 = internal constant [7 x i8] c"Sphere\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str43 = internal constant [7 x i8] c"center\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype44 = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([7 x i8]* @.str43, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 14, i64 96, i64 32, i64 0, i32 1, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.derivedtype45 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite52 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array46 = internal constant [3 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype45 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1]
-@llvm.dbg.composite47 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array46 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@.str48 = internal constant [11 x i8] c"ray_sphere\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1]
-@.str49 = internal constant [30 x i8] c"_ZN6Sphere10ray_sphereERK3Vec\00", section "llvm.metadata" ; <[30 x i8]*> [#uses=1]
-@llvm.dbg.subprogram50 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([11 x i8]* @.str48, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str48, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str49, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 16, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite47 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.array51 = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype44 to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram50 to { }*) ], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1]
-@llvm.dbg.composite52 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([7 x i8]* @.str41, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 12, i64 96, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array51 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.derivedtype53 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite52 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@llvm.dbg.array54 = internal constant [3 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype53 to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1]
-@llvm.dbg.composite55 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array54 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprogram56 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([11 x i8]* @.str48, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str48, i32 0, i32 0), i8* getelementptr ([30 x i8]* @.str49, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 16, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite55 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str61 = internal constant [2 x i8] c"v\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable62 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram56 to { }*), i8* getelementptr ([2 x i8]* @.str61, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 17, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite18 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
-
-define i32 @_ZN6Sphere10ray_sphereERK3Vec(%struct.Sphere* %this, %struct.Vec* %Orig) nounwind {
-entry:
- %v = alloca %struct.Vec, align 8 ; <%struct.Vec*> [#uses=4]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram56 to { }*))
- %0 = bitcast %struct.Vec* %v to { }* ; <{ }*> [#uses=1]
- call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable62 to { }*))
- %1 = getelementptr %struct.Sphere* %this, i32 0, i32 0, i32 2 ; <i32*> [#uses=1]
- %2 = load i32* %1, align 4 ; <i32> [#uses=1]
- %3 = getelementptr %struct.Vec* %Orig, i32 0, i32 2 ; <i32*> [#uses=1]
- %4 = load i32* %3, align 4 ; <i32> [#uses=1]
- %5 = sub i32 %2, %4 ; <i32> [#uses=1]
- %6 = getelementptr %struct.Sphere* %this, i32 0, i32 0, i32 1 ; <i32*> [#uses=1]
- %7 = load i32* %6, align 4 ; <i32> [#uses=1]
- %8 = getelementptr %struct.Vec* %Orig, i32 0, i32 1 ; <i32*> [#uses=1]
- %9 = load i32* %8, align 4 ; <i32> [#uses=1]
- %10 = sub i32 %7, %9 ; <i32> [#uses=1]
- %11 = getelementptr %struct.Sphere* %this, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
- %12 = load i32* %11, align 4 ; <i32> [#uses=1]
- %13 = getelementptr %struct.Vec* %Orig, i32 0, i32 0 ; <i32*> [#uses=1]
- %14 = load i32* %13, align 4 ; <i32> [#uses=1]
- %15 = sub i32 %12, %14 ; <i32> [#uses=1]
- %16 = getelementptr %struct.Vec* %v, i32 0, i32 0 ; <i32*> [#uses=2]
- store i32 %15, i32* %16, align 8
- %17 = getelementptr %struct.Vec* %v, i32 0, i32 1 ; <i32*> [#uses=1]
- store i32 %10, i32* %17, align 4
- %18 = getelementptr %struct.Vec* %v, i32 0, i32 2 ; <i32*> [#uses=1]
- store i32 %5, i32* %18, align 8
- call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind
- call void @llvm.dbg.stoppoint(i32 9, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) nounwind
- %19 = load i32* %16, align 8 ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 18, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram56 to { }*))
- ret i32 %19
-}
diff --git a/test/Transforms/ScalarRepl/dg.exp b/test/Transforms/ScalarRepl/dg.exp
deleted file mode 100644
index 39954d8..0000000
--- a/test/Transforms/ScalarRepl/dg.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-load_lib llvm.exp
-
-RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
diff --git a/test/Transforms/ScalarRepl/lit.local.cfg b/test/Transforms/ScalarRepl/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/Transforms/ScalarRepl/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/test/Transforms/ScalarRepl/negative-memset.ll b/test/Transforms/ScalarRepl/negative-memset.ll
new file mode 100644
index 0000000..e52ab46
--- /dev/null
+++ b/test/Transforms/ScalarRepl/negative-memset.ll
@@ -0,0 +1,20 @@
+; PR12202
+; RUN: opt < %s -scalarrepl -S
+; Ensure that we do not hang or crash when feeding a negative value to memset
+
+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-S32"
+target triple = "i686-pc-win32"
+
+define i32 @test() nounwind {
+entry:
+ %retval = alloca i32, align 4
+ %buff = alloca [1 x i8], align 1
+ store i32 0, i32* %retval
+ %0 = bitcast [1 x i8]* %buff to i8*
+ call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 1, i32 1, i1 false)
+ %arraydecay = getelementptr inbounds [1 x i8]* %buff, i32 0, i32 0
+ call void @llvm.memset.p0i8.i32(i8* %arraydecay, i8 -1, i32 -8, i32 1, i1 false) ; Negative 8!
+ ret i32 0
+}
+
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
diff --git a/test/Transforms/ScalarRepl/phi-cycle.ll b/test/Transforms/ScalarRepl/phi-cycle.ll
new file mode 100644
index 0000000..cb5101c
--- /dev/null
+++ b/test/Transforms/ScalarRepl/phi-cycle.ll
@@ -0,0 +1,77 @@
+; RUN: opt -S -scalarrepl-ssa < %s | FileCheck %s
+; rdar://10589171
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.foo = type { i32, i32 }
+
+@.str = private unnamed_addr constant [6 x i8] c"x=%d\0A\00", align 1
+
+define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable {
+entry:
+ %f = alloca %struct.foo, align 4
+ %x.i = getelementptr inbounds %struct.foo* %f, i64 0, i32 0
+ store i32 1, i32* %x.i, align 4
+ %y.i = getelementptr inbounds %struct.foo* %f, i64 0, i32 1
+ br label %while.cond.i
+
+; CHECK: while.cond.i:
+; CHECK-NEXT: %tmp = phi i32 [ 1, %entry ], [ %tmp2, %while.cond.backedge.i ]
+; CHECK-NEXT: %pos.0.i = phi i32 [ 1, %entry ], [ %xtmp.i, %while.cond.backedge.i ]
+; CHECK-NEXT: %left.0.i = phi i32 [ 1, %entry ], [ %dec.i, %while.cond.backedge.i ]
+; CHECK-NOT: phi
+while.cond.i: ; preds = %while.cond.backedge.i, %entry
+ %tmp = phi i32 [ 1, %entry ], [ %tmp2, %while.cond.backedge.i ]
+ %pos.0.i = phi i32 [ 1, %entry ], [ %xtmp.i, %while.cond.backedge.i ]
+ %left.0.i = phi i32 [ 1, %entry ], [ %dec.i, %while.cond.backedge.i ]
+ %cmp.i = icmp sgt i32 %left.0.i, 0
+ br i1 %cmp.i, label %while.body.i, label %while.cond.i.func.exit_crit_edge
+
+while.cond.i.func.exit_crit_edge: ; preds = %while.cond.i
+ br label %func.exit
+
+while.body.i: ; preds = %while.cond.i
+ %dec.i = add nsw i32 %left.0.i, -1
+ switch i32 1, label %while.body.i.func.exit_crit_edge [
+ i32 0, label %while.cond.backedge.i
+ i32 1, label %sw.bb.i
+ ]
+
+while.body.i.func.exit_crit_edge: ; preds = %while.body.i
+ br label %func.exit
+
+sw.bb.i: ; preds = %while.body.i
+ %cmp2.i = icmp eq i32 %tmp, 1
+ br i1 %cmp2.i, label %if.then.i, label %if.end.i
+
+if.then.i: ; preds = %sw.bb.i
+ store i32 %pos.0.i, i32* %x.i, align 4
+ br label %if.end.i
+
+; CHECK: if.end.i:
+; CHECK-NEXT: %tmp1 = phi i32 [ %pos.0.i, %if.then.i ], [ %tmp, %sw.bb.i ]
+; CHECK-NOT: phi
+if.end.i: ; preds = %if.then.i, %sw.bb.i
+ %tmp1 = phi i32 [ %pos.0.i, %if.then.i ], [ %tmp, %sw.bb.i ]
+ store i32 %tmp1, i32* %y.i, align 4
+ br label %while.cond.backedge.i
+
+; CHECK: while.cond.backedge.i:
+; CHECK-NEXT: %tmp2 = phi i32 [ %tmp1, %if.end.i ], [ %tmp, %while.body.i ]
+; CHECK-NOT: phi
+while.cond.backedge.i: ; preds = %if.end.i, %while.body.i
+ %tmp2 = phi i32 [ %tmp1, %if.end.i ], [ %tmp, %while.body.i ]
+ %xtmp.i = add i32 %pos.0.i, 1
+ br label %while.cond.i
+
+; CHECK: func.exit:
+; CHECK-NOT: load
+; CHECK: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp) nounwind
+func.exit: ; preds = %while.body.i.func.exit_crit_edge, %while.cond.i.func.exit_crit_edge
+ %tmp3 = load i32* %x.i, align 4
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp3) nounwind
+ ret i32 0
+}
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/test/Transforms/ScalarRepl/volatile.ll b/test/Transforms/ScalarRepl/volatile.ll
index ab276b0..fadf1aa 100644
--- a/test/Transforms/ScalarRepl/volatile.ll
+++ b/test/Transforms/ScalarRepl/volatile.ll
@@ -4,9 +4,9 @@
define i32 @voltest(i32 %T) {
%A = alloca {i32, i32}
%B = getelementptr {i32,i32}* %A, i32 0, i32 0
- volatile store i32 %T, i32* %B
+ store volatile i32 %T, i32* %B
%C = getelementptr {i32,i32}* %A, i32 0, i32 1
- %X = volatile load i32* %C
+ %X = load volatile i32* %C
ret i32 %X
}
diff --git a/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll b/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
index 568e61c..e2765e5 100644
--- a/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
+++ b/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll
@@ -1,9 +1,14 @@
-; RUN: opt < %s -simplifycfg -S | grep {br i1 } | count 4
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
; PR3354
; Do not merge bb1 into the entry block, it might trap.
@G = extern_weak global i32
+; CHECK: @test(
+; CHECK: br i1 %tmp25
+; CHECK: bb1:
+; CHECK: sdiv
+
define i32 @test(i32 %tmp21, i32 %tmp24) {
%tmp25 = icmp sle i32 %tmp21, %tmp24
br i1 %tmp25, label %bb2, label %bb1
@@ -18,6 +23,11 @@ bb6:
ret i32 927
}
+; CHECK: @test2(
+; CHECK: br i1 %tmp34
+; CHECK: bb5:
+; CHECK: sdiv
+
define i32 @test2(i32 %tmp21, i32 %tmp24, i1 %tmp34) {
br i1 %tmp34, label %bb5, label %bb6
diff --git a/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll b/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll
deleted file mode 100644
index ebacf2f..0000000
--- a/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll
+++ /dev/null
@@ -1,6 +0,0 @@
-; RUN: opt %s -simplifycfg -disable-output
-; PR8445
-
-define void @test() {
- unwind
-}
diff --git a/test/Transforms/SimplifyCFG/SpeculativeExec.ll b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
index 5cfc77c..a61867f 100644
--- a/test/Transforms/SimplifyCFG/SpeculativeExec.ll
+++ b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
@@ -1,7 +1,10 @@
-; RUN: opt < %s -simplifycfg -S | grep select
-; RUN: opt < %s -simplifycfg -S | grep br | count 2
+; RUN: opt < %s -simplifycfg -phi-node-folding-threshold=2 -S | FileCheck %s
-define i32 @t2(i32 %a, i32 %b, i32 %c) nounwind {
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @test1(i32 %a, i32 %b, i32 %c) nounwind {
+; CHECK: @test1
entry:
%tmp1 = icmp eq i32 %b, 0
br i1 %tmp1, label %bb1, label %bb3
@@ -9,6 +12,11 @@ entry:
bb1: ; preds = %entry
%tmp2 = icmp sgt i32 %c, 1
br i1 %tmp2, label %bb2, label %bb3
+; CHECK: bb1:
+; CHECK-NEXT: icmp sgt i32 %c, 1
+; CHECK-NEXT: add i32 %a, 1
+; CHECK-NEXT: select i1 %tmp2, i32 %tmp3, i32 %a
+; CHECK-NEXT: br label %bb3
bb2: ; preds = bb1
%tmp3 = add i32 %a, 1
@@ -19,3 +27,20 @@ bb3: ; preds = %bb2, %entry
%tmp5 = sub i32 %tmp4, 1
ret i32 %tmp5
}
+
+declare i8 @llvm.cttz.i8(i8, i1)
+
+define i8 @test2(i8 %a) {
+; CHECK: @test2
+ br i1 undef, label %bb_true, label %bb_false
+bb_true:
+ %b = tail call i8 @llvm.cttz.i8(i8 %a, i1 false)
+ br label %join
+bb_false:
+ br label %join
+join:
+ %c = phi i8 [%b, %bb_true], [%a, %bb_false]
+; CHECK: select
+ ret i8 %c
+}
+
diff --git a/test/Transforms/SimplifyCFG/branch-branch-dbginfo.ll b/test/Transforms/SimplifyCFG/branch-branch-dbginfo.ll
deleted file mode 100644
index 761f0d5..0000000
--- a/test/Transforms/SimplifyCFG/branch-branch-dbginfo.ll
+++ /dev/null
@@ -1,70 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | grep {br i1} | count 1
-
-; ModuleID = '<stdin>'
-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:32:32"
-target triple = "i386-pc-linux-gnu"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8* }
- %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 393262, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 393233, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([7 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 393216, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [7 x i8] c"cond.c\00", section "llvm.metadata" ; <[7 x i8]*> [#uses=1]
-@.str1 = internal constant [5 x i8] c"/tmp\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5555) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@.str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 393473, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=0]
-@.str5 = internal constant [2 x i8] c"x\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable6 = internal constant %llvm.dbg.variable.type { i32 393473, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=0]
-@.str7 = internal constant [2 x i8] c"y\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 393238, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([6 x i8]* @.str8, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, i64 0, i64 0, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype9 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
-@.str8 = internal constant [6 x i8] c"uint1\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@llvm.dbg.basictype9 = internal constant %llvm.dbg.basictype.type { i32 393252, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 7 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-
-define i32 @foo(i32 %x1, i1 zeroext %y2) nounwind {
-entry:
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp4 = icmp eq i32 %x1, 0 ; <i1> [#uses=1]
- br i1 %tmp4, label %bb, label %bb14
-
-bb: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %y2, label %bb14, label %bb10
-
-bb7: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 7, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp9 = call i32 @g1(i32 %x1) nounwind ; <i32> [#uses=1]
- ret i32 %tmp9
-
-bb10: ; preds = %bb
- call void @llvm.dbg.stoppoint(i32 8, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp12 = add i32 %x1, 1 ; <i32> [#uses=1]
- %tmp13 = call i32 @g2(i32 %tmp12) nounwind ; <i32> [#uses=1]
- ret i32 %tmp13
-
-bb14: ; preds = %entry
- call void @llvm.dbg.stoppoint(i32 10, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp16 = call i32 @g1(i32 %x1) nounwind ; <i32> [#uses=1]
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- ret i32 %tmp16
-}
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare i32 @g1(i32)
-
-declare i32 @g2(i32)
-
-declare void @llvm.dbg.region.end({ }*) nounwind
diff --git a/test/Transforms/SimplifyCFG/branch-fold.ll b/test/Transforms/SimplifyCFG/branch-fold.ll
index 266609b5..2b29681 100644
--- a/test/Transforms/SimplifyCFG/branch-fold.ll
+++ b/test/Transforms/SimplifyCFG/branch-fold.ll
@@ -1,13 +1,19 @@
-; RUN: opt < %s -simplifycfg -S | grep {br i1} | count 1
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
define void @test(i32* %P, i32* %Q, i1 %A, i1 %B) {
+; CHECK: test
+; CHECK: br i1
+; CHECK-NOT: br i1
+; CHECK: ret
+; CHECK: ret
+
+entry:
br i1 %A, label %a, label %b
-a: ; preds = %0
+a:
br i1 %B, label %b, label %c
-b: ; preds = %a, %0
+b:
store i32 123, i32* %P
ret void
-c: ; preds = %a
+c:
ret void
}
-
diff --git a/test/Transforms/SimplifyCFG/branch_fold_dbg.ll b/test/Transforms/SimplifyCFG/branch_fold_dbg.ll
deleted file mode 100644
index 6a500de..0000000
--- a/test/Transforms/SimplifyCFG/branch_fold_dbg.ll
+++ /dev/null
@@ -1,122 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | not grep br
-; END.
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"
-
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-
-define void @main() {
-entry:
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.14.i19 = icmp eq i32 0, 2 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.14.i19, label %endif.1.i20, label %read_min.exit
-endif.1.i20: ; preds = %entry
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.9.i.i = icmp eq i8* null, null ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.9.i.i, label %then.i12.i, label %then.i.i
-then.i.i: ; preds = %endif.1.i20
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-then.i12.i: ; preds = %endif.1.i20
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.9.i4.i = icmp eq i8* null, null ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.9.i4.i, label %endif.2.i33, label %then.i5.i
-then.i5.i: ; preds = %then.i12.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-endif.2.i33: ; preds = %then.i12.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %loopexit.0.i40, label %no_exit.0.i35
-no_exit.0.i35: ; preds = %no_exit.0.i35, %endif.2.i33
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.130.i = icmp slt i32 0, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.130.i, label %loopexit.0.i40.loopexit, label %no_exit.0.i35
-loopexit.0.i40.loopexit: ; preds = %no_exit.0.i35
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %loopexit.0.i40
-loopexit.0.i40: ; preds = %loopexit.0.i40.loopexit, %endif.2.i33
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.341.i = icmp eq i32 0, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.341.i, label %loopentry.1.i, label %read_min.exit
-loopentry.1.i: ; preds = %loopexit.0.i40
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.347.i = icmp sgt i32 0, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.347.i, label %no_exit.1.i41, label %loopexit.2.i44
-no_exit.1.i41: ; preds = %endif.5.i, %loopentry.1.i
- %indvar.i42 = phi i32 [ %indvar.next.i, %endif.5.i ], [ 0, %loopentry.1.i ] ; <i32> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.355.i = icmp eq i32 0, 3 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.355.i, label %endif.5.i, label %read_min.exit
-endif.5.i: ; preds = %no_exit.1.i41
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.34773.i = icmp sgt i32 0, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %indvar.next.i = add i32 %indvar.i42, 1 ; <i32> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.34773.i, label %no_exit.1.i41, label %loopexit.1.i.loopexit
-loopexit.1.i.loopexit: ; preds = %endif.5.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-loopexit.2.i44: ; preds = %loopentry.1.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-read_min.exit: ; preds = %no_exit.1.i41, %loopexit.0.i40, %entry
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.23 = icmp eq i32 0, 0 ; <i1> [#uses=1]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 %tmp.23, label %endif.1, label %then.1
-then.1: ; preds = %read_min.exit
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %endif.0.i, label %then.0.i
-then.0.i: ; preds = %then.1
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %endif.1.i, label %then.1.i
-endif.0.i: ; preds = %then.1
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %endif.1.i, label %then.1.i
-then.1.i: ; preds = %endif.0.i, %then.0.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %getfree.exit, label %then.2.i
-endif.1.i: ; preds = %endif.0.i, %then.0.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %getfree.exit, label %then.2.i
-then.2.i: ; preds = %endif.1.i, %then.1.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-getfree.exit: ; preds = %endif.1.i, %then.1.i
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-endif.1: ; preds = %read_min.exit
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.27.i = getelementptr i32* null, i32 0 ; <i32*> [#uses=0]
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %loopexit.0.i15, label %no_exit.0.i14
-no_exit.0.i14: ; preds = %endif.1
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-loopexit.0.i15: ; preds = %endif.1
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %primal_start_artificial.exit, label %no_exit.1.i16
-no_exit.1.i16: ; preds = %no_exit.1.i16, %loopexit.0.i15
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br i1 false, label %primal_start_artificial.exit, label %no_exit.1.i16
-primal_start_artificial.exit: ; preds = %no_exit.1.i16, %loopexit.0.i15
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- ret void
-}
diff --git a/test/Transforms/SimplifyCFG/dg.exp b/test/Transforms/SimplifyCFG/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/SimplifyCFG/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/SimplifyCFG/hoist-common-code.dbg.ll b/test/Transforms/SimplifyCFG/hoist-common-code.dbg.ll
deleted file mode 100644
index 6fbbb1b..0000000
--- a/test/Transforms/SimplifyCFG/hoist-common-code.dbg.ll
+++ /dev/null
@@ -1,33 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | not grep br
-
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"
-
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @bar(i32)
-
-define void @test(i1 %P, i32* %Q) {
- br i1 %P, label %T, label %F
-T: ; preds = %0
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- store i32 1, i32* %Q
- %A = load i32* %Q ; <i32> [#uses=1]
- call void @bar( i32 %A )
- ret void
-F: ; preds = %0
- store i32 1, i32* %Q
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %B = load i32* %Q ; <i32> [#uses=1]
- call void @bar( i32 %B )
- ret void
-}
-
diff --git a/test/Transforms/SimplifyCFG/lit.local.cfg b/test/Transforms/SimplifyCFG/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/SimplifyCFG/multiple-phis.ll b/test/Transforms/SimplifyCFG/multiple-phis.ll
new file mode 100644
index 0000000..7845423
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/multiple-phis.ll
@@ -0,0 +1,39 @@
+; RUN: opt -simplifycfg -S < %s | FileCheck %s
+
+; It's not worthwhile to if-convert one of the phi nodes and leave
+; the other behind, because that still requires a branch. If
+; SimplifyCFG if-converts one of the phis, it should do both.
+
+; CHECK: %div.high.addr.0 = select i1 %cmp1, i32 %div, i32 %high.addr.0
+; CHECK-NEXT: %low.0.add2 = select i1 %cmp1, i32 %low.0, i32 %add2
+; CHECK-NEXT: br label %while.cond
+
+define i32 @upper_bound(i32* %r, i32 %high, i32 %k) nounwind {
+entry:
+ br label %while.cond
+
+while.cond: ; preds = %if.then, %if.else, %entry
+ %high.addr.0 = phi i32 [ %high, %entry ], [ %div, %if.then ], [ %high.addr.0, %if.else ]
+ %low.0 = phi i32 [ 0, %entry ], [ %low.0, %if.then ], [ %add2, %if.else ]
+ %cmp = icmp ult i32 %low.0, %high.addr.0
+ br i1 %cmp, label %while.body, label %while.end
+
+while.body: ; preds = %while.cond
+ %add = add i32 %low.0, %high.addr.0
+ %div = udiv i32 %add, 2
+ %idxprom = zext i32 %div to i64
+ %arrayidx = getelementptr inbounds i32* %r, i64 %idxprom
+ %0 = load i32* %arrayidx
+ %cmp1 = icmp ult i32 %k, %0
+ br i1 %cmp1, label %if.then, label %if.else
+
+if.then: ; preds = %while.body
+ br label %while.cond
+
+if.else: ; preds = %while.body
+ %add2 = add i32 %div, 1
+ br label %while.cond
+
+while.end: ; preds = %while.cond
+ ret i32 %low.0
+}
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/test/Transforms/SimplifyCFG/preserve-branchweights.ll
new file mode 100644
index 0000000..c791785
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights.ll
@@ -0,0 +1,88 @@
+; RUN: opt -simplifycfg -S -o - < %s | FileCheck %s
+
+declare void @helper(i32)
+
+define void @test1(i1 %a, i1 %b) {
+; CHECK: @test1
+entry:
+ br i1 %a, label %Y, label %X, !prof !0
+; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !0
+
+X:
+ %c = or i1 %b, false
+ br i1 %c, label %Z, label %Y, !prof !1
+
+Y:
+ call void @helper(i32 0)
+ ret void
+
+Z:
+ call void @helper(i32 1)
+ ret void
+}
+
+define void @test2(i1 %a, i1 %b) {
+; CHECK: @test2
+entry:
+ br i1 %a, label %X, label %Y, !prof !1
+; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !1
+; CHECK-NOT: !prof
+
+X:
+ %c = or i1 %b, false
+ br i1 %c, label %Z, label %Y, !prof !2
+
+Y:
+ call void @helper(i32 0)
+ ret void
+
+Z:
+ call void @helper(i32 1)
+ ret void
+}
+
+define void @test3(i1 %a, i1 %b) {
+; CHECK: @test3
+; CHECK-NOT: !prof
+entry:
+ br i1 %a, label %X, label %Y, !prof !1
+
+X:
+ %c = or i1 %b, false
+ br i1 %c, label %Z, label %Y
+
+Y:
+ call void @helper(i32 0)
+ ret void
+
+Z:
+ call void @helper(i32 1)
+ ret void
+}
+
+define void @test4(i1 %a, i1 %b) {
+; CHECK: @test4
+; CHECK-NOT: !prof
+entry:
+ br i1 %a, label %X, label %Y
+
+X:
+ %c = or i1 %b, false
+ br i1 %c, label %Z, label %Y, !prof !1
+
+Y:
+ call void @helper(i32 0)
+ ret void
+
+Z:
+ call void @helper(i32 1)
+ ret void
+}
+
+!0 = metadata !{metadata !"branch_weights", i32 3, i32 5}
+!1 = metadata !{metadata !"branch_weights", i32 1, i32 1}
+!2 = metadata !{metadata !"branch_weights", i32 1, i32 2}
+
+; CHECK: !0 = metadata !{metadata !"branch_weights", i32 5, i32 11}
+; CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 5}
+; CHECK-NOT: !2
diff --git a/test/Transforms/SimplifyCFG/select-gep.ll b/test/Transforms/SimplifyCFG/select-gep.ll
index 009f05e..7654d02 100644
--- a/test/Transforms/SimplifyCFG/select-gep.ll
+++ b/test/Transforms/SimplifyCFG/select-gep.ll
@@ -35,6 +35,6 @@ if.end:
ret i8* %x.addr
; CHECK: @test2
-; CHECK: %x.addr = select i1 %cmp, i8* %incdec.ptr, i8* %y
-; CHECK: ret i8* %x.addr
+; CHECK: %incdec.ptr.y = select i1 %cmp, i8* %incdec.ptr, i8* %y
+; CHECK: ret i8* %incdec.ptr.y
}
diff --git a/test/Transforms/SimplifyCFG/switch-masked-bits.ll b/test/Transforms/SimplifyCFG/switch-masked-bits.ll
index fc83ec2..3b0c48b 100644
--- a/test/Transforms/SimplifyCFG/switch-masked-bits.ll
+++ b/test/Transforms/SimplifyCFG/switch-masked-bits.ll
@@ -15,8 +15,8 @@ c:
ret i32 5
; CHECK: @test1
; CHECK: %cond = icmp eq i32 %i, 24
-; CHECK: %merge = select i1 %cond, i32 5, i32 0
-; CHECK: ret i32 %merge
+; CHECK: %. = select i1 %cond, i32 5, i32 0
+; CHECK: ret i32 %.
}
diff --git a/test/Transforms/SimplifyCFG/switch-on-const-select.ll b/test/Transforms/SimplifyCFG/switch-on-const-select.ll
index 5494a65..673a62b 100644
--- a/test/Transforms/SimplifyCFG/switch-on-const-select.ll
+++ b/test/Transforms/SimplifyCFG/switch-on-const-select.ll
@@ -115,7 +115,7 @@ entry:
cont:
; CHECK: %lt = icmp slt i64 %x, %y
%lt = icmp slt i64 %x, %y
-; CHECK-NEXT: br i1 %lt, label %a, label %r
+; CHECK-NEXT: select i1 %lt, i32 -1, i32 1
%qux = select i1 %lt, i32 0, i32 2
switch i32 %qux, label %bees [
i32 0, label %a
diff --git a/test/Transforms/SimplifyCFG/switch_formation.dbg.ll b/test/Transforms/SimplifyCFG/switch_formation.dbg.ll
deleted file mode 100644
index 2723ec6..0000000
--- a/test/Transforms/SimplifyCFG/switch_formation.dbg.ll
+++ /dev/null
@@ -1,50 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | FileCheck %s
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"
-
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-define i1 @t({ i32, i32 }* %I) {
-; CHECK: @t
-; CHECK: %tmp.2.i.off = add i32 %tmp.2.i, -14
-; CHECK: %switch = icmp ult i32 %tmp.2.i.off, 6
-entry:
- %tmp.1.i = getelementptr { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1]
- %tmp.2.i = load i32* %tmp.1.i ; <i32> [#uses=6]
- %tmp.2 = icmp eq i32 %tmp.2.i, 14 ; <i1> [#uses=1]
- br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0
-shortcirc_next.0: ; preds = %entry
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.6 = icmp eq i32 %tmp.2.i, 15 ; <i1> [#uses=1]
- br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1
-shortcirc_next.1: ; preds = %shortcirc_next.0
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.11 = icmp eq i32 %tmp.2.i, 16 ; <i1> [#uses=1]
- br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2
-shortcirc_next.2: ; preds = %shortcirc_next.1
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.16 = icmp eq i32 %tmp.2.i, 17 ; <i1> [#uses=1]
- br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3
-shortcirc_next.3: ; preds = %shortcirc_next.2
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.21 = icmp eq i32 %tmp.2.i, 18 ; <i1> [#uses=1]
- br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4
-shortcirc_next.4: ; preds = %shortcirc_next.3
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp.26 = icmp eq i32 %tmp.2.i, 19 ; <i1> [#uses=1]
- br label %UnifiedReturnBlock
-shortcirc_done.4: ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry
- br label %UnifiedReturnBlock
-UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4
- %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1]
- ret i1 %UnifiedRetVal
-}
-
diff --git a/test/Transforms/SimplifyCFG/switch_switch_fold_dbginfo.ll b/test/Transforms/SimplifyCFG/switch_switch_fold_dbginfo.ll
deleted file mode 100644
index 343e169..0000000
--- a/test/Transforms/SimplifyCFG/switch_switch_fold_dbginfo.ll
+++ /dev/null
@@ -1,116 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | \
-; RUN: not grep " switch"
-
-; ModuleID = '<stdin>'
-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:32:32"
-target triple = "i386-pc-linux-gnu"
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i32 }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str = internal constant [10 x i8] c"swithh2.c\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1]
-@.str1 = internal constant [38 x i8] c"/developer/home2/zsth/test/debug/tmp/\00", section "llvm.metadata" ; <[38 x i8]*> [#uses=1]
-@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5641) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([10 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([38 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null, i32 -1 }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
-@llvm.dbg.array = internal constant [2 x { }*] [{ }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*)], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1]
-@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*), i32 0 }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
-@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
-@.str4 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@.str5 = internal constant [2 x i8] c"x\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
-@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=0]
-
-define i32 @foo(i32 %x) nounwind {
-entry:
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- switch i32 %x, label %bb4 [
- i32 1, label %bb
- i32 2, label %bb1
- i32 3, label %bb2
- i32 4, label %bb3
- ]
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb
-
-bb: ; preds = %0, %entry
- call void @llvm.dbg.stoppoint(i32 3, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 3, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb1
-
-bb1: ; preds = %1, %entry
- call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb2
-
-bb2: ; preds = %2, %entry
- call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb3
-
-bb3: ; preds = %3, %entry
- call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 6, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb4
-
-bb4: ; preds = %4, %entry
- call void @llvm.dbg.stoppoint(i32 10, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- switch i32 %x, label %bb7 [
- i32 5, label %bb5
- i32 6, label %bb6
- ]
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 10, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb5
-
-bb5: ; preds = %5, %bb4
- call void @llvm.dbg.stoppoint(i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb6
-
-bb6: ; preds = %6, %bb4
- call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
- ; No predecessors!
- call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb7
-
-bb7: ; preds = %7, %bb4
- call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %bb8
-
-bb8: ; preds = %bb7, %bb6, %bb5, %bb3, %bb2, %bb1, %bb
- %.0 = phi i32 [ 4, %bb3 ], [ 3, %bb2 ], [ 2, %bb1 ], [ 1, %bb ], [ 6, %bb6 ], [ 5, %bb5 ], [ 0, %bb7 ] ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- br label %return
-
-return: ; preds = %bb8
- call void @llvm.dbg.stoppoint(i32 13, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- ret i32 %.0
-}
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
diff --git a/test/Transforms/SimplifyCFG/two-entry-phi-return.dbg.ll b/test/Transforms/SimplifyCFG/two-entry-phi-return.dbg.ll
deleted file mode 100644
index 01041eb..0000000
--- a/test/Transforms/SimplifyCFG/two-entry-phi-return.dbg.ll
+++ /dev/null
@@ -1,28 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | not grep br
-
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-
-@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"
-
-@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
-@.str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
-@.str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
-@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-define i1 @qux(i8* %m, i8* %n, i8* %o, i8* %p) nounwind {
-entry:
- %tmp7 = icmp eq i8* %m, %n
- br i1 %tmp7, label %bb, label %UnifiedReturnBlock
-
-bb:
-call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %tmp15 = icmp eq i8* %o, %p
- br label %UnifiedReturnBlock
-
-UnifiedReturnBlock:
- %result = phi i1 [ 0, %entry ], [ %tmp15, %bb ]
- ret i1 %result
-}
diff --git a/test/Transforms/SimplifyCFG/unreachable-blocks.ll b/test/Transforms/SimplifyCFG/unreachable-blocks.ll
new file mode 100644
index 0000000..1df0eab
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/unreachable-blocks.ll
@@ -0,0 +1,28 @@
+; RUN: opt -simplifycfg < %s -disable-output
+
+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-pc-linux-gnu"
+
+; PR11825
+define void @test1() {
+entry:
+ br label %return
+
+while_block: ; preds = %and_if_cont2, %and_if_cont
+ %newlen = sub i32 %newlen, 1
+ %newptr = getelementptr i8* %newptr, i64 1
+ %test = icmp sgt i32 %newlen, 0
+ br i1 %test, label %and_if1, label %and_if_cont2
+
+and_if1: ; preds = %while_block
+ %char = load i8* %newptr
+ %test2 = icmp ule i8 %char, 32
+ br label %and_if_cont2
+
+and_if_cont2: ; preds = %and_if1, %while_block
+ %a18 = phi i1 [ %test, %while_block ], [ %test2, %and_if1 ]
+ br i1 %a18, label %while_block, label %return
+
+return: ; preds = %and_if_cont2, %and_if_cont
+ ret void
+}
diff --git a/test/Transforms/SimplifyLibCalls/PR7357.ll b/test/Transforms/SimplifyLibCalls/PR7357.ll
index 6d5c1d5..3529a9c 100644
--- a/test/Transforms/SimplifyLibCalls/PR7357.ll
+++ b/test/Transforms/SimplifyLibCalls/PR7357.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -default-data-layout="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-v64:64:64-v128:128:128-a0:0:64-n32" -simplify-libcalls -S | FileCheck %s
+; RUN: opt < %s "-default-data-layout=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-v64:64:64-v128:128:128-a0:0:64-n32" -simplify-libcalls -S | FileCheck %s
@.str1 = private constant [11 x i8] c"(){};[]&|:\00", align 4
; check that simplify libcalls will not replace a call with one calling
diff --git a/test/Transforms/SimplifyLibCalls/Printf.ll b/test/Transforms/SimplifyLibCalls/Printf.ll
index caea311..489c993 100644
--- a/test/Transforms/SimplifyLibCalls/Printf.ll
+++ b/test/Transforms/SimplifyLibCalls/Printf.ll
@@ -1,9 +1,10 @@
-; RUN: opt < %s -simplify-libcalls -S -o %t
-; RUN: FileCheck < %t %s
+; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
@str = internal constant [13 x i8] c"hello world\0A\00" ; <[13 x i8]*> [#uses=1]
@str1 = internal constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=1]
+; CHECK: private unnamed_addr constant [12 x i8] c"hello world\00"
+
declare i32 @printf(i8*, ...)
; CHECK: define void @f0
diff --git a/test/Transforms/SimplifyLibCalls/StrLen.ll b/test/Transforms/SimplifyLibCalls/StrLen.ll
index 45b349d..acd8aaf 100644
--- a/test/Transforms/SimplifyLibCalls/StrLen.ll
+++ b/test/Transforms/SimplifyLibCalls/StrLen.ll
@@ -6,6 +6,7 @@ target datalayout = "e-p:32:32"
@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=3]
@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=3]
@null_hello = constant [7 x i8] c"\00hello\00" ; <[7 x i8]*> [#uses=1]
+@nullstring = constant i8 0
declare i32 @strlen(i8*)
@@ -54,3 +55,8 @@ define i1 @test7() {
%ne_null = icmp ne i32 %null_l, 0 ; <i1> [#uses=1]
ret i1 %ne_null
}
+
+define i32 @test8() {
+ %len = tail call i32 @strlen(i8* @nullstring) nounwind
+ ret i32 %len
+}
diff --git a/test/Transforms/SimplifyLibCalls/cos.ll b/test/Transforms/SimplifyLibCalls/cos.ll
new file mode 100644
index 0000000..6a8ce8c
--- /dev/null
+++ b/test/Transforms/SimplifyLibCalls/cos.ll
@@ -0,0 +1,14 @@
+; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define double @foo(double %d) nounwind readnone {
+; CHECK: @foo
+ %1 = fsub double -0.000000e+00, %d
+ %2 = call double @cos(double %1) nounwind readnone
+; CHECK: call double @cos(double %d)
+ ret double %2
+}
+
+declare double @cos(double) nounwind readnone
diff --git a/test/Transforms/SimplifyLibCalls/dg.exp b/test/Transforms/SimplifyLibCalls/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/SimplifyLibCalls/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/SimplifyLibCalls/fwrite.ll b/test/Transforms/SimplifyLibCalls/fwrite.ll
new file mode 100644
index 0000000..f0f3dca
--- /dev/null
+++ b/test/Transforms/SimplifyLibCalls/fwrite.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+
+%FILE = type { i32 }
+
+@.str = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+
+define i64 @foo(%FILE* %f) {
+; CHECK: %retval = call i64 @fwrite
+ %retval = call i64 @fwrite(i8* getelementptr inbounds ([1 x i8]* @.str, i64 0, i64 0), i64 1, i64 1, %FILE* %f)
+ ret i64 %retval
+}
+
+declare i64 @fwrite(i8*, i64, i64, %FILE *)
diff --git a/test/Transforms/SimplifyLibCalls/lit.local.cfg b/test/Transforms/SimplifyLibCalls/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/SimplifyLibCalls/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/SimplifyLibCalls/osx-names.ll b/test/Transforms/SimplifyLibCalls/osx-names.ll
new file mode 100644
index 0000000..e321d1d
--- /dev/null
+++ b/test/Transforms/SimplifyLibCalls/osx-names.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+; <rdar://problem/9815881>
+; On OSX x86-32, fwrite and fputs aren't called fwrite and fputs.
+; Make sure we use the correct names.
+
+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-S128"
+target triple = "i386-apple-macosx10.7.2"
+
+%struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+%struct.__sbuf = type { i8*, i32 }
+%struct.__sFILEX = type opaque
+
+@.str = private unnamed_addr constant [13 x i8] c"Hello world\0A\00", align 1
+@.str2 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
+
+define void @test1(%struct.__sFILE* %stream) nounwind {
+; CHECK: define void @test1
+; CHECK: call i32 @"fwrite$UNIX2003"
+ %call = tail call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %stream, i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) nounwind
+ ret void
+}
+
+define void @test2(%struct.__sFILE* %stream, i8* %str) nounwind ssp {
+; CHECK: define void @test2
+; CHECK: call i32 @"fputs$UNIX2003"
+ %call = tail call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %stream, i8* getelementptr inbounds ([3 x i8]* @.str2, i32 0, i32 0), i8* %str) nounwind
+ ret void
+}
+
+declare i32 @fprintf(%struct.__sFILE*, i8*, ...) nounwind
diff --git a/test/Transforms/Sink/basic.ll b/test/Transforms/Sink/basic.ll
index 2343372..4c531d8 100644
--- a/test/Transforms/Sink/basic.ll
+++ b/test/Transforms/Sink/basic.ll
@@ -21,7 +21,7 @@ false:
ret i32 0
}
-; But don't sink volatile loads...
+; But don't sink load volatiles...
; CHECK: @foo2
; CHECK: load volatile
diff --git a/test/Transforms/Sink/dg.exp b/test/Transforms/Sink/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/Sink/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/Sink/lit.local.cfg b/test/Transforms/Sink/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/Sink/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/StripSymbols/dg.exp b/test/Transforms/StripSymbols/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/StripSymbols/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/StripSymbols/lit.local.cfg b/test/Transforms/StripSymbols/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/StripSymbols/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/TailCallElim/dg.exp b/test/Transforms/TailCallElim/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/TailCallElim/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/TailCallElim/dont_reorder_load.ll b/test/Transforms/TailCallElim/dont_reorder_load.ll
index 899e115..a29b72e 100644
--- a/test/Transforms/TailCallElim/dont_reorder_load.ll
+++ b/test/Transforms/TailCallElim/dont_reorder_load.ll
@@ -46,7 +46,7 @@ else: ; preds = %entry
}
; This load can't be safely moved above the call because that would change the
-; order in which the volatile loads are performed.
+; order in which the load volatiles are performed.
define fastcc i32 @no_tailrecelim_3(i32* %a_arg, i32 %a_len_arg, i32 %start_arg) nounwind {
entry:
%tmp2 = icmp sge i32 %start_arg, %a_len_arg ; <i1> [#uses=1]
@@ -58,7 +58,7 @@ if: ; preds = %entry
else: ; preds = %entry
%tmp7 = add i32 %start_arg, 1 ; <i32> [#uses=1]
%tmp8 = call fastcc i32 @no_tailrecelim_3(i32* %a_arg, i32 %a_len_arg, i32 %tmp7) ; <i32> [#uses=1]
- %tmp9 = volatile load i32* %a_arg ; <i32> [#uses=1]
+ %tmp9 = load volatile i32* %a_arg ; <i32> [#uses=1]
%tmp10 = add i32 %tmp9, %tmp8 ; <i32> [#uses=1]
ret i32 %tmp10
}
diff --git a/test/Transforms/TailCallElim/lit.local.cfg b/test/Transforms/TailCallElim/lit.local.cfg
new file mode 100644
index 0000000..19eebc0
--- /dev/null
+++ b/test/Transforms/TailCallElim/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll', '.c', '.cpp']
diff --git a/test/Transforms/TailCallElim/setjmp.ll b/test/Transforms/TailCallElim/setjmp.ll
index 7ef9cb3..4ce6ac7 100644
--- a/test/Transforms/TailCallElim/setjmp.ll
+++ b/test/Transforms/TailCallElim/setjmp.ll
@@ -15,7 +15,7 @@ bb:
ret void
}
-declare i32 @setjmp(i32*)
+declare i32 @setjmp(i32*) returns_twice
; CHECK: foo2
; CHECK-NOT: tail call void @bar()
diff --git a/test/Transforms/TailDup/X86/dg.exp b/test/Transforms/TailDup/X86/dg.exp
deleted file mode 100644
index 7b7bd4e..0000000
--- a/test/Transforms/TailDup/X86/dg.exp
+++ /dev/null
@@ -1,5 +0,0 @@
-load_lib llvm.exp
-
-if { [llvm_supports_target X86] } {
- RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
-}
diff --git a/test/Transforms/TailDup/X86/lit.local.cfg b/test/Transforms/TailDup/X86/lit.local.cfg
new file mode 100644
index 0000000..da2db5a
--- /dev/null
+++ b/test/Transforms/TailDup/X86/lit.local.cfg
@@ -0,0 +1,6 @@
+config.suffixes = ['.ll']
+
+targets = set(config.root.targets_to_build.split())
+if not 'X86' in targets:
+ config.unsupported = True
+
diff --git a/test/Transforms/TailDup/dg.exp b/test/Transforms/TailDup/dg.exp
deleted file mode 100644
index f200589..0000000
--- a/test/Transforms/TailDup/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/TailDup/lit.local.cfg b/test/Transforms/TailDup/lit.local.cfg
new file mode 100644
index 0000000..18c604a
--- /dev/null
+++ b/test/Transforms/TailDup/lit.local.cfg
@@ -0,0 +1,5 @@
+config.suffixes = ['.ll', '.c', '.cpp']
+
+targets = set(config.root.targets_to_build.split())
+if not 'X86' in targets:
+ config.unsupported = True
OpenPOWER on IntegriCloud