aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/AddDiscriminators/basic.ll34
-rw-r--r--test/Transforms/AddDiscriminators/first-only.ll58
-rw-r--r--test/Transforms/AddDiscriminators/multiple.ll34
-rw-r--r--test/Transforms/AddDiscriminators/no-discriminators.ll44
-rw-r--r--test/Transforms/ArgumentPromotion/control-flow2.ll5
-rw-r--r--test/Transforms/ArgumentPromotion/dbg.ll10
-rw-r--r--test/Transforms/ArgumentPromotion/reserve-tbaa.ll26
-rw-r--r--test/Transforms/BBVectorize/loop1.ll2
-rw-r--r--test/Transforms/BBVectorize/metadata.ll8
-rw-r--r--test/Transforms/BDCE/basic.ll348
-rw-r--r--test/Transforms/BDCE/dce-pure.ll33
-rw-r--r--test/Transforms/BDCE/order.ll37
-rw-r--r--test/Transforms/CodeGenPrepare/statepoint-relocate.ll88
-rw-r--r--test/Transforms/ConstProp/InsertElement.ll12
-rw-r--r--test/Transforms/ConstProp/insertvalue.ll9
-rw-r--r--test/Transforms/CorrelatedValuePropagation/icmp.ll63
-rw-r--r--test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll80
-rw-r--r--test/Transforms/DeadArgElim/aggregates.ll162
-rw-r--r--test/Transforms/DeadArgElim/dbginfo.ll44
-rw-r--r--test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll6
-rw-r--r--test/Transforms/DeadStoreElimination/inst-limits.ll30
-rw-r--r--test/Transforms/DebugIR/crash.ll42
-rw-r--r--test/Transforms/DebugIR/exception.ll127
-rw-r--r--test/Transforms/DebugIR/function.ll51
-rw-r--r--test/Transforms/DebugIR/simple-addrspace.ll11
-rw-r--r--test/Transforms/DebugIR/simple.ll25
-rw-r--r--test/Transforms/DebugIR/struct.ll24
-rw-r--r--test/Transforms/DebugIR/vector.ll93
-rw-r--r--test/Transforms/EarlyCSE/AArch64/intrinsics.ll232
-rw-r--r--test/Transforms/EarlyCSE/AArch64/lit.local.cfg5
-rw-r--r--test/Transforms/EarlyCSE/basic.ll12
-rw-r--r--test/Transforms/GCOVProfiling/function-numbering.ll30
-rw-r--r--test/Transforms/GCOVProfiling/global-ctor.ll34
-rw-r--r--test/Transforms/GCOVProfiling/linezero.ll100
-rw-r--r--test/Transforms/GCOVProfiling/linkagename.ll22
-rw-r--r--test/Transforms/GCOVProfiling/return-block.ll66
-rw-r--r--test/Transforms/GCOVProfiling/version.ll24
-rw-r--r--test/Transforms/GVN/cond_br2.ll12
-rw-r--r--test/Transforms/GVN/condprop.ll48
-rw-r--r--test/Transforms/GVN/edge.ll110
-rw-r--r--test/Transforms/GVN/fpmath.ll4
-rw-r--r--test/Transforms/GVN/invariant-load.ll40
-rw-r--r--test/Transforms/GVN/load-from-unreachable-predecessor.ll20
-rw-r--r--test/Transforms/GVN/load-pre-nonlocal.ll12
-rw-r--r--test/Transforms/GVN/noalias.ll6
-rw-r--r--test/Transforms/GVN/pre-gep-load.ll49
-rw-r--r--test/Transforms/GVN/pre-no-cost-phi.ll31
-rw-r--r--test/Transforms/GVN/preserve-tbaa.ll8
-rw-r--r--test/Transforms/GVN/range.ll32
-rw-r--r--test/Transforms/GVN/tbaa.ll69
-rw-r--r--test/Transforms/GVN/volatile.ll157
-rw-r--r--test/Transforms/GlobalDCE/pr20981.ll4
-rw-r--r--test/Transforms/GlobalOpt/2009-03-05-dbg.ll48
-rw-r--r--test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll2
-rw-r--r--test/Transforms/GlobalOpt/metadata.ll16
-rw-r--r--test/Transforms/GlobalOpt/pr21191.ll8
-rw-r--r--test/Transforms/GlobalOpt/preserve-comdats.ll6
-rw-r--r--test/Transforms/IRCE/bug-mismatched-types.ll66
-rw-r--r--test/Transforms/IRCE/decrementing-loop.ll43
-rw-r--r--test/Transforms/IRCE/low-becount.ll32
-rw-r--r--test/Transforms/IRCE/multiple-access-no-preloop.ll66
-rw-r--r--test/Transforms/IRCE/not-likely-taken.ll40
-rw-r--r--test/Transforms/IRCE/single-access-no-preloop.ll116
-rw-r--r--test/Transforms/IRCE/single-access-with-preloop.ll71
-rw-r--r--test/Transforms/IRCE/unhandled.ll37
-rw-r--r--test/Transforms/IRCE/with-parent-loops.ll345
-rw-r--r--test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll2
-rw-r--r--test/Transforms/IndVarSimplify/backedge-on-min-max.ll453
-rw-r--r--test/Transforms/IndVarSimplify/overflowcheck.ll2
-rw-r--r--test/Transforms/IndVarSimplify/pr20680.ll4
-rw-r--r--test/Transforms/IndVarSimplify/pr22222.ll46
-rw-r--r--test/Transforms/IndVarSimplify/sharpen-range.ll2
-rw-r--r--test/Transforms/IndVarSimplify/strengthen-overflow.ll108
-rw-r--r--test/Transforms/IndVarSimplify/use-range-metadata.ll2
-rw-r--r--test/Transforms/Inline/alloca-dbgdeclare.ll141
-rw-r--r--test/Transforms/Inline/debug-info-duplicate-calls.ll121
-rw-r--r--test/Transforms/Inline/debug-invoke.ll14
-rw-r--r--test/Transforms/Inline/ignore-debug-info.ll12
-rw-r--r--test/Transforms/Inline/inline-fast-math-flags.ll34
-rw-r--r--test/Transforms/Inline/inline-fp.ll136
-rw-r--r--test/Transforms/Inline/inline-indirect.ll19
-rw-r--r--test/Transforms/Inline/inline-vla.ll2
-rw-r--r--test/Transforms/Inline/inline_dbg_declare.ll97
-rw-r--r--test/Transforms/Inline/noalias-calls.ll12
-rw-r--r--test/Transforms/Inline/noalias-cs.ll68
-rw-r--r--test/Transforms/Inline/noalias.ll18
-rw-r--r--test/Transforms/Inline/noalias2.ll42
-rw-r--r--test/Transforms/Inline/optimization-remarks.ll2
-rw-r--r--test/Transforms/Inline/pr21206.ll8
-rw-r--r--test/Transforms/InstCombine/2008-05-23-CompareFold.ll5
-rw-r--r--test/Transforms/InstCombine/2008-11-08-FCmp.ll7
-rw-r--r--test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll3
-rw-r--r--test/Transforms/InstCombine/AddOverFlow.ll4
-rw-r--r--test/Transforms/InstCombine/LandingPadClauses.ll52
-rw-r--r--test/Transforms/InstCombine/add2.ll10
-rw-r--r--test/Transforms/InstCombine/addnegneg.ll1
-rw-r--r--test/Transforms/InstCombine/alias-recursion.ll24
-rw-r--r--test/Transforms/InstCombine/aligned-altivec.ll131
-rw-r--r--test/Transforms/InstCombine/aligned-qpx.ll162
-rw-r--r--test/Transforms/InstCombine/and-compare.ll8
-rw-r--r--test/Transforms/InstCombine/and-xor-merge.ll11
-rw-r--r--test/Transforms/InstCombine/apint-call-cast-target.ll9
-rw-r--r--test/Transforms/InstCombine/bitcast-alias-function.ll15
-rw-r--r--test/Transforms/InstCombine/bitcast-store.ll10
-rw-r--r--test/Transforms/InstCombine/bswap-fold.ll184
-rw-r--r--test/Transforms/InstCombine/call-cast-target.ll49
-rw-r--r--test/Transforms/InstCombine/canonicalize_branch.ll8
-rw-r--r--test/Transforms/InstCombine/cast-int-fcmp-eq-0.ll454
-rw-r--r--test/Transforms/InstCombine/cast.ll29
-rw-r--r--test/Transforms/InstCombine/cast_ptr.ll23
-rw-r--r--test/Transforms/InstCombine/debug-line.ll22
-rw-r--r--test/Transforms/InstCombine/debuginfo.ll58
-rw-r--r--test/Transforms/InstCombine/div.ll43
-rw-r--r--test/Transforms/InstCombine/fast-math.ll10
-rw-r--r--test/Transforms/InstCombine/fcmp.ll82
-rw-r--r--test/Transforms/InstCombine/float-shrink-compare.ll38
-rw-r--r--test/Transforms/InstCombine/fpcast.ll12
-rw-r--r--test/Transforms/InstCombine/gc.relocate.ll20
-rw-r--r--test/Transforms/InstCombine/gep-sext.ll61
-rw-r--r--test/Transforms/InstCombine/gepphigep.ll44
-rw-r--r--test/Transforms/InstCombine/getelementptr.ll4
-rw-r--r--test/Transforms/InstCombine/icmp-range.ll8
-rw-r--r--test/Transforms/InstCombine/icmp.ll51
-rw-r--r--test/Transforms/InstCombine/intrinsics.ll122
-rw-r--r--test/Transforms/InstCombine/load-cmp.ll8
-rw-r--r--test/Transforms/InstCombine/load.ll53
-rw-r--r--test/Transforms/InstCombine/loadstore-metadata.ll39
-rw-r--r--test/Transforms/InstCombine/malloc-free-delete.ll27
-rw-r--r--test/Transforms/InstCombine/max-of-nots.ll68
-rw-r--r--test/Transforms/InstCombine/mem-gep-zidx.ll48
-rw-r--r--test/Transforms/InstCombine/memcpy_chk-1.ll49
-rw-r--r--test/Transforms/InstCombine/memmove_chk-1.ll36
-rw-r--r--test/Transforms/InstCombine/memset_chk-1.ll45
-rw-r--r--test/Transforms/InstCombine/minnum.ll18
-rw-r--r--test/Transforms/InstCombine/mul.ll91
-rw-r--r--test/Transforms/InstCombine/narrow-switch.ll30
-rw-r--r--test/Transforms/InstCombine/not-fcmp.ll7
-rw-r--r--test/Transforms/InstCombine/not.ll8
-rw-r--r--test/Transforms/InstCombine/or-xor.ll36
-rw-r--r--test/Transforms/InstCombine/or.ll10
-rw-r--r--test/Transforms/InstCombine/pr12251.ll2
-rw-r--r--test/Transforms/InstCombine/pr12338.ll2
-rw-r--r--test/Transforms/InstCombine/pr21199.ll25
-rw-r--r--test/Transforms/InstCombine/pr21210.ll50
-rw-r--r--test/Transforms/InstCombine/pr21651.ll20
-rw-r--r--test/Transforms/InstCombine/pr21891.ll18
-rw-r--r--test/Transforms/InstCombine/range-check.ll159
-rw-r--r--test/Transforms/InstCombine/select-cmp-br.ll155
-rw-r--r--test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll327
-rw-r--r--test/Transforms/InstCombine/select.ll257
-rw-r--r--test/Transforms/InstCombine/shift.ll58
-rw-r--r--test/Transforms/InstCombine/signext.ll27
-rw-r--r--test/Transforms/InstCombine/sitofp.ll169
-rw-r--r--test/Transforms/InstCombine/statepoint.ll52
-rw-r--r--test/Transforms/InstCombine/store.ll10
-rw-r--r--test/Transforms/InstCombine/stpcpy_chk-1.ll55
-rw-r--r--test/Transforms/InstCombine/strcpy_chk-1.ll59
-rw-r--r--test/Transforms/InstCombine/strncpy_chk-1.ll45
-rw-r--r--test/Transforms/InstCombine/struct-assign-tbaa.ll20
-rw-r--r--test/Transforms/InstCombine/type_pun.ll137
-rw-r--r--test/Transforms/InstCombine/unordered-fcmp-select.ll125
-rw-r--r--test/Transforms/InstCombine/vec_demanded_elts.ll27
-rw-r--r--test/Transforms/InstCombine/xor.ll86
-rw-r--r--test/Transforms/InstMerge/st_sink_barrier_call.ll43
-rw-r--r--test/Transforms/InstMerge/st_sink_bugfix_22613.ll106
-rw-r--r--test/Transforms/InstMerge/st_sink_no_barrier_call.ll45
-rw-r--r--test/Transforms/InstMerge/st_sink_no_barrier_load.ll43
-rw-r--r--test/Transforms/InstMerge/st_sink_no_barrier_store.ll42
-rw-r--r--test/Transforms/InstMerge/st_sink_two_stores.ll47
-rw-r--r--test/Transforms/InstMerge/st_sink_with_barrier.ll42
-rw-r--r--test/Transforms/InstSimplify/AndOrXor.ll55
-rw-r--r--test/Transforms/InstSimplify/compare.ll64
-rw-r--r--test/Transforms/InstSimplify/fast-math.ll9
-rw-r--r--test/Transforms/InstSimplify/floating-point-arithmetic.ll26
-rw-r--r--test/Transforms/InstSimplify/floating-point-compare.ll60
-rw-r--r--test/Transforms/InstSimplify/load.ll19
-rw-r--r--test/Transforms/InstSimplify/noalias-ptr.ll259
-rw-r--r--test/Transforms/InstSimplify/select.ll161
-rw-r--r--test/Transforms/InstSimplify/undef.ll105
-rw-r--r--test/Transforms/JumpThreading/conservative-lvi.ll58
-rw-r--r--test/Transforms/JumpThreading/phi-eq.ll2
-rw-r--r--test/Transforms/JumpThreading/pr22086.ll28
-rw-r--r--test/Transforms/JumpThreading/thread-loads.ll8
-rw-r--r--test/Transforms/LCSSA/indirectbr.ll40
-rw-r--r--test/Transforms/LCSSA/unreachable-use.ll4
-rw-r--r--test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll14
-rw-r--r--test/Transforms/LICM/constexpr.ll46
-rw-r--r--test/Transforms/LICM/debug-value.ll56
-rw-r--r--test/Transforms/LICM/hoist-invariant-load.ll2
-rw-r--r--test/Transforms/LICM/preheader-safe.ll69
-rw-r--r--test/Transforms/LICM/promote-order.ll10
-rw-r--r--test/Transforms/LICM/scalar_promote.ll12
-rw-r--r--test/Transforms/LICM/sinking.ll78
-rw-r--r--test/Transforms/LoopIdiom/debug-line.ll44
-rw-r--r--test/Transforms/LoopReroll/basic.ll254
-rw-r--r--test/Transforms/LoopReroll/reduction.ll36
-rw-r--r--test/Transforms/LoopRotate/crash.ll18
-rw-r--r--test/Transforms/LoopRotate/dbgvalue.ll52
-rw-r--r--test/Transforms/LoopRotate/pr22337.ll24
-rw-r--r--test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/AArch64/lsr-memset.ll6
-rw-r--r--test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/count-to-zero.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/pr12018.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/pr18165.ll18
-rw-r--r--test/Transforms/LoopStrengthReduce/uglygep.ll2
-rw-r--r--test/Transforms/LoopUnroll/PowerPC/p7-unrolling.ll99
-rw-r--r--test/Transforms/LoopUnroll/full-unroll-heuristics.ll62
-rw-r--r--test/Transforms/LoopUnroll/partial-unroll-optsize.ll19
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop.ll8
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop1.ll2
-rw-r--r--test/Transforms/LoopUnroll/runtime-loop2.ll2
-rw-r--r--test/Transforms/LoopUnroll/tripcount-overflow.ll29
-rw-r--r--test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll42
-rw-r--r--test/Transforms/LoopUnroll/unroll-pragmas.ll26
-rw-r--r--test/Transforms/LoopVectorize/AArch64/arbitrary-induction-step.ll150
-rw-r--r--test/Transforms/LoopVectorize/PowerPC/small-loop-rdx.ll47
-rw-r--r--test/Transforms/LoopVectorize/X86/already-vectorized.ll8
-rw-r--r--test/Transforms/LoopVectorize/X86/illegal-parallel-loop-uniform-write.ll6
-rw-r--r--test/Transforms/LoopVectorize/X86/masked_load_store.ll502
-rw-r--r--test/Transforms/LoopVectorize/X86/metadata-enable.ll8
-rw-r--r--test/Transforms/LoopVectorize/X86/parallel-loops-after-reg2mem.ll2
-rw-r--r--test/Transforms/LoopVectorize/X86/parallel-loops.ll10
-rw-r--r--test/Transforms/LoopVectorize/X86/small-size.ll2
-rw-r--r--test/Transforms/LoopVectorize/X86/vect.omp.force.ll6
-rw-r--r--test/Transforms/LoopVectorize/X86/vect.omp.force.small-tc.ll6
-rw-r--r--test/Transforms/LoopVectorize/X86/vector-scalar-select-cost.ll4
-rw-r--r--test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll74
-rw-r--r--test/Transforms/LoopVectorize/X86/vectorization-remarks.ll46
-rw-r--r--test/Transforms/LoopVectorize/conditional-assignment.ll40
-rw-r--r--test/Transforms/LoopVectorize/control-flow.ll42
-rw-r--r--test/Transforms/LoopVectorize/dbg.value.ll50
-rw-r--r--test/Transforms/LoopVectorize/debugloc.ll60
-rw-r--r--test/Transforms/LoopVectorize/duplicated-metadata.ll6
-rw-r--r--test/Transforms/LoopVectorize/gcc-examples.ll3
-rw-r--r--test/Transforms/LoopVectorize/if-conversion-edgemasks.ll5
-rw-r--r--test/Transforms/LoopVectorize/if-conversion.ll4
-rw-r--r--test/Transforms/LoopVectorize/incorrect-dom-info.ll2
-rw-r--r--test/Transforms/LoopVectorize/loop-form.ll31
-rw-r--r--test/Transforms/LoopVectorize/loop-vect-memdep.ll26
-rw-r--r--test/Transforms/LoopVectorize/metadata-unroll.ll4
-rw-r--r--test/Transforms/LoopVectorize/metadata-width.ll4
-rw-r--r--test/Transforms/LoopVectorize/metadata.ll20
-rw-r--r--test/Transforms/LoopVectorize/minmax_reduction.ll16
-rw-r--r--test/Transforms/LoopVectorize/no_array_bounds.ll54
-rw-r--r--test/Transforms/LoopVectorize/no_switch.ll50
-rw-r--r--test/Transforms/LoopVectorize/reverse_induction.ll4
-rw-r--r--test/Transforms/LoopVectorize/runtime-check-address-space.ll154
-rw-r--r--test/Transforms/LoopVectorize/runtime-check-readonly-address-space.ll120
-rw-r--r--test/Transforms/LoopVectorize/scev-exitlim-crash.ll12
-rw-r--r--test/Transforms/LoopVectorize/tbaa-nodep.ll12
-rw-r--r--test/Transforms/LoopVectorize/vect.omp.persistence.ll8
-rw-r--r--test/Transforms/LoopVectorize/vect.stats.ll58
-rw-r--r--test/Transforms/LoopVectorize/vectorize-once.ll12
-rw-r--r--test/Transforms/LoopVectorize/version-mem-access.ll12
-rw-r--r--test/Transforms/LowerBitSets/constant.ll34
-rw-r--r--test/Transforms/LowerBitSets/layout.ll35
-rw-r--r--test/Transforms/LowerBitSets/simple.ll122
-rw-r--r--test/Transforms/LowerBitSets/single-offset.ll40
-rw-r--r--test/Transforms/LowerExpectIntrinsic/basic.ll9
-rw-r--r--test/Transforms/LowerSwitch/2014-06-11-SwitchDefaultUnreachableOpt.ll7
-rw-r--r--test/Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll110
-rw-r--r--test/Transforms/Mem2Reg/ConvertDebugInfo.ll38
-rw-r--r--test/Transforms/Mem2Reg/ConvertDebugInfo2.ll54
-rw-r--r--test/Transforms/MemCpyOpt/callslot_aa.ll22
-rw-r--r--test/Transforms/MemCpyOpt/form-memset.ll15
-rw-r--r--test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll4
-rw-r--r--test/Transforms/MergeFunc/ranges.ll4
-rw-r--r--test/Transforms/ObjCARC/allocas.ll2
-rw-r--r--test/Transforms/ObjCARC/arc-annotations.ll12
-rw-r--r--test/Transforms/ObjCARC/basic.ll10
-rw-r--r--test/Transforms/ObjCARC/cfg-hazards.ll2
-rw-r--r--test/Transforms/ObjCARC/contract-marker.ll2
-rw-r--r--test/Transforms/ObjCARC/contract-storestrong.ll98
-rw-r--r--test/Transforms/ObjCARC/contract-testcases.ll2
-rw-r--r--test/Transforms/ObjCARC/empty-block.ll2
-rw-r--r--test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll126
-rw-r--r--test/Transforms/ObjCARC/escape.ll2
-rw-r--r--test/Transforms/ObjCARC/intrinsic-use.ll2
-rw-r--r--test/Transforms/ObjCARC/invoke.ll2
-rw-r--r--test/Transforms/ObjCARC/nested.ll2
-rw-r--r--test/Transforms/ObjCARC/path-overflow.ll2
-rw-r--r--test/Transforms/ObjCARC/retain-not-declared.ll2
-rw-r--r--test/Transforms/ObjCARC/split-backedge.ll2
-rw-r--r--test/Transforms/ObjCARC/weak-copies.ll2
-rw-r--r--test/Transforms/PlaceSafepoints/basic.ll94
-rw-r--r--test/Transforms/PlaceSafepoints/call-in-loop.ll31
-rw-r--r--test/Transforms/PlaceSafepoints/finite-loops.ll80
-rw-r--r--test/Transforms/PlaceSafepoints/invokes.ll110
-rw-r--r--test/Transforms/PlaceSafepoints/split-backedge.ll46
-rw-r--r--test/Transforms/PruneEH/2003-11-21-PHIUpdate.ll15
-rw-r--r--test/Transforms/PruneEH/recursivetest.ll5
-rw-r--r--test/Transforms/PruneEH/seh-nounwind.ll31
-rw-r--r--test/Transforms/PruneEH/simpletest.ll4
-rw-r--r--test/Transforms/Reassociate/crash2.ll25
-rw-r--r--test/Transforms/Reassociate/min_int.ll13
-rw-r--r--test/Transforms/RewriteStatepointsForGC/basics.ll88
-rw-r--r--test/Transforms/SLPVectorizer/X86/addsub.ll133
-rw-r--r--test/Transforms/SLPVectorizer/X86/atomics.ll31
-rw-r--r--test/Transforms/SLPVectorizer/X86/bad_types.ll50
-rw-r--r--test/Transforms/SLPVectorizer/X86/consecutive-access.ll2
-rw-r--r--test/Transforms/SLPVectorizer/X86/crash_cmpop.ll56
-rw-r--r--test/Transforms/SLPVectorizer/X86/crash_scheduling.ll4
-rw-r--r--test/Transforms/SLPVectorizer/X86/debug_info.ll74
-rw-r--r--test/Transforms/SLPVectorizer/X86/metadata.ll16
-rw-r--r--test/Transforms/SLPVectorizer/X86/operandorder.ll110
-rw-r--r--test/Transforms/SLPVectorizer/X86/pr16899.ll12
-rw-r--r--test/Transforms/SROA/alignment.ll13
-rw-r--r--test/Transforms/SROA/basictest.ll155
-rw-r--r--test/Transforms/SROA/vector-promotion.ll19
-rw-r--r--test/Transforms/SampleProfile/branch.ll98
-rw-r--r--test/Transforms/SampleProfile/calls.ll52
-rw-r--r--test/Transforms/SampleProfile/discriminator.ll44
-rw-r--r--test/Transforms/SampleProfile/fnptr.ll52
-rw-r--r--test/Transforms/SampleProfile/propagate.ll86
-rw-r--r--test/Transforms/ScalarRepl/debuginfo-preserved.ll48
-rw-r--r--test/Transforms/Scalarizer/basic.ll12
-rw-r--r--test/Transforms/Scalarizer/dbginfo.ll66
-rw-r--r--test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll4
-rw-r--r--test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll16
-rw-r--r--test/Transforms/SimplifyCFG/AArch64/lit.local.cfg5
-rw-r--r--test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll72
-rw-r--r--test/Transforms/SimplifyCFG/PhiBlockMerge.ll4
-rw-r--r--test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll45
-rw-r--r--test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg2
-rw-r--r--test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll249
-rw-r--r--test/Transforms/SimplifyCFG/R600/lit.local.cfg2
-rw-r--r--test/Transforms/SimplifyCFG/SpeculativeExec.ll16
-rw-r--r--test/Transforms/SimplifyCFG/UnreachableEliminate.ll26
-rw-r--r--test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll330
-rw-r--r--test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll211
-rw-r--r--test/Transforms/SimplifyCFG/basictest.ll7
-rw-r--r--test/Transforms/SimplifyCFG/branch-fold-dbg.ll34
-rw-r--r--test/Transforms/SimplifyCFG/clamp.ll22
-rw-r--r--test/Transforms/SimplifyCFG/hoist-dbgvalue.ll52
-rw-r--r--test/Transforms/SimplifyCFG/hoist-with-range.ll6
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll2
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll18
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights.ll48
-rw-r--r--test/Transforms/SimplifyCFG/seh-nounwind.ll31
-rw-r--r--test/Transforms/SimplifyCFG/select-gep.ll23
-rw-r--r--test/Transforms/SimplifyCFG/sink-common-code.ll34
-rw-r--r--test/Transforms/SimplifyCFG/switch-range-to-icmp.ll77
-rw-r--r--test/Transforms/SimplifyCFG/switch-to-br.ll64
-rw-r--r--test/Transforms/SimplifyCFG/switch-to-select-two-case.ll35
-rw-r--r--test/Transforms/SimplifyCFG/trap-debugloc.ll22
-rw-r--r--test/Transforms/SimplifyCFG/trivial-throw.ll77
-rw-r--r--test/Transforms/SimplifyCFG/volatile-phioper.ll2
-rw-r--r--test/Transforms/StraightLineStrengthReduce/slsr.ll119
-rw-r--r--test/Transforms/StripSymbols/2010-06-30-StripDebug.ll30
-rw-r--r--test/Transforms/StripSymbols/2010-08-25-crash.ll30
-rw-r--r--test/Transforms/StripSymbols/strip-dead-debug-info.ll54
-rw-r--r--test/Transforms/StructurizeCFG/nested-loop-order.ll79
-rw-r--r--test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll42
-rw-r--r--test/Transforms/StructurizeCFG/post-order-traversal-bug.ll100
-rw-r--r--test/Transforms/Util/combine-alias-scope-metadata.ll24
-rw-r--r--test/Transforms/Util/lowerswitch.ll36
358 files changed, 14814 insertions, 2775 deletions
diff --git a/test/Transforms/AddDiscriminators/basic.ll b/test/Transforms/AddDiscriminators/basic.ll
index 6c1e532..7c8b3d3 100644
--- a/test/Transforms/AddDiscriminators/basic.ll
+++ b/test/Transforms/AddDiscriminators/basic.ll
@@ -40,20 +40,20 @@ attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointe
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.5 \000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [basic.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"basic.c", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", metadata !1, metadata !5, metadata !6, null, void (i32)* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [basic.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!8 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5 "}
-!10 = metadata !{i32 3, i32 0, metadata !11, null}
-!11 = metadata !{metadata !"0xb\003\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [basic.c]
-!12 = metadata !{i32 4, i32 0, metadata !4, null}
-
-; CHECK: !12 = metadata !{i32 3, i32 0, metadata !13, null}
-; CHECK: !13 = metadata !{metadata !"0xb\001", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ] [./basic.c]
-; CHECK: !14 = metadata !{i32 4, i32 0, metadata !4, null}
+!0 = !{!"0x11\0012\00clang version 3.5 \000\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [basic.c] [DW_LANG_C99]
+!1 = !{!"basic.c", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", !1, !5, !6, null, void (i32)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [basic.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 1, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5 "}
+!10 = !MDLocation(line: 3, scope: !11)
+!11 = !{!"0xb\003\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [basic.c]
+!12 = !MDLocation(line: 4, scope: !4)
+
+; CHECK: !12 = !MDLocation(line: 3, scope: !13)
+; CHECK: !13 = !{!"0xb\001", !1, !11} ; [ DW_TAG_lexical_block ] [./basic.c]
+; CHECK: !14 = !MDLocation(line: 4, scope: !4)
diff --git a/test/Transforms/AddDiscriminators/first-only.ll b/test/Transforms/AddDiscriminators/first-only.ll
index e15a80a..153cfc8 100644
--- a/test/Transforms/AddDiscriminators/first-only.ll
+++ b/test/Transforms/AddDiscriminators/first-only.ll
@@ -50,33 +50,33 @@ attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointe
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.5 (trunk 199750) (llvm/trunk 199751)\000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [first-only.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"first-only.c", metadata !"."}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", metadata !1, metadata !5, metadata !6, null, void (i32)* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [first-only.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!8 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5 (trunk 199750) (llvm/trunk 199751)"}
-!10 = metadata !{i32 3, i32 0, metadata !11, null}
-
-!11 = metadata !{metadata !"0xb\003\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [first-only.c]
-; CHECK: !11 = metadata !{metadata !"0xb\003\000\000", metadata !1, metadata !4}
-
-!12 = metadata !{i32 3, i32 0, metadata !13, null}
-
-!13 = metadata !{metadata !"0xb\003\000\001", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ] [first-only.c]
-; CHECK: !13 = metadata !{metadata !"0xb\001", metadata !1, metadata !14} ; [ DW_TAG_lexical_block ] [./first-only.c]
-
-!14 = metadata !{i32 4, i32 0, metadata !13, null}
-; CHECK: !14 = metadata !{metadata !"0xb\003\000\001", metadata !1, metadata !11}
-
-!15 = metadata !{i32 5, i32 0, metadata !13, null}
-; CHECK: !15 = metadata !{i32 4, i32 0, metadata !14, null}
-
-!16 = metadata !{i32 6, i32 0, metadata !4, null}
-; CHECK: !16 = metadata !{i32 5, i32 0, metadata !14, null}
-; CHECK: !17 = metadata !{i32 6, i32 0, metadata !4, null}
+!0 = !{!"0x11\0012\00clang version 3.5 (trunk 199750) (llvm/trunk 199751)\000\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [first-only.c] [DW_LANG_C99]
+!1 = !{!"first-only.c", !"."}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", !1, !5, !6, null, void (i32)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [first-only.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 1, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5 (trunk 199750) (llvm/trunk 199751)"}
+!10 = !MDLocation(line: 3, scope: !11)
+
+!11 = !{!"0xb\003\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [first-only.c]
+; CHECK: !11 = !{!"0xb\003\000\000", !1, !4}
+
+!12 = !MDLocation(line: 3, scope: !13)
+
+!13 = !{!"0xb\003\000\001", !1, !11} ; [ DW_TAG_lexical_block ] [first-only.c]
+; CHECK: !13 = !{!"0xb\001", !1, !14} ; [ DW_TAG_lexical_block ] [./first-only.c]
+
+!14 = !MDLocation(line: 4, scope: !13)
+; CHECK: !14 = !{!"0xb\003\000\001", !1, !11}
+
+!15 = !MDLocation(line: 5, scope: !13)
+; CHECK: !15 = !MDLocation(line: 4, scope: !14)
+
+!16 = !MDLocation(line: 6, scope: !4)
+; CHECK: !16 = !MDLocation(line: 5, scope: !14)
+; CHECK: !17 = !MDLocation(line: 6, scope: !4)
diff --git a/test/Transforms/AddDiscriminators/multiple.ll b/test/Transforms/AddDiscriminators/multiple.ll
index 8418c9e..5e552a8 100644
--- a/test/Transforms/AddDiscriminators/multiple.ll
+++ b/test/Transforms/AddDiscriminators/multiple.ll
@@ -51,21 +51,21 @@ attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointe
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.5 (trunk 199750) (llvm/trunk 199751)\000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [multiple.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"multiple.c", metadata !"."}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", metadata !1, metadata !5, metadata !6, null, void (i32)* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [multiple.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!8 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5 (trunk 199750) (llvm/trunk 199751)"}
-!10 = metadata !{i32 3, i32 0, metadata !11, null}
-!11 = metadata !{metadata !"0xb\003\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [multiple.c]
-!12 = metadata !{i32 4, i32 0, metadata !4, null}
+!0 = !{!"0x11\0012\00clang version 3.5 (trunk 199750) (llvm/trunk 199751)\000\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [multiple.c] [DW_LANG_C99]
+!1 = !{!"multiple.c", !"."}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", !1, !5, !6, null, void (i32)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [multiple.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 1, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5 (trunk 199750) (llvm/trunk 199751)"}
+!10 = !MDLocation(line: 3, scope: !11)
+!11 = !{!"0xb\003\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [multiple.c]
+!12 = !MDLocation(line: 4, scope: !4)
-; CHECK: !12 = metadata !{i32 3, i32 0, metadata !13, null}
-; CHECK: !13 = metadata !{metadata !"0xb\001", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ] [./multiple.c]
-; CHECK: !14 = metadata !{i32 3, i32 0, metadata !15, null}
-; CHECK: !15 = metadata !{metadata !"0xb\002", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ] [./multiple.c]
+; CHECK: !12 = !MDLocation(line: 3, scope: !13)
+; CHECK: !13 = !{!"0xb\001", !1, !11} ; [ DW_TAG_lexical_block ] [./multiple.c]
+; CHECK: !14 = !MDLocation(line: 3, scope: !15)
+; CHECK: !15 = !{!"0xb\002", !1, !11} ; [ DW_TAG_lexical_block ] [./multiple.c]
diff --git a/test/Transforms/AddDiscriminators/no-discriminators.ll b/test/Transforms/AddDiscriminators/no-discriminators.ll
index 66a2c4e..dd7faf0 100644
--- a/test/Transforms/AddDiscriminators/no-discriminators.ll
+++ b/test/Transforms/AddDiscriminators/no-discriminators.ll
@@ -17,7 +17,7 @@ entry:
%retval = alloca i32, align 4
%i.addr = alloca i64, align 8
store i64 %i, i64* %i.addr, align 8
- call void @llvm.dbg.declare(metadata !{i64* %i.addr}, metadata !13, metadata !{}), !dbg !14
+ call void @llvm.dbg.declare(metadata i64* %i.addr, metadata !13, metadata !{}), !dbg !14
%0 = load i64* %i.addr, align 8, !dbg !15
; CHECK: %0 = load i64* %i.addr, align 8, !dbg !15
%cmp = icmp slt i64 %0, 5, !dbg !15
@@ -48,24 +48,24 @@ attributes #1 = { nounwind readnone }
!llvm.module.flags = !{!10, !11}
!llvm.ident = !{!12}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.5.0 \000\00\000\00\001", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [./no-discriminators] [DW_LANG_C99]
-!1 = metadata !{metadata !"no-discriminators", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", metadata !1, metadata !5, metadata !6, null, i32 (i64)* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./no-discriminators]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !8, metadata !9}
-!8 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!9 = metadata !{metadata !"0x24\00long int\000\0064\0064\000\000\005", null, null} ; [ DW_TAG_base_type ] [long int] [line 0, size 64, align 64, offset 0, enc DW_ATE_signed]
-!10 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-; CHECK: !10 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!11 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!12 = metadata !{metadata !"clang version 3.5.0 "}
-!13 = metadata !{metadata !"0x101\00i\0016777217\000", metadata !4, metadata !5, metadata !9} ; [ DW_TAG_arg_variable ] [i] [line 1]
-!14 = metadata !{i32 1, i32 0, metadata !4, null}
-!15 = metadata !{i32 2, i32 0, metadata !16, null}
-; CHECK: !15 = metadata !{i32 2, i32 0, metadata !16, null}
-!16 = metadata !{metadata !"0xb\002\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [./no-discriminators]
-; CHECK: !16 = metadata !{metadata !"0xb\002\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [./no-discriminators]
-!17 = metadata !{i32 3, i32 0, metadata !4, null}
+!0 = !{!"0x11\0012\00clang version 3.5.0 \000\00\000\00\001", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [./no-discriminators] [DW_LANG_C99]
+!1 = !{!"no-discriminators", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", !1, !5, !6, null, i32 (i64)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./no-discriminators]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!8, !9}
+!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!9 = !{!"0x24\00long int\000\0064\0064\000\000\005", null, null} ; [ DW_TAG_base_type ] [long int] [line 0, size 64, align 64, offset 0, enc DW_ATE_signed]
+!10 = !{i32 2, !"Dwarf Version", i32 2}
+; CHECK: !10 = !{i32 2, !"Dwarf Version", i32 2}
+!11 = !{i32 1, !"Debug Info Version", i32 2}
+!12 = !{!"clang version 3.5.0 "}
+!13 = !{!"0x101\00i\0016777217\000", !4, !5, !9} ; [ DW_TAG_arg_variable ] [i] [line 1]
+!14 = !MDLocation(line: 1, scope: !4)
+!15 = !MDLocation(line: 2, scope: !16)
+; CHECK: !15 = !MDLocation(line: 2, scope: !16)
+!16 = !{!"0xb\002\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [./no-discriminators]
+; CHECK: !16 = !{!"0xb\002\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [./no-discriminators]
+!17 = !MDLocation(line: 3, scope: !4)
diff --git a/test/Transforms/ArgumentPromotion/control-flow2.ll b/test/Transforms/ArgumentPromotion/control-flow2.ll
index 2543218..db63584 100644
--- a/test/Transforms/ArgumentPromotion/control-flow2.ll
+++ b/test/Transforms/ArgumentPromotion/control-flow2.ll
@@ -1,5 +1,6 @@
-; RUN: opt < %s -argpromotion -S | \
-; RUN: grep "load i32\* %A"
+; RUN: opt < %s -argpromotion -S | FileCheck %s
+
+; CHECK: load i32* %A
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"
define internal i32 @callee(i1 %C, i32* %P) {
diff --git a/test/Transforms/ArgumentPromotion/dbg.ll b/test/Transforms/ArgumentPromotion/dbg.ll
index d155750..65cf367 100644
--- a/test/Transforms/ArgumentPromotion/dbg.ll
+++ b/test/Transforms/ArgumentPromotion/dbg.ll
@@ -19,8 +19,8 @@ define void @caller(i32** %Y) {
!llvm.module.flags = !{!0}
!llvm.dbg.cu = !{!3}
-!0 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!1 = metadata !{i32 8, i32 0, metadata !2, null}
-!2 = metadata !{metadata !"0x2e\00test\00test\00\003\001\001\000\006\00256\000\003", null, null, null, null, void (i32**)* @test, null, null, null} ; [ DW_TAG_subprogram ]
-!3 = metadata !{metadata !"0x11\004\00clang version 3.5.0 \000\00\000\00\002", null, null, null, metadata !4, null, null} ; [ DW_TAG_compile_unit ] [/usr/local/google/home/blaikie/dev/scratch/pr20038/reduce/<stdin>] [DW_LANG_C_plus_plus]
-!4 = metadata !{metadata !2}
+!0 = !{i32 2, !"Debug Info Version", i32 2}
+!1 = !MDLocation(line: 8, scope: !2)
+!2 = !{!"0x2e\00test\00test\00\003\001\001\000\006\00256\000\003", null, null, null, null, void (i32**)* @test, null, null, null} ; [ DW_TAG_subprogram ]
+!3 = !{!"0x11\004\00clang version 3.5.0 \000\00\000\00\002", null, null, null, !4, null, null} ; [ DW_TAG_compile_unit ] [/usr/local/google/home/blaikie/dev/scratch/pr20038/reduce/<stdin>] [DW_LANG_C_plus_plus]
+!4 = !{!2}
diff --git a/test/Transforms/ArgumentPromotion/reserve-tbaa.ll b/test/Transforms/ArgumentPromotion/reserve-tbaa.ll
index 4688a83..db9d70d 100644
--- a/test/Transforms/ArgumentPromotion/reserve-tbaa.ll
+++ b/test/Transforms/ArgumentPromotion/reserve-tbaa.ll
@@ -37,16 +37,16 @@ entry:
ret i32 0
}
-!1 = metadata !{metadata !2, metadata !2, i64 0}
-!2 = metadata !{metadata !"long", metadata !3, i64 0}
-!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
-!4 = metadata !{metadata !"Simple C/C++ TBAA"}
-!5 = metadata !{metadata !6, metadata !6, i64 0}
-!6 = metadata !{metadata !"int", metadata !3, i64 0}
-!7 = metadata !{metadata !3, metadata !3, i64 0}
-!8 = metadata !{metadata !9, metadata !9, i64 0}
-!9 = metadata !{metadata !"any pointer", metadata !3, i64 0}
-; CHECK: ![[I32]] = metadata !{metadata ![[I32_TYPE:[0-9]+]], metadata ![[I32_TYPE]], i64 0}
-; CHECK: ![[I32_TYPE]] = metadata !{metadata !"int", metadata !{{.*}}, i64 0}
-; CHECK: ![[LONG]] = metadata !{metadata ![[LONG_TYPE:[0-9]+]], metadata ![[LONG_TYPE]], i64 0}
-; CHECK: ![[LONG_TYPE]] = metadata !{metadata !"long", metadata !{{.*}}, i64 0}
+!1 = !{!2, !2, i64 0}
+!2 = !{!"long", !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C/C++ TBAA"}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !3, i64 0}
+!7 = !{!3, !3, i64 0}
+!8 = !{!9, !9, i64 0}
+!9 = !{!"any pointer", !3, i64 0}
+; CHECK: ![[I32]] = !{![[I32_TYPE:[0-9]+]], ![[I32_TYPE]], i64 0}
+; CHECK: ![[I32_TYPE]] = !{!"int", !{{.*}}, i64 0}
+; CHECK: ![[LONG]] = !{![[LONG_TYPE:[0-9]+]], ![[LONG_TYPE]], i64 0}
+; CHECK: ![[LONG_TYPE]] = !{!"long", !{{.*}}, i64 0}
diff --git a/test/Transforms/BBVectorize/loop1.ll b/test/Transforms/BBVectorize/loop1.ll
index ed7be15..ca36170 100644
--- a/test/Transforms/BBVectorize/loop1.ll
+++ b/test/Transforms/BBVectorize/loop1.ll
@@ -83,7 +83,7 @@ for.body: ; preds = %for.body, %entry
; 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: %indvars.iv.next.1 = add nsw 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
diff --git a/test/Transforms/BBVectorize/metadata.ll b/test/Transforms/BBVectorize/metadata.ll
index ac7297d..874fbb8 100644
--- a/test/Transforms/BBVectorize/metadata.ll
+++ b/test/Transforms/BBVectorize/metadata.ll
@@ -41,9 +41,9 @@ entry:
; CHECK: ret void
}
-!0 = metadata !{i64 0, i64 2}
-!1 = metadata !{i64 3, i64 5}
+!0 = !{i64 0, i64 2}
+!1 = !{i64 3, i64 5}
-!2 = metadata !{ float 5.0 }
-!3 = metadata !{ float 2.5 }
+!2 = !{ float 5.0 }
+!3 = !{ float 2.5 }
diff --git a/test/Transforms/BDCE/basic.ll b/test/Transforms/BDCE/basic.ll
new file mode 100644
index 0000000..6e748c6
--- /dev/null
+++ b/test/Transforms/BDCE/basic.ll
@@ -0,0 +1,348 @@
+; RUN: opt -S -bdce -instsimplify < %s | FileCheck %s
+; RUN: opt -S -instsimplify < %s | FileCheck %s -check-prefix=CHECK-IO
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+; Function Attrs: nounwind readnone
+define signext i32 @bar(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 4
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 8
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %shr = ashr i32 %or15, 4
+ ret i32 %shr
+
+; CHECK-LABEL: @bar
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+
+; Check that instsimplify is not doing this all on its own.
+; CHECK-IO-LABEL: @bar
+; CHECK-IO: tail call signext i32 @foo(i32 signext 5)
+; CHECK-IO: tail call signext i32 @foo(i32 signext 3)
+; CHECK-IO: tail call signext i32 @foo(i32 signext 2)
+; CHECK-IO: tail call signext i32 @foo(i32 signext 1)
+; CHECK-IO: tail call signext i32 @foo(i32 signext 0)
+; CHECK-IO: tail call signext i32 @foo(i32 signext 4)
+; CHECK-IO: ret i32
+}
+
+; Function Attrs: nounwind readnone
+declare signext i32 @foo(i32 signext) #0
+
+; Function Attrs: nounwind readnone
+define signext i32 @far(i32 signext %x) #1 {
+entry:
+ %call = tail call signext i32 @goo(i32 signext 5) #1
+ %and = and i32 %call, 4
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @goo(i32 signext 3) #1
+ %and2 = and i32 %call1, 8
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @goo(i32 signext 2) #1
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @goo(i32 signext 1) #1
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @goo(i32 signext 0) #1
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @goo(i32 signext 4) #1
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %shr = ashr i32 %or15, 4
+ ret i32 %shr
+
+; CHECK-LABEL: @far
+; Calls to foo(5) and foo(3) are still there, but their results are not used.
+; CHECK: tail call signext i32 @goo(i32 signext 5)
+; CHECK-NEXT: tail call signext i32 @goo(i32 signext 3)
+; CHECK-NEXT: tail call signext i32 @goo(i32 signext 2)
+; CHECK: tail call signext i32 @goo(i32 signext 1)
+; CHECK: tail call signext i32 @goo(i32 signext 0)
+; CHECK: tail call signext i32 @goo(i32 signext 4)
+; CHECK: ret i32
+
+; Check that instsimplify is not doing this all on its own.
+; CHECK-IO-LABEL: @far
+; CHECK-IO: tail call signext i32 @goo(i32 signext 5)
+; CHECK-IO: tail call signext i32 @goo(i32 signext 3)
+; CHECK-IO: tail call signext i32 @goo(i32 signext 2)
+; CHECK-IO: tail call signext i32 @goo(i32 signext 1)
+; CHECK-IO: tail call signext i32 @goo(i32 signext 0)
+; CHECK-IO: tail call signext i32 @goo(i32 signext 4)
+; CHECK-IO: ret i32
+}
+
+declare signext i32 @goo(i32 signext) #1
+
+; Function Attrs: nounwind readnone
+define signext i32 @tar1(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %bs = tail call i32 @llvm.bswap.i32(i32 %or15) #0
+ %shr = ashr i32 %bs, 4
+ ret i32 %shr
+
+; CHECK-LABEL: @tar1
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+}
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.bswap.i32(i32) #0
+
+; Function Attrs: nounwind readnone
+define signext i32 @tar2(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %shl = shl i32 %or15, 10
+ ret i32 %shl
+
+; CHECK-LABEL: @tar2
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+}
+
+; Function Attrs: nounwind readnone
+define signext i32 @tar3(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %add = add i32 %or15, 5
+ %shl = shl i32 %add, 10
+ ret i32 %shl
+
+; CHECK-LABEL: @tar3
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+}
+
+; Function Attrs: nounwind readnone
+define signext i32 @tar4(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %sub = sub i32 %or15, 5
+ %shl = shl i32 %sub, 10
+ ret i32 %shl
+
+; CHECK-LABEL: @tar4
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+}
+
+; Function Attrs: nounwind readnone
+define signext i32 @tar5(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %xor = xor i32 %or15, 5
+ %shl = shl i32 %xor, 10
+ ret i32 %shl
+
+; CHECK-LABEL: @tar5
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+}
+
+; Function Attrs: nounwind readnone
+define signext i32 @tar7(i32 signext %x, i1 %b) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %v = select i1 %b, i32 %or15, i32 5
+ %shl = shl i32 %v, 10
+ ret i32 %shl
+
+; CHECK-LABEL: @tar7
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i32
+}
+
+; Function Attrs: nounwind readnone
+define signext i16 @tar8(i32 signext %x) #0 {
+entry:
+ %call = tail call signext i32 @foo(i32 signext 5) #0
+ %and = and i32 %call, 33554432
+ %or = or i32 %and, %x
+ %call1 = tail call signext i32 @foo(i32 signext 3) #0
+ %and2 = and i32 %call1, 67108864
+ %or3 = or i32 %or, %and2
+ %call4 = tail call signext i32 @foo(i32 signext 2) #0
+ %and5 = and i32 %call4, 16
+ %or6 = or i32 %or3, %and5
+ %call7 = tail call signext i32 @foo(i32 signext 1) #0
+ %and8 = and i32 %call7, 32
+ %or9 = or i32 %or6, %and8
+ %call10 = tail call signext i32 @foo(i32 signext 0) #0
+ %and11 = and i32 %call10, 64
+ %or12 = or i32 %or9, %and11
+ %call13 = tail call signext i32 @foo(i32 signext 4) #0
+ %and14 = and i32 %call13, 128
+ %or15 = or i32 %or12, %and14
+ %tr = trunc i32 %or15 to i16
+ ret i16 %tr
+
+; CHECK-LABEL: @tar8
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 5)
+; CHECK-NOT: tail call signext i32 @foo(i32 signext 3)
+; CHECK: tail call signext i32 @foo(i32 signext 2)
+; CHECK: tail call signext i32 @foo(i32 signext 1)
+; CHECK: tail call signext i32 @foo(i32 signext 0)
+; CHECK: tail call signext i32 @foo(i32 signext 4)
+; CHECK: ret i16
+}
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { nounwind }
+
diff --git a/test/Transforms/BDCE/dce-pure.ll b/test/Transforms/BDCE/dce-pure.ll
new file mode 100644
index 0000000..6a432fc
--- /dev/null
+++ b/test/Transforms/BDCE/dce-pure.ll
@@ -0,0 +1,33 @@
+; RUN: opt -bdce -S < %s | FileCheck %s
+
+declare i32 @strlen(i8*) readonly nounwind
+
+define void @test1() {
+ call i32 @strlen( i8* null )
+ ret void
+
+; CHECK-LABEL: @test1
+; CHECK-NOT: call
+; CHECK: ret void
+}
+
+define i32 @test2() {
+ ; invoke of pure function should not be deleted!
+ invoke i32 @strlen( i8* null ) readnone
+ to label %Cont unwind label %Other
+
+Cont: ; preds = %0
+ ret i32 0
+
+Other: ; preds = %0
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
+ ret i32 1
+
+; CHECK-LABEL: @test2
+; CHECK: invoke
+; CHECK: ret i32 1
+}
+
+declare i32 @__gxx_personality_v0(...)
+
diff --git a/test/Transforms/BDCE/order.ll b/test/Transforms/BDCE/order.ll
new file mode 100644
index 0000000..301f447
--- /dev/null
+++ b/test/Transforms/BDCE/order.ll
@@ -0,0 +1,37 @@
+; RUN: opt -bdce -S < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare i32 @__gxx_personality_v0(...)
+
+define fastcc void @_ZN11__sanitizerL12TestRegistryEPNS_14ThreadRegistryEb() #0 {
+entry:
+ br i1 undef, label %if.else, label %entry.if.end_crit_edge
+
+if.else:
+ ret void
+
+invoke.cont70:
+ store i32 %call71, i32* undef, align 4
+ br label %if.else
+
+; CHECK-LABEL: @_ZN11__sanitizerL12TestRegistryEPNS_14ThreadRegistryEb
+; CHECK: store i32 %call71
+
+lpad65.loopexit.split-lp.loopexit.split-lp:
+ br label %if.else
+
+lpad65.loopexit.split-lp.loopexit.split-lp.loopexit:
+ %lpad.loopexit1121 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ br label %lpad65.loopexit.split-lp.loopexit.split-lp
+
+entry.if.end_crit_edge:
+ %call71 = invoke i32 @_ZN11__sanitizer14ThreadRegistry12CreateThreadEmbjPv()
+ to label %invoke.cont70 unwind label %lpad65.loopexit.split-lp.loopexit.split-lp.loopexit
+}
+
+declare i32 @_ZN11__sanitizer14ThreadRegistry12CreateThreadEmbjPv()
+
+attributes #0 = { uwtable }
+
diff --git a/test/Transforms/CodeGenPrepare/statepoint-relocate.ll b/test/Transforms/CodeGenPrepare/statepoint-relocate.ll
new file mode 100644
index 0000000..cf411bc
--- /dev/null
+++ b/test/Transforms/CodeGenPrepare/statepoint-relocate.ll
@@ -0,0 +1,88 @@
+; RUN: opt -codegenprepare -S < %s | FileCheck %s
+
+target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+declare zeroext i1 @return_i1()
+
+define i32 @test_sor_basic(i32* %base) {
+; CHECK: getelementptr i32* %base, i32 15
+; CHECK: getelementptr i32* %base-new, i32 15
+entry:
+ %ptr = getelementptr i32* %base, i32 15
+ %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
+ %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 4)
+ %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+ %ret = load i32* %ptr-new
+ ret i32 %ret
+}
+
+define i32 @test_sor_two_derived(i32* %base) {
+; CHECK: getelementptr i32* %base, i32 15
+; CHECK: getelementptr i32* %base, i32 12
+; CHECK: getelementptr i32* %base-new, i32 15
+; CHECK: getelementptr i32* %base-new, i32 12
+entry:
+ %ptr = getelementptr i32* %base, i32 15
+ %ptr2 = getelementptr i32* %base, i32 12
+ %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
+ %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 4)
+ %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+ %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 6)
+ %ret = load i32* %ptr-new
+ ret i32 %ret
+}
+
+define i32 @test_sor_ooo(i32* %base) {
+; CHECK: getelementptr i32* %base, i32 15
+; CHECK: getelementptr i32* %base-new, i32 15
+entry:
+ %ptr = getelementptr i32* %base, i32 15
+ %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
+ %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+ %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 4)
+ %ret = load i32* %ptr-new
+ ret i32 %ret
+}
+
+define i32 @test_sor_gep_smallint([3 x i32]* %base) {
+; CHECK: getelementptr [3 x i32]* %base, i32 0, i32 2
+; CHECK: getelementptr [3 x i32]* %base-new, i32 0, i32 2
+entry:
+ %ptr = getelementptr [3 x i32]* %base, i32 0, i32 2
+ %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
+ %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 4, i32 4)
+ %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+ %ret = load i32* %ptr-new
+ ret i32 %ret
+}
+
+define i32 @test_sor_gep_largeint([3 x i32]* %base) {
+; CHECK: getelementptr [3 x i32]* %base, i32 0, i32 21
+; CHECK-NOT: getelementptr [3 x i32]* %base-new, i32 0, i32 21
+entry:
+ %ptr = getelementptr [3 x i32]* %base, i32 0, i32 21
+ %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
+ %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 4, i32 4)
+ %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+ %ret = load i32* %ptr-new
+ ret i32 %ret
+}
+
+define i32 @test_sor_noop(i32* %base) {
+; CHECK: getelementptr i32* %base, i32 15
+; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 6)
+entry:
+ %ptr = getelementptr i32* %base, i32 15
+ %ptr2 = getelementptr i32* %base, i32 12
+ %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
+ %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 5)
+ %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 6)
+ %ret = load i32* %ptr-new
+ ret i32 %ret
+}
+
+declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
+declare i32* @llvm.experimental.gc.relocate.p0i32(i32, i32, i32)
+declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32)
diff --git a/test/Transforms/ConstProp/InsertElement.ll b/test/Transforms/ConstProp/InsertElement.ll
new file mode 100644
index 0000000..d249c2e
--- /dev/null
+++ b/test/Transforms/ConstProp/InsertElement.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -constprop -S | FileCheck %s
+
+define i32 @test1() {
+ %A = bitcast i32 2139171423 to float
+ %B = insertelement <1 x float> undef, float %A, i32 0
+ %C = extractelement <1 x float> %B, i32 0
+ %D = bitcast float %C to i32
+ ret i32 %D
+; CHECK: @test1
+; CHECK: ret i32 2139171423
+}
+
diff --git a/test/Transforms/ConstProp/insertvalue.ll b/test/Transforms/ConstProp/insertvalue.ll
index 0d288b3..dce2b72 100644
--- a/test/Transforms/ConstProp/insertvalue.ll
+++ b/test/Transforms/ConstProp/insertvalue.ll
@@ -65,3 +65,12 @@ define [3 x %struct] @undef-test3() {
; CHECK: ret [3 x %struct] [%struct undef, %struct { i32 0, [4 x i8] undef }, %struct undef]
}
+define i32 @test-float-Nan() {
+ %A = bitcast i32 2139171423 to float
+ %B = insertvalue [1 x float] undef, float %A, 0
+ %C = extractvalue [1 x float] %B, 0
+ %D = bitcast float %C to i32
+ ret i32 %D
+; CHECK: @test-float-Nan
+; CHECK: ret i32 2139171423
+}
diff --git a/test/Transforms/CorrelatedValuePropagation/icmp.ll b/test/Transforms/CorrelatedValuePropagation/icmp.ll
new file mode 100644
index 0000000..c2863ff
--- /dev/null
+++ b/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -0,0 +1,63 @@
+; RUN: opt -correlated-propagation -S %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+; Function Attrs: noreturn
+declare void @check1(i1) #1
+
+; Function Attrs: noreturn
+declare void @check2(i1) #1
+
+; Make sure we propagate the value of %tmp35 to the true/false cases
+; CHECK-LABEL: @test1
+; CHECK: call void @check1(i1 false)
+; CHECK: call void @check2(i1 true)
+define void @test1(i64 %tmp35) {
+bb:
+ %tmp36 = icmp sgt i64 %tmp35, 0
+ br i1 %tmp36, label %bb_true, label %bb_false
+
+bb_true:
+ %tmp47 = icmp slt i64 %tmp35, 0
+ tail call void @check1(i1 %tmp47) #4
+ unreachable
+
+bb_false:
+ %tmp48 = icmp sle i64 %tmp35, 0
+ tail call void @check2(i1 %tmp48) #4
+ unreachable
+}
+
+; Function Attrs: noreturn
+; This is the same as test1 but with a diamond to ensure we
+; get %tmp36 from both true and false BBs.
+; CHECK-LABEL: @test2
+; CHECK: call void @check1(i1 false)
+; CHECK: call void @check2(i1 true)
+define void @test2(i64 %tmp35, i1 %inner_cmp) {
+bb:
+ %tmp36 = icmp sgt i64 %tmp35, 0
+ br i1 %tmp36, label %bb_true, label %bb_false
+
+bb_true:
+ br i1 %inner_cmp, label %inner_true, label %inner_false
+
+inner_true:
+ br label %merge
+
+inner_false:
+ br label %merge
+
+merge:
+ %tmp47 = icmp slt i64 %tmp35, 0
+ tail call void @check1(i1 %tmp47) #0
+ unreachable
+
+bb_false:
+ %tmp48 = icmp sle i64 %tmp35, 0
+ tail call void @check2(i1 %tmp48) #4
+ unreachable
+}
+
+attributes #4 = { noreturn }
diff --git a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll
index 077394f..dd283ae 100644
--- a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll
+++ b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll
@@ -4,10 +4,10 @@
define i8* @vfs_addname(i8* %name, i32 %len, i32 %hash, i32 %flags) nounwind ssp {
entry:
- call void @llvm.dbg.value(metadata !{i8* %name}, i64 0, metadata !0, metadata !{})
- call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !10, metadata !{})
- call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !11, metadata !{})
- call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !12, metadata !{})
+ call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !0, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !10, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !11, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !12, metadata !{})
; CHECK: call fastcc i8* @add_name_internal(i8* %name, i32 %hash) [[NUW:#[0-9]+]], !dbg !{{[0-9]+}}
%0 = call fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext 0, i32 %flags) nounwind, !dbg !13 ; <i8*> [#uses=1]
ret i8* %0, !dbg !13
@@ -17,11 +17,11 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
define internal fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext %extra, i32 %flags) noinline nounwind ssp {
entry:
- call void @llvm.dbg.value(metadata !{i8* %name}, i64 0, metadata !15, metadata !{})
- call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !20, metadata !{})
- call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !21, metadata !{})
- call void @llvm.dbg.value(metadata !{i8 %extra}, i64 0, metadata !22, metadata !{})
- call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !23, metadata !{})
+ call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !15, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !20, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !21, metadata !{})
+ call void @llvm.dbg.value(metadata i8 %extra, i64 0, metadata !22, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !23, metadata !{})
%0 = icmp eq i32 %hash, 0, !dbg !24 ; <i1> [#uses=1]
br i1 %0, label %bb, label %bb1, !dbg !24
@@ -45,34 +45,34 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!3}
!llvm.module.flags = !{!30}
-!0 = metadata !{metadata !"0x101\00name\008\000", metadata !1, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ]
-!1 = metadata !{metadata !"0x2e\00vfs_addname\00vfs_addname\00vfs_addname\0012\000\001\000\006\000\000\000", metadata !28, metadata !2, metadata !4, null, null, null, null, null} ; [ DW_TAG_subprogram ]
-!2 = metadata !{metadata !"0x29", metadata !28} ; [ DW_TAG_file_type ]
-!3 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)\001\00\000\00\000", metadata !28, metadata !29, metadata !29, null, null, null} ; [ DW_TAG_compile_unit ]
-!4 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !28, metadata !2, null, metadata !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!5 = metadata !{metadata !6, metadata !6, metadata !9, metadata !9, metadata !9}
-!6 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", metadata !28, metadata !2, metadata !7} ; [ DW_TAG_pointer_type ]
-!7 = metadata !{metadata !"0x26\00\000\008\008\000\000", metadata !28, metadata !2, metadata !8} ; [ DW_TAG_const_type ]
-!8 = metadata !{metadata !"0x24\00char\000\008\008\000\000\006", metadata !28, metadata !2} ; [ DW_TAG_base_type ]
-!9 = metadata !{metadata !"0x24\00unsigned int\000\0032\0032\000\000\007", metadata !28, metadata !2} ; [ DW_TAG_base_type ]
-!10 = metadata !{metadata !"0x101\00len\009\000", metadata !1, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ]
-!11 = metadata !{metadata !"0x101\00hash\0010\000", metadata !1, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ]
-!12 = metadata !{metadata !"0x101\00flags\0011\000", metadata !1, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ]
-!13 = metadata !{i32 13, i32 0, metadata !14, null}
-!14 = metadata !{metadata !"0xb\0012\000\000", metadata !28, metadata !1} ; [ DW_TAG_lexical_block ]
-!15 = metadata !{metadata !"0x101\00name\0017\000", metadata !16, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ]
-!16 = metadata !{metadata !"0x2e\00add_name_internal\00add_name_internal\00add_name_internal\0022\001\001\000\006\000\000\000", metadata !28, metadata !2, metadata !17, null, null, null, null, null} ; [ DW_TAG_subprogram ]
-!17 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !28, metadata !2, null, metadata !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!18 = metadata !{metadata !6, metadata !6, metadata !9, metadata !9, metadata !19, metadata !9}
-!19 = metadata !{metadata !"0x24\00unsigned char\000\008\008\000\000\008", metadata !28, metadata !2} ; [ DW_TAG_base_type ]
-!20 = metadata !{metadata !"0x101\00len\0018\000", metadata !16, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ]
-!21 = metadata !{metadata !"0x101\00hash\0019\000", metadata !16, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ]
-!22 = metadata !{metadata !"0x101\00extra\0020\000", metadata !16, metadata !2, metadata !19} ; [ DW_TAG_arg_variable ]
-!23 = metadata !{metadata !"0x101\00flags\0021\000", metadata !16, metadata !2, metadata !9} ; [ DW_TAG_arg_variable ]
-!24 = metadata !{i32 23, i32 0, metadata !25, null}
-!25 = metadata !{metadata !"0xb\0022\000\000", metadata !28, metadata !16} ; [ DW_TAG_lexical_block ]
-!26 = metadata !{i32 24, i32 0, metadata !25, null}
-!27 = metadata !{i32 26, i32 0, metadata !25, null}
-!28 = metadata !{metadata !"tail.c", metadata !"/Users/echeng/LLVM/radars/r7927803/"}
-!29 = metadata !{i32 0}
-!30 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x101\00name\008\000", !1, !2, !6} ; [ DW_TAG_arg_variable ]
+!1 = !{!"0x2e\00vfs_addname\00vfs_addname\00vfs_addname\0012\000\001\000\006\000\000\000", !28, !2, !4, null, null, null, null, null} ; [ DW_TAG_subprogram ]
+!2 = !{!"0x29", !28} ; [ DW_TAG_file_type ]
+!3 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)\001\00\000\00\000", !28, !29, !29, null, null, null} ; [ DW_TAG_compile_unit ]
+!4 = !{!"0x15\00\000\000\000\000\000\000", !28, !2, null, !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!5 = !{!6, !6, !9, !9, !9}
+!6 = !{!"0xf\00\000\0064\0064\000\000", !28, !2, !7} ; [ DW_TAG_pointer_type ]
+!7 = !{!"0x26\00\000\008\008\000\000", !28, !2, !8} ; [ DW_TAG_const_type ]
+!8 = !{!"0x24\00char\000\008\008\000\000\006", !28, !2} ; [ DW_TAG_base_type ]
+!9 = !{!"0x24\00unsigned int\000\0032\0032\000\000\007", !28, !2} ; [ DW_TAG_base_type ]
+!10 = !{!"0x101\00len\009\000", !1, !2, !9} ; [ DW_TAG_arg_variable ]
+!11 = !{!"0x101\00hash\0010\000", !1, !2, !9} ; [ DW_TAG_arg_variable ]
+!12 = !{!"0x101\00flags\0011\000", !1, !2, !9} ; [ DW_TAG_arg_variable ]
+!13 = !MDLocation(line: 13, scope: !14)
+!14 = !{!"0xb\0012\000\000", !28, !1} ; [ DW_TAG_lexical_block ]
+!15 = !{!"0x101\00name\0017\000", !16, !2, !6} ; [ DW_TAG_arg_variable ]
+!16 = !{!"0x2e\00add_name_internal\00add_name_internal\00add_name_internal\0022\001\001\000\006\000\000\000", !28, !2, !17, null, null, null, null, null} ; [ DW_TAG_subprogram ]
+!17 = !{!"0x15\00\000\000\000\000\000\000", !28, !2, null, !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!18 = !{!6, !6, !9, !9, !19, !9}
+!19 = !{!"0x24\00unsigned char\000\008\008\000\000\008", !28, !2} ; [ DW_TAG_base_type ]
+!20 = !{!"0x101\00len\0018\000", !16, !2, !9} ; [ DW_TAG_arg_variable ]
+!21 = !{!"0x101\00hash\0019\000", !16, !2, !9} ; [ DW_TAG_arg_variable ]
+!22 = !{!"0x101\00extra\0020\000", !16, !2, !19} ; [ DW_TAG_arg_variable ]
+!23 = !{!"0x101\00flags\0021\000", !16, !2, !9} ; [ DW_TAG_arg_variable ]
+!24 = !MDLocation(line: 23, scope: !25)
+!25 = !{!"0xb\0022\000\000", !28, !16} ; [ DW_TAG_lexical_block ]
+!26 = !MDLocation(line: 24, scope: !25)
+!27 = !MDLocation(line: 26, scope: !25)
+!28 = !{!"tail.c", !"/Users/echeng/LLVM/radars/r7927803/"}
+!29 = !{i32 0}
+!30 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/DeadArgElim/aggregates.ll b/test/Transforms/DeadArgElim/aggregates.ll
new file mode 100644
index 0000000..f54c6c9
--- /dev/null
+++ b/test/Transforms/DeadArgElim/aggregates.ll
@@ -0,0 +1,162 @@
+; RUN: opt -S -deadargelim %s | FileCheck %s
+
+; Case 0: the basic example: an entire aggregate use is returned, but it's
+; actually only used in ways we can eliminate. We gain benefit from analysing
+; the "use" and applying its results to all sub-values.
+
+; CHECK-LABEL: define internal void @agguse_dead()
+
+define internal { i32, i32 } @agguse_dead() {
+ ret { i32, i32 } { i32 0, i32 1 }
+}
+
+define internal { i32, i32 } @test_agguse_dead() {
+ %val = call { i32, i32 } @agguse_dead()
+ ret { i32, i32 } %val
+}
+
+
+
+; Case 1: an opaque use of the aggregate exists (in this case dead). Otherwise
+; only one value is used, so function can be simplified.
+
+; CHECK-LABEL: define internal i32 @rets_independent_if_agguse_dead()
+; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } { i32 0, i32 1 }, 1
+; CHECK: ret i32 [[RET]]
+
+define internal { i32, i32 } @rets_independent_if_agguse_dead() {
+ ret { i32, i32 } { i32 0, i32 1 }
+}
+
+define internal { i32, i32 } @test_rets_independent_if_agguse_dead(i1 %tst) {
+ %val = call { i32, i32 } @rets_independent_if_agguse_dead()
+ br i1 %tst, label %use_1, label %use_aggregate
+
+use_1:
+ ; This use can be classified as applying only to ret 1.
+ %val0 = extractvalue { i32, i32 } %val, 1
+ call void @callee(i32 %val0)
+ ret { i32, i32 } undef
+
+use_aggregate:
+ ; This use is assumed to apply to both 0 and 1.
+ ret { i32, i32 } %val
+}
+
+; Case 2: an opaque use of the aggregate exists (in this case *live*). Other
+; uses shouldn't matter.
+
+; CHECK-LABEL: define internal { i32, i32 } @rets_live_agguse()
+; CHECK: ret { i32, i32 } { i32 0, i32 1 }
+
+define internal { i32, i32 } @rets_live_agguse() {
+ ret { i32, i32} { i32 0, i32 1 }
+}
+
+define { i32, i32 } @test_rets_live_aggues(i1 %tst) {
+ %val = call { i32, i32 } @rets_live_agguse()
+ br i1 %tst, label %use_1, label %use_aggregate
+
+use_1:
+ ; This use can be classified as applying only to ret 1.
+ %val0 = extractvalue { i32, i32 } %val, 1
+ call void @callee(i32 %val0)
+ ret { i32, i32 } undef
+
+use_aggregate:
+ ; This use is assumed to apply to both 0 and 1.
+ ret { i32, i32 } %val
+}
+
+declare void @callee(i32)
+
+; Case 3: the insertvalue meant %in was live if ret-slot-1 was, but we were only
+; tracking multiple ret-slots for struct types. So %in was eliminated
+; incorrectly.
+
+; CHECK-LABEL: define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in)
+
+define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in) {
+ %ret = insertvalue [2 x i32] undef, i32 %in, 1
+ ret [2 x i32] %ret
+}
+
+define [2 x i32] @test_array_rets_have_multiple_slots() {
+ %res = call [2 x i32] @array_rets_have_multiple_slots(i32 42)
+ ret [2 x i32] %res
+}
+
+; Case 4: we can remove some retvals from the array. It's nice to produce an
+; array again having done so (rather than converting it to a struct).
+
+; CHECK-LABEL: define internal [2 x i32] @can_shrink_arrays()
+; CHECK: [[VAL0:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 0
+; CHECK: [[RESTMP:%.*]] = insertvalue [2 x i32] undef, i32 [[VAL0]], 0
+; CHECK: [[VAL2:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 2
+; CHECK: [[RES:%.*]] = insertvalue [2 x i32] [[RESTMP]], i32 [[VAL2]], 1
+; CHECK: ret [2 x i32] [[RES]]
+
+; CHECK-LABEL: define void @test_can_shrink_arrays()
+
+define internal [3 x i32] @can_shrink_arrays() {
+ ret [3 x i32] [i32 42, i32 43, i32 44]
+}
+
+define void @test_can_shrink_arrays() {
+ %res = call [3 x i32] @can_shrink_arrays()
+
+ %res.0 = extractvalue [3 x i32] %res, 0
+ call void @callee(i32 %res.0)
+
+ %res.2 = extractvalue [3 x i32] %res, 2
+ call void @callee(i32 %res.2)
+
+ ret void
+}
+
+; Case 5: %in gets passed directly to the return. It should mark be marked as
+; used if *any* of the return values are, not just if value 0 is.
+
+; CHECK-LABEL: define internal i32 @ret_applies_to_all({ i32, i32 } %in)
+; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } %in, 1
+; CHECK: ret i32 [[RET]]
+
+define internal {i32, i32} @ret_applies_to_all({i32, i32} %in) {
+ ret {i32, i32} %in
+}
+
+define i32 @test_ret_applies_to_all() {
+ %val = call {i32, i32} @ret_applies_to_all({i32, i32} {i32 42, i32 43})
+ %ret = extractvalue {i32, i32} %val, 1
+ ret i32 %ret
+}
+
+; Case 6: When considering @mid, the return instruciton has sub-value 0
+; unconditionally live, but 1 only conditionally live. Since at that level we're
+; applying the results to the whole of %res, this means %res is live and cannot
+; be reduced. There is scope for further optimisation here (though not visible
+; in this test-case).
+
+; CHECK-LABEL: define internal { i8*, i32 } @inner()
+
+define internal {i8*, i32} @mid() {
+ %res = call {i8*, i32} @inner()
+ %intval = extractvalue {i8*, i32} %res, 1
+ %tst = icmp eq i32 %intval, 42
+ br i1 %tst, label %true, label %true
+
+true:
+ ret {i8*, i32} %res
+}
+
+define internal {i8*, i32} @inner() {
+ ret {i8*, i32} {i8* null, i32 42}
+}
+
+define internal i8 @outer() {
+ %res = call {i8*, i32} @mid()
+ %resptr = extractvalue {i8*, i32} %res, 0
+
+ %val = load i8* %resptr
+ ret i8 %val
+} \ No newline at end of file
diff --git a/test/Transforms/DeadArgElim/dbginfo.ll b/test/Transforms/DeadArgElim/dbginfo.ll
index b457f01..5bbf821 100644
--- a/test/Transforms/DeadArgElim/dbginfo.ll
+++ b/test/Transforms/DeadArgElim/dbginfo.ll
@@ -29,7 +29,7 @@ entry:
; Function Attrs: nounwind uwtable
define internal void @_ZL2f1iz(i32, ...) #1 {
entry:
- call void @llvm.dbg.value(metadata !{i32 %0}, i64 0, metadata !17, metadata !18), !dbg !19
+ call void @llvm.dbg.value(metadata i32 %0, i64 0, metadata !17, metadata !18), !dbg !19
ret void, !dbg !20
}
@@ -47,24 +47,24 @@ attributes #2 = { nounwind readnone }
!llvm.module.flags = !{!12, !13}
!llvm.ident = !{!14}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.6.0 \000\00\000\00\001", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/dbg.cpp] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"dbg.cpp", metadata !"/tmp/dbginfo"}
-!2 = metadata !{}
-!3 = metadata !{metadata !4, metadata !8}
-!4 = metadata !{metadata !"0x2e\00f2\00f2\00_Z2f2v\004\000\001\000\000\00256\000\004", metadata !1, metadata !5, metadata !6, null, void ()* @_Z2f2v, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 4] [def] [f2]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/tmp/dbginfo/dbg.cpp]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{null}
-!8 = metadata !{metadata !"0x2e\00f1\00f1\00_ZL2f1iz\001\001\001\000\000\00256\000\001", metadata !1, metadata !5, metadata !9, null, void (i32, ...)* @_ZL2f1iz, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [local] [def] [f1]
-!9 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !10, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!10 = metadata !{null, metadata !11, null}
-!11 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!12 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!13 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!14 = metadata !{metadata !"clang version 3.6.0 "}
-!15 = metadata !{i32 5, i32 3, metadata !4, null}
-!16 = metadata !{i32 6, i32 1, metadata !4, null}
-!17 = metadata !{metadata !"0x101\00\0016777217\000", metadata !8, metadata !5, metadata !11} ; [ DW_TAG_arg_variable ] [line 1]
-!18 = metadata !{metadata !"0x102"} ; [ DW_TAG_expression ]
-!19 = metadata !{i32 1, i32 19, metadata !8, null}
-!20 = metadata !{i32 2, i32 1, metadata !8, null}
+!0 = !{!"0x11\004\00clang version 3.6.0 \000\00\000\00\001", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/dbg.cpp] [DW_LANG_C_plus_plus]
+!1 = !{!"dbg.cpp", !"/tmp/dbginfo"}
+!2 = !{}
+!3 = !{!4, !8}
+!4 = !{!"0x2e\00f2\00f2\00_Z2f2v\004\000\001\000\000\00256\000\004", !1, !5, !6, null, void ()* @_Z2f2v, null, null, !2} ; [ DW_TAG_subprogram ] [line 4] [def] [f2]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/tmp/dbginfo/dbg.cpp]
+!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{null}
+!8 = !{!"0x2e\00f1\00f1\00_ZL2f1iz\001\001\001\000\000\00256\000\001", !1, !5, !9, null, void (i32, ...)* @_ZL2f1iz, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [local] [def] [f1]
+!9 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !10, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!10 = !{null, !11, null}
+!11 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!12 = !{i32 2, !"Dwarf Version", i32 4}
+!13 = !{i32 2, !"Debug Info Version", i32 2}
+!14 = !{!"clang version 3.6.0 "}
+!15 = !MDLocation(line: 5, column: 3, scope: !4)
+!16 = !MDLocation(line: 6, column: 1, scope: !4)
+!17 = !{!"0x101\00\0016777217\000", !8, !5, !11} ; [ DW_TAG_arg_variable ] [line 1]
+!18 = !{!"0x102"} ; [ DW_TAG_expression ]
+!19 = !MDLocation(line: 1, column: 19, scope: !8)
+!20 = !MDLocation(line: 2, column: 1, scope: !8)
diff --git a/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll b/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
index 079eec4..39d5358 100644
--- a/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
+++ b/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
@@ -5,9 +5,9 @@ target triple = "i386-apple-darwin9.8"
@A = external global [0 x i32]
-declare cc10 void @Func2(i32*, i32*, i32*, i32)
+declare ghccc void @Func2(i32*, i32*, i32*, i32)
-define cc10 void @Func1(i32* noalias %Arg1, i32* noalias %Arg2, i32* %Arg3, i32 %Arg4) {
+define ghccc void @Func1(i32* noalias %Arg1, i32* noalias %Arg2, i32* %Arg3, i32 %Arg4) {
entry:
store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2
; CHECK: store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2
@@ -18,6 +18,6 @@ entry:
%ln2gE = bitcast i32* %ln2gD to double*
store double %ln2gB, double* %ln2gE
; CHECK: store double %ln2gB, double* %ln2gE
- tail call cc10 void @Func2(i32* %Arg1, i32* %Arg2, i32* %Arg3, i32 %Arg4) nounwind
+ tail call ghccc void @Func2(i32* %Arg1, i32* %Arg2, i32* %Arg3, i32 %Arg4) nounwind
ret void
}
diff --git a/test/Transforms/DeadStoreElimination/inst-limits.ll b/test/Transforms/DeadStoreElimination/inst-limits.ll
index 3d78bb5..3ef5607 100644
--- a/test/Transforms/DeadStoreElimination/inst-limits.ll
+++ b/test/Transforms/DeadStoreElimination/inst-limits.ll
@@ -118,7 +118,7 @@ entry:
; Insert a meaningless dbg.value intrinsic; it should have no
; effect on the working of DSE in any way.
- call void @llvm.dbg.value(metadata !12, i64 0, metadata !10, metadata !{})
+ call void @llvm.dbg.value(metadata i32* undef, i64 0, metadata !10, metadata !{})
; CHECK: store i32 -1, i32* @x, align 4
store i32 -1, i32* @x, align 4
@@ -245,18 +245,18 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!11, !13}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.4\001\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !9, metadata !2} ; [ DW_TAG_compile_unit ] [/home/tmp/test.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"test.c", metadata !"/home/tmp"}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00test_within_limit\00test_within_limit\00\003\000\001\000\006\00256\000\004", metadata !1, metadata !5, metadata !6, null, i32 ()* @test_within_limit, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 4] [test]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/home/tmp/test.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !8}
-!8 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!9 = metadata !{metadata !10}
-!10 = metadata !{metadata !"0x34\00x\00x\00\001\000\001", null, metadata !5, metadata !8, i32* @x, null} ; [ DW_TAG_variable ] [x] [line 1] [def]
-!11 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!12 = metadata !{i32* undef}
+!0 = !{!"0x11\004\00clang version 3.4\001\00\000\00\000", !1, !2, !2, !3, !9, !2} ; [ DW_TAG_compile_unit ] [/home/tmp/test.c] [DW_LANG_C99]
+!1 = !{!"test.c", !"/home/tmp"}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00test_within_limit\00test_within_limit\00\003\000\001\000\006\00256\000\004", !1, !5, !6, null, i32 ()* @test_within_limit, null, null, !2} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 4] [test]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/home/tmp/test.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!8}
+!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!9 = !{!10}
+!10 = !{!"0x34\00x\00x\00\001\000\001", null, !5, !8, i32* @x, null} ; [ DW_TAG_variable ] [x] [line 1] [def]
+!11 = !{i32 2, !"Dwarf Version", i32 4}
+!12 = !{i32* undef}
-!13 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!13 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/DebugIR/crash.ll b/test/Transforms/DebugIR/crash.ll
deleted file mode 100644
index f4a88d7..0000000
--- a/test/Transforms/DebugIR/crash.ll
+++ /dev/null
@@ -1,42 +0,0 @@
-; ModuleID = 'crash.c'
-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-pc-linux-gnu"
-
-@.str = private unnamed_addr constant [18 x i8] c"Hello, segfault!\0A\00", align 1
-@.str1 = private unnamed_addr constant [14 x i8] c"Now crash %d\0A\00", align 1
-
-; Function Attrs: nounwind uwtable
-define i32 @main(i32 %argc, i8** %argv) #0 {
- %1 = alloca i32, align 4 ;CHECK: !dbg
- %2 = alloca i32, align 4 ;CHECK-NEXT: !dbg
- %3 = alloca i8**, align 8 ;CHECK-NEXT: !dbg
- %null_ptr = alloca i32*, align 8 ;CHECK-NEXT: !dbg
- store i32 0, i32* %1 ;CHECK-NEXT: !dbg
- store i32 %argc, i32* %2, align 4 ;CHECK-NEXT: !dbg
- store i8** %argv, i8*** %3, align 8 ;CHECK-NEXT: !dbg
- store i32* null, i32** %null_ptr, align 8 ;CHECK-NEXT: !dbg
- %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0)) ;CHECK-NEXT: !dbg
- %5 = load i32** %null_ptr, align 8 ;CHECK-NEXT: !dbg
- %6 = load i32* %5, align 4 ;CHECK-NEXT: !dbg
- %7 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str1, i32 0, i32 0), i32 %6) ;CHECK-NEXT: !dbg
- %8 = load i32* %2, align 4 ;CHECK-NEXT: !dbg
- ret i32 %8 ;CHECK-NEXT: !dbg
-}
-
-declare i32 @printf(i8*, ...) #1
-
-attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-
-; CHECK: = metadata !{i32 14,
-; CHECK-NEXT: = metadata !{i32 15,
-; CHECK-NEXT: = metadata !{i32 16,
-; CHECK-NEXT: = metadata !{i32 17,
-; CHECK-NEXT: = metadata !{i32 18,
-; CHECK-NEXT: = metadata !{i32 19,
-; CHECK-NEXT: = metadata !{i32 20,
-; CHECK-NEXT: = metadata !{i32 21,
-; CHECK-NEXT: = metadata !{i32 22,
-; CHECK-NEXT: = metadata !{i32 23,
-
-; RUN: opt %s -debug-ir -S | FileCheck %s
diff --git a/test/Transforms/DebugIR/exception.ll b/test/Transforms/DebugIR/exception.ll
deleted file mode 100644
index 2436d38..0000000
--- a/test/Transforms/DebugIR/exception.ll
+++ /dev/null
@@ -1,127 +0,0 @@
-; ModuleID = 'exception.cpp'
-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-pc-linux-gnu"
-
-@_ZTIi = external constant i8*
-
-; Function Attrs: uwtable
-define i32 @main(i32 %argc, i8** %argv) #0 {
- %1 = alloca i32, align 4 ; CHECK: !dbg
- %2 = alloca i32, align 4 ; CHECK-NEXT: !dbg
- %3 = alloca i8**, align 8 ; CHECK-NEXT: !dbg
- %4 = alloca i8* ; CHECK-NEXT: !dbg
- %5 = alloca i32 ; CHECK-NEXT: !dbg
- %e = alloca i32, align 4 ; CHECK-NEXT: !dbg
- %6 = alloca i32 ; CHECK-NEXT: !dbg
- store i32 0, i32* %1 ; CHECK-NEXT: !dbg
- store i32 %argc, i32* %2, align 4 ; CHECK-NEXT: !dbg
- store i8** %argv, i8*** %3, align 8 ; CHECK-NEXT: !dbg
- %7 = call i8* @__cxa_allocate_exception(i64 4) #2 ; CHECK-NEXT: !dbg
- %8 = bitcast i8* %7 to i32* ; CHECK-NEXT: !dbg
- %9 = load i32* %2, align 4 ; CHECK-NEXT: !dbg
- store i32 %9, i32* %8 ; CHECK-NEXT: !dbg
- invoke void @__cxa_throw(i8* %7, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3
- to label %31 unwind label %10 ; CHECK: !dbg
-
-; <label>:10 ; preds = %0
- %11 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- catch i8* bitcast (i8** @_ZTIi to i8*) ; CHECK: !dbg
- %12 = extractvalue { i8*, i32 } %11, 0 ; CHECK-NEXT: !dbg
- store i8* %12, i8** %4 ; CHECK-NEXT: !dbg
- %13 = extractvalue { i8*, i32 } %11, 1 ; CHECK-NEXT: !dbg
- store i32 %13, i32* %5 ; CHECK-NEXT: !dbg
- br label %14 ; CHECK-NEXT: !dbg
-
-; <label>:14 ; preds = %10
- %15 = load i32* %5 ; CHECK: !dbg
- %16 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2 ; CHECK-NEXT: !dbg
- %17 = icmp eq i32 %15, %16 ; CHECK-NEXT: !dbg
- br i1 %17, label %18, label %26 ; CHECK-NEXT: !dbg
-
-; <label>:18 ; preds = %14
- %19 = load i8** %4 ; CHECK: !dbg
- %20 = call i8* @__cxa_begin_catch(i8* %19) #2 ; CHECK-NEXT: !dbg
- %21 = bitcast i8* %20 to i32* ; CHECK-NEXT: !dbg
- %22 = load i32* %21, align 4 ; CHECK-NEXT: !dbg
- store i32 %22, i32* %e, align 4 ; CHECK-NEXT: !dbg
- %23 = load i32* %e, align 4 ; CHECK-NEXT: !dbg
- store i32 %23, i32* %1 ; CHECK-NEXT: !dbg
- store i32 1, i32* %6 ; CHECK-NEXT: !dbg
- call void @__cxa_end_catch() #2 ; CHECK-NEXT: !dbg
- br label %24 ; CHECK-NEXT: !dbg
-
-; <label>:24 ; preds = %18
- %25 = load i32* %1 ; CHECK: !dbg
- ret i32 %25 ; CHECK-NEXT: !dbg
-
-; <label>:26 ; preds = %14
- %27 = load i8** %4 ; CHECK: !dbg
- %28 = load i32* %5 ; CHECK-NEXT: !dbg
- %29 = insertvalue { i8*, i32 } undef, i8* %27, 0 ; CHECK-NEXT: !dbg
- %30 = insertvalue { i8*, i32 } %29, i32 %28, 1 ; CHECK-NEXT: !dbg
- resume { i8*, i32 } %30 ; CHECK-NEXT: !dbg
-
-; <label>:31 ; preds = %0
- unreachable ; CHECK: !dbg
-}
-
-declare i8* @__cxa_allocate_exception(i64)
-
-declare void @__cxa_throw(i8*, i8*, i8*)
-
-declare i32 @__gxx_personality_v0(...)
-
-; Function Attrs: nounwind readnone
-declare i32 @llvm.eh.typeid.for(i8*) #1
-
-declare i8* @__cxa_begin_catch(i8*)
-
-declare void @__cxa_end_catch()
-
-attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { nounwind readnone }
-attributes #2 = { nounwind }
-attributes #3 = { noreturn }
-; CHECK: = metadata !{i32 16,
-; CHECK-NEXT: = metadata !{i32 17,
-; CHECK-NEXT: = metadata !{i32 18,
-; CHECK-NEXT: = metadata !{i32 19,
-; CHECK-NEXT: = metadata !{i32 20,
-; CHECK-NEXT: = metadata !{i32 21,
-; CHECK-NEXT: = metadata !{i32 22,
-; CHECK-NEXT: = metadata !{i32 24,
-
-; CHECK-NEXT: = metadata !{i32 28,
-; CHECK-NEXT: = metadata !{i32 29,
-; CHECK-NEXT: = metadata !{i32 30,
-; CHECK-NEXT: = metadata !{i32 31,
-; CHECK-NEXT: = metadata !{i32 32,
-; CHECK-NEXT: = metadata !{i32 33,
-
-; CHECK-NEXT: = metadata !{i32 36,
-; CHECK-NEXT: = metadata !{i32 37,
-; CHECK-NEXT: = metadata !{i32 38,
-; CHECK-NEXT: = metadata !{i32 39,
-
-; CHECK-NEXT: = metadata !{i32 42,
-; CHECK-NEXT: = metadata !{i32 43,
-; CHECK-NEXT: = metadata !{i32 44,
-; CHECK-NEXT: = metadata !{i32 45,
-; CHECK-NEXT: = metadata !{i32 46,
-; CHECK-NEXT: = metadata !{i32 47,
-; CHECK-NEXT: = metadata !{i32 48,
-; CHECK-NEXT: = metadata !{i32 49,
-; CHECK-NEXT: = metadata !{i32 50,
-; CHECK-NEXT: = metadata !{i32 51,
-
-; CHECK-NEXT: = metadata !{i32 54,
-; CHECK-NEXT: = metadata !{i32 55,
-
-; CHECK-NEXT: = metadata !{i32 58,
-; CHECK-NEXT: = metadata !{i32 59,
-; CHECK-NEXT: = metadata !{i32 60,
-; CHECK-NEXT: = metadata !{i32 61,
-; CHECK-NEXT: = metadata !{i32 62,
-; CHECK-NEXT: = metadata !{i32 65,
-
-; RUN: opt %s -debug-ir -S | FileCheck %s
diff --git a/test/Transforms/DebugIR/function.ll b/test/Transforms/DebugIR/function.ll
deleted file mode 100644
index dba073d..0000000
--- a/test/Transforms/DebugIR/function.ll
+++ /dev/null
@@ -1,51 +0,0 @@
-; ModuleID = 'function.c'
-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-pc-linux-gnu"
-
-; Function Attrs: nounwind uwtable
-define void @blah(i32* %i) #0 {
- %1 = alloca i32*, align 8 ; CHECK: !dbg
- store i32* %i, i32** %1, align 8 ; CHECK-NEXT: !dbg
- %2 = load i32** %1, align 8 ; CHECK-NEXT: !dbg
- %3 = load i32* %2, align 4 ; CHECK-NEXT: !dbg
- %4 = add nsw i32 %3, 1 ; CHECK-NEXT: !dbg
- store i32 %4, i32* %2, align 4 ; CHECK-NEXT: !dbg
- ret void ; CHECK-NEXT: !dbg
-}
-
-; Function Attrs: nounwind uwtable
-define i32 @main(i32 %argc, i8** %argv) #0 {
- %1 = alloca i32, align 4 ; CHECK: !dbg
- %2 = alloca i32, align 4 ; CHECK-NEXT: !dbg
- %3 = alloca i8**, align 8 ; CHECK-NEXT: !dbg
- %i = alloca i32, align 4 ; CHECK-NEXT: !dbg
- store i32 0, i32* %1 ; CHECK-NEXT: !dbg
- store i32 %argc, i32* %2, align 4 ; CHECK-NEXT: !dbg
- store i8** %argv, i8*** %3, align 8 ; CHECK-NEXT: !dbg
- store i32 7, i32* %i, align 4 ; CHECK-NEXT: !dbg
- call void @blah(i32* %i) ; CHECK-NEXT: !dbg
- %4 = load i32* %i, align 4 ; CHECK-NEXT: !dbg
- ret i32 %4 ; CHECK-NEXT: !dbg
-}
-
-attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-; CHECK: = metadata !{i32 8,
-; CHECK-NEXT: = metadata !{i32 9,
-; CHECK-NEXT: = metadata !{i32 10,
-; CHECK-NEXT: = metadata !{i32 11,
-; CHECK-NEXT: = metadata !{i32 12,
-; CHECK-NEXT: = metadata !{i32 13,
-
-; CHECK-NEXT: = metadata !{i32 18,
-; CHECK-NEXT: = metadata !{i32 19,
-; CHECK-NEXT: = metadata !{i32 20,
-; CHECK-NEXT: = metadata !{i32 21,
-; CHECK-NEXT: = metadata !{i32 22,
-; CHECK-NEXT: = metadata !{i32 23,
-; CHECK-NEXT: = metadata !{i32 24,
-; CHECK-NEXT: = metadata !{i32 25,
-; CHECK-NEXT: = metadata !{i32 26,
-; CHECK-NEXT: = metadata !{i32 27,
-; CHECK-NEXT: = metadata !{i32 28,
-
-; RUN: opt %s -debug-ir -S | FileCheck %s
diff --git a/test/Transforms/DebugIR/simple-addrspace.ll b/test/Transforms/DebugIR/simple-addrspace.ll
deleted file mode 100644
index 6539c8a..0000000
--- a/test/Transforms/DebugIR/simple-addrspace.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; RUN: opt -debug-ir -S %s -o - | FileCheck %s
-
-target datalayout = "e-p:64:64:64-p1:16:16:16"
-
-define void @foo(i32 addrspace(1)*) nounwind {
- ret void
-}
-
-; Make sure the pointer size is 16
-
-; CHECK: metadata !"0xf\00i32 addrspace(1)*\000\0016\002\000\000"
diff --git a/test/Transforms/DebugIR/simple.ll b/test/Transforms/DebugIR/simple.ll
deleted file mode 100644
index 3b18895..0000000
--- a/test/Transforms/DebugIR/simple.ll
+++ /dev/null
@@ -1,25 +0,0 @@
-; ModuleID = 'simple.c'
-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-pc-linux-gnu"
-
-; Function Attrs: nounwind uwtable
-define i32 @main(i32 %argc, i8** %argv) #0 {
- %1 = alloca i32, align 4 ; CHECK: !dbg
- %2 = alloca i32, align 4 ; CHECK-NEXT: !dbg
- %3 = alloca i8**, align 8 ; CHECK-NEXT: !dbg
- store i32 0, i32* %1 ; CHECK-NEXT: !dbg
- store i32 %argc, i32* %2, align 4 ; CHECK-NEXT: !dbg
- store i8** %argv, i8*** %3, align 8 ; CHECK-NEXT: !dbg
- %4 = load i32* %2, align 4 ; CHECK-NEXT: !dbg
- ret i32 %4 ; CHECK-NEXT: !dbg
-}
-
-attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-
-; CHECK: = metadata !{i32 10,
-; CHECK-NEXT: = metadata !{i32 11,
-; CHECK-NEXT: = metadata !{i32 12,
-; CHECK-NEXT: = metadata !{i32 13,
-; CHECK-NEXT: = metadata !{i32 14,
-
-; RUN: opt %s -debug-ir -S | FileCheck %s
diff --git a/test/Transforms/DebugIR/struct.ll b/test/Transforms/DebugIR/struct.ll
deleted file mode 100644
index 8db3dbe..0000000
--- a/test/Transforms/DebugIR/struct.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; ModuleID = 'struct.cpp'
-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-pc-linux-gnu"
-
-%struct.blah = type { i32, float, i8 }
-
-; Function Attrs: nounwind uwtable
-define i32 @main() #0 {
- %1 = alloca i32, align 4 ; CHECK: !dbg
- %b = alloca %struct.blah, align 4 ; CHECK-NEXT: !dbg
- store i32 0, i32* %1 ; CHECK-NEXT: !dbg
- %2 = getelementptr inbounds %struct.blah* %b, i32 0, i32 0 ; CHECK-NEXT: !dbg
- %3 = load i32* %2, align 4 ; CHECK-NEXT: !dbg
- ret i32 %3 ; CHECK-NEXT: !dbg
-}
-
-attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-
-; CHECK: = metadata !{i32 11,
-; CHECK-NEXT: = metadata !{i32 12,
-; CHECK-NEXT: = metadata !{i32 13,
-; CHECK-NEXT: = metadata !{i32 14,
-
-; RUN: opt %s -debug-ir -S | FileCheck %s
diff --git a/test/Transforms/DebugIR/vector.ll b/test/Transforms/DebugIR/vector.ll
deleted file mode 100644
index 50d99ac..0000000
--- a/test/Transforms/DebugIR/vector.ll
+++ /dev/null
@@ -1,93 +0,0 @@
-; ModuleID = 'vector.cpp'
-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-pc-linux-gnu"
-
-; Function Attrs: noinline nounwind uwtable
-define <4 x float> @_Z3fooDv2_fS_(double %a.coerce, double %b.coerce) #0 {
- %1 = alloca <2 x float>, align 8 ; CHECK: !dbg
- %2 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- %3 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- %4 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- %c = alloca <4 x float>, align 16 ; CHECK-NEXT: !dbg
- %5 = bitcast <2 x float>* %1 to double* ; CHECK-NEXT: !dbg
- store double %a.coerce, double* %5, align 1 ; CHECK-NEXT: !dbg
- %a = load <2 x float>* %1, align 8 ; CHECK-NEXT: !dbg
- store <2 x float> %a, <2 x float>* %2, align 8 ; CHECK-NEXT: !dbg
- %6 = bitcast <2 x float>* %3 to double* ; CHECK-NEXT: !dbg
- store double %b.coerce, double* %6, align 1 ; CHECK-NEXT: !dbg
- %b = load <2 x float>* %3, align 8 ; CHECK-NEXT: !dbg
- store <2 x float> %b, <2 x float>* %4, align 8 ; CHECK-NEXT: !dbg
- %7 = load <2 x float>* %2, align 8 ; CHECK-NEXT: !dbg
- %8 = load <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg
- %9 = shufflevector <2 x float> %7, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> ; CHECK-NEXT: !dbg
- %10 = shufflevector <4 x float> %8, <4 x float> %9, <4 x i32> <i32 4, i32 1, i32 5, i32 3> ; CHECK-NEXT: !dbg
- store <4 x float> %10, <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg
- %11 = load <2 x float>* %4, align 8 ; CHECK-NEXT: !dbg
- %12 = load <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg
- %13 = shufflevector <2 x float> %11, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> ; CHECK-NEXT: !dbg
- %14 = shufflevector <4 x float> %12, <4 x float> %13, <4 x i32> <i32 0, i32 4, i32 2, i32 5> ; CHECK-NEXT: !dbg
- store <4 x float> %14, <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg
- %15 = load <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg
- ret <4 x float> %15 ; CHECK-NEXT: !dbg
-}
-
-; Function Attrs: nounwind uwtable
-define i32 @main() #1 {
- %1 = alloca i32, align 4 ; CHECK: !dbg
- %a = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- %b = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- %x = alloca <4 x float>, align 16 ; CHECK-NEXT: !dbg
- %2 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- %3 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg
- store i32 0, i32* %1 ; CHECK-NEXT: !dbg
- store <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float>* %a, align 8 ; CHECK-NEXT: !dbg
- store <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float>* %b, align 8 ; CHECK-NEXT: !dbg
- %4 = load <2 x float>* %a, align 8 ; CHECK-NEXT: !dbg
- %5 = load <2 x float>* %b, align 8 ; CHECK-NEXT: !dbg
- store <2 x float> %4, <2 x float>* %2, align 8 ; CHECK-NEXT: !dbg
- %6 = bitcast <2 x float>* %2 to double* ; CHECK-NEXT: !dbg
- %7 = load double* %6, align 1 ; CHECK-NEXT: !dbg
- store <2 x float> %5, <2 x float>* %3, align 8 ; CHECK-NEXT: !dbg
- %8 = bitcast <2 x float>* %3 to double* ; CHECK-NEXT: !dbg
- %9 = load double* %8, align 1 ; CHECK-NEXT: !dbg
- %10 = call <4 x float> @_Z3fooDv2_fS_(double %7, double %9) ; CHECK-NEXT: !dbg
- store <4 x float> %10, <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg
- %11 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg
- %12 = extractelement <4 x float> %11, i32 0 ; CHECK-NEXT: !dbg
- %13 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg
- %14 = extractelement <4 x float> %13, i32 1 ; CHECK-NEXT: !dbg
- %15 = fadd float %12, %14 ; CHECK-NEXT: !dbg
- %16 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg
- %17 = extractelement <4 x float> %16, i32 2 ; CHECK-NEXT: !dbg
- %18 = fadd float %15, %17 ; CHECK-NEXT: !dbg
- %19 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg
- %20 = extractelement <4 x float> %19, i32 3 ; CHECK-NEXT: !dbg
- %21 = fadd float %18, %20 ; CHECK-NEXT: !dbg
- %22 = fptosi float %21 to i32 ; CHECK-NEXT: !dbg
- ret i32 %22 ; CHECK-NEXT: !dbg
-}
-
-attributes #0 = { noinline nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-
-; CHECK: = metadata !{i32 13,
-; CHECK-NEXT: = metadata !{i32 14,
-; CHECK-NEXT: = metadata !{i32 15,
-; CHECK-NEXT: = metadata !{i32 16,
-; CHECK-NEXT: = metadata !{i32 17,
-; CHECK-NEXT: = metadata !{i32 18,
-; CHECK-NEXT: = metadata !{i32 19,
-; CHECK-NEXT: = metadata !{i32 20,
-; CHECK-NEXT: = metadata !{i32 21,
-; CHECK-NEXT: = metadata !{i32 22,
-; CHECK-NEXT: = metadata !{i32 23,
-; CHECK-NEXT: = metadata !{i32 24,
-; CHECK-NEXT: = metadata !{i32 25,
-; CHECK-NEXT: = metadata !{i32 26,
-; CHECK-NEXT: = metadata !{i32 27,
-; CHECK-NEXT: = metadata !{i32 28,
-; CHECK-NEXT: = metadata !{i32 29,
-; CHECK-NEXT: = metadata !{i32 30,
-; CHECK-NEXT: = metadata !{i32 31,
-
-; RUN: opt %s -debug-ir -S | FileCheck %s
diff --git a/test/Transforms/EarlyCSE/AArch64/intrinsics.ll b/test/Transforms/EarlyCSE/AArch64/intrinsics.ll
new file mode 100644
index 0000000..d166ff1
--- /dev/null
+++ b/test/Transforms/EarlyCSE/AArch64/intrinsics.ll
@@ -0,0 +1,232 @@
+; RUN: opt < %s -S -mtriple=aarch64-none-linux-gnu -mattr=+neon -early-cse | FileCheck %s
+; RUN: opt < %s -S -mtriple=aarch64-none-linux-gnu -mattr=+neon -passes=early-cse | FileCheck %s
+
+define <4 x i32> @test_cse(i32* %a, [2 x <4 x i32>] %s.coerce, i32 %n) {
+entry:
+; Check that @llvm.aarch64.neon.ld2 is optimized away by Early CSE.
+; CHECK-LABEL: @test_cse
+; CHECK-NOT: call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8
+ %s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
+ %s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %res.0 = phi <4 x i32> [ undef, %entry ], [ %call, %for.body ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %0 = bitcast i32* %a to i8*
+ %1 = bitcast <4 x i32> %s.coerce.fca.0.extract to <16 x i8>
+ %2 = bitcast <4 x i32> %s.coerce.fca.1.extract to <16 x i8>
+ %3 = bitcast <16 x i8> %1 to <4 x i32>
+ %4 = bitcast <16 x i8> %2 to <4 x i32>
+ call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %4, i8* %0)
+ %5 = bitcast i32* %a to i8*
+ %vld2 = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8(i8* %5)
+ %vld2.fca.0.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 0
+ %vld2.fca.1.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 1
+ %call = call <4 x i32> @vaddq_s32(<4 x i32> %vld2.fca.0.extract, <4 x i32> %vld2.fca.0.extract)
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret <4 x i32> %res.0
+}
+
+define <4 x i32> @test_cse2(i32* %a, [2 x <4 x i32>] %s.coerce, i32 %n) {
+entry:
+; Check that the first @llvm.aarch64.neon.st2 is optimized away by Early CSE.
+; CHECK-LABEL: @test_cse2
+; CHECK-NOT: call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %3, i8* %0)
+; CHECK: call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %4, i8* %0)
+ %s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
+ %s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %res.0 = phi <4 x i32> [ undef, %entry ], [ %call, %for.body ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %0 = bitcast i32* %a to i8*
+ %1 = bitcast <4 x i32> %s.coerce.fca.0.extract to <16 x i8>
+ %2 = bitcast <4 x i32> %s.coerce.fca.1.extract to <16 x i8>
+ %3 = bitcast <16 x i8> %1 to <4 x i32>
+ %4 = bitcast <16 x i8> %2 to <4 x i32>
+ call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %3, i8* %0)
+ call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %4, i8* %0)
+ %5 = bitcast i32* %a to i8*
+ %vld2 = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8(i8* %5)
+ %vld2.fca.0.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 0
+ %vld2.fca.1.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 1
+ %call = call <4 x i32> @vaddq_s32(<4 x i32> %vld2.fca.0.extract, <4 x i32> %vld2.fca.0.extract)
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret <4 x i32> %res.0
+}
+
+define <4 x i32> @test_cse3(i32* %a, [2 x <4 x i32>] %s.coerce, i32 %n) #0 {
+entry:
+; Check that the first @llvm.aarch64.neon.ld2 is optimized away by Early CSE.
+; CHECK-LABEL: @test_cse3
+; CHECK: call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8
+; CHECK-NOT: call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8
+ %s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
+ %s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %res.0 = phi <4 x i32> [ undef, %entry ], [ %call, %for.body ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %0 = bitcast i32* %a to i8*
+ %vld2 = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8(i8* %0)
+ %vld2.fca.0.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 0
+ %vld2.fca.1.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 1
+ %1 = bitcast i32* %a to i8*
+ %vld22 = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8(i8* %1)
+ %vld22.fca.0.extract = extractvalue { <4 x i32>, <4 x i32> } %vld22, 0
+ %vld22.fca.1.extract = extractvalue { <4 x i32>, <4 x i32> } %vld22, 1
+ %call = call <4 x i32> @vaddq_s32(<4 x i32> %vld2.fca.0.extract, <4 x i32> %vld22.fca.0.extract)
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret <4 x i32> %res.0
+}
+
+
+define <4 x i32> @test_nocse(i32* %a, i32* %b, [2 x <4 x i32>] %s.coerce, i32 %n) {
+entry:
+; Check that the store prevents @llvm.aarch64.neon.ld2 from being optimized
+; away by Early CSE.
+; CHECK-LABEL: @test_nocse
+; CHECK: call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8
+ %s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
+ %s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %res.0 = phi <4 x i32> [ undef, %entry ], [ %call, %for.body ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %0 = bitcast i32* %a to i8*
+ %1 = bitcast <4 x i32> %s.coerce.fca.0.extract to <16 x i8>
+ %2 = bitcast <4 x i32> %s.coerce.fca.1.extract to <16 x i8>
+ %3 = bitcast <16 x i8> %1 to <4 x i32>
+ %4 = bitcast <16 x i8> %2 to <4 x i32>
+ call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %4, i8* %0)
+ store i32 0, i32* %b, align 4
+ %5 = bitcast i32* %a to i8*
+ %vld2 = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8(i8* %5)
+ %vld2.fca.0.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 0
+ %vld2.fca.1.extract = extractvalue { <4 x i32>, <4 x i32> } %vld2, 1
+ %call = call <4 x i32> @vaddq_s32(<4 x i32> %vld2.fca.0.extract, <4 x i32> %vld2.fca.0.extract)
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret <4 x i32> %res.0
+}
+
+define <4 x i32> @test_nocse2(i32* %a, [2 x <4 x i32>] %s.coerce, i32 %n) {
+entry:
+; Check that @llvm.aarch64.neon.ld3 is not optimized away by Early CSE due
+; to mismatch between st2 and ld3.
+; CHECK-LABEL: @test_nocse2
+; CHECK: call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i8
+ %s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
+ %s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %res.0 = phi <4 x i32> [ undef, %entry ], [ %call, %for.body ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %0 = bitcast i32* %a to i8*
+ %1 = bitcast <4 x i32> %s.coerce.fca.0.extract to <16 x i8>
+ %2 = bitcast <4 x i32> %s.coerce.fca.1.extract to <16 x i8>
+ %3 = bitcast <16 x i8> %1 to <4 x i32>
+ %4 = bitcast <16 x i8> %2 to <4 x i32>
+ call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %4, i8* %0)
+ %5 = bitcast i32* %a to i8*
+ %vld3 = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i8(i8* %5)
+ %vld3.fca.0.extract = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %vld3, 0
+ %vld3.fca.2.extract = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %vld3, 2
+ %call = call <4 x i32> @vaddq_s32(<4 x i32> %vld3.fca.0.extract, <4 x i32> %vld3.fca.2.extract)
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret <4 x i32> %res.0
+}
+
+define <4 x i32> @test_nocse3(i32* %a, [2 x <4 x i32>] %s.coerce, i32 %n) {
+entry:
+; Check that @llvm.aarch64.neon.st3 is not optimized away by Early CSE due to
+; mismatch between st2 and st3.
+; CHECK-LABEL: @test_nocse3
+; CHECK: call void @llvm.aarch64.neon.st3.v4i32.p0i8
+; CHECK: call void @llvm.aarch64.neon.st2.v4i32.p0i8
+ %s.coerce.fca.0.extract = extractvalue [2 x <4 x i32>] %s.coerce, 0
+ %s.coerce.fca.1.extract = extractvalue [2 x <4 x i32>] %s.coerce, 1
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %res.0 = phi <4 x i32> [ undef, %entry ], [ %call, %for.body ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %0 = bitcast i32* %a to i8*
+ %1 = bitcast <4 x i32> %s.coerce.fca.0.extract to <16 x i8>
+ %2 = bitcast <4 x i32> %s.coerce.fca.1.extract to <16 x i8>
+ %3 = bitcast <16 x i8> %1 to <4 x i32>
+ %4 = bitcast <16 x i8> %2 to <4 x i32>
+ call void @llvm.aarch64.neon.st3.v4i32.p0i8(<4 x i32> %4, <4 x i32> %3, <4 x i32> %3, i8* %0)
+ call void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32> %3, <4 x i32> %3, i8* %0)
+ %5 = bitcast i32* %a to i8*
+ %vld3 = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i8(i8* %5)
+ %vld3.fca.0.extract = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %vld3, 0
+ %vld3.fca.1.extract = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %vld3, 1
+ %call = call <4 x i32> @vaddq_s32(<4 x i32> %vld3.fca.0.extract, <4 x i32> %vld3.fca.0.extract)
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret <4 x i32> %res.0
+}
+
+; Function Attrs: nounwind
+declare void @llvm.aarch64.neon.st2.v4i32.p0i8(<4 x i32>, <4 x i32>, i8* nocapture)
+
+; Function Attrs: nounwind
+declare void @llvm.aarch64.neon.st3.v4i32.p0i8(<4 x i32>, <4 x i32>, <4 x i32>, i8* nocapture)
+
+; Function Attrs: nounwind readonly
+declare { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0i8(i8*)
+
+; Function Attrs: nounwind readonly
+declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i8(i8*)
+
+define internal fastcc <4 x i32> @vaddq_s32(<4 x i32> %__p0, <4 x i32> %__p1) {
+entry:
+ %add = add <4 x i32> %__p0, %__p1
+ ret <4 x i32> %add
+}
diff --git a/test/Transforms/EarlyCSE/AArch64/lit.local.cfg b/test/Transforms/EarlyCSE/AArch64/lit.local.cfg
new file mode 100644
index 0000000..6642d28
--- /dev/null
+++ b/test/Transforms/EarlyCSE/AArch64/lit.local.cfg
@@ -0,0 +1,5 @@
+config.suffixes = ['.ll']
+
+targets = set(config.root.targets_to_build.split())
+if not 'AArch64' in targets:
+ config.unsupported = True
diff --git a/test/Transforms/EarlyCSE/basic.ll b/test/Transforms/EarlyCSE/basic.ll
index 155d36f..a36a103 100644
--- a/test/Transforms/EarlyCSE/basic.ll
+++ b/test/Transforms/EarlyCSE/basic.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -S -early-cse | FileCheck %s
+; RUN: opt < %s -S -passes=early-cse | FileCheck %s
declare void @llvm.assume(i1) nounwind
@@ -192,4 +193,13 @@ define void @test11(i32 *%P) {
; CHECK-NEXT: ret void
}
-
+; CHECK-LABEL: @test12(
+define i32 @test12(i1 %B, i32* %P1, i32* %P2) {
+ %load0 = load i32* %P1
+ %1 = load atomic i32* %P2 seq_cst, align 4
+ %load1 = load i32* %P1
+ %sel = select i1 %B, i32 %load0, i32 %load1
+ ret i32 %sel
+ ; CHECK: load i32* %P1
+ ; CHECK: load i32* %P1
+}
diff --git a/test/Transforms/GCOVProfiling/function-numbering.ll b/test/Transforms/GCOVProfiling/function-numbering.ll
index 2480820..487f4ca 100644
--- a/test/Transforms/GCOVProfiling/function-numbering.ll
+++ b/test/Transforms/GCOVProfiling/function-numbering.ll
@@ -2,7 +2,7 @@
; functions aren't emitted.
; Inject metadata to set the .gcno file location
-; RUN: echo '!14 = metadata !{metadata !"%/T/function-numbering.ll", metadata !0}' > %t1
+; RUN: echo '!14 = !{!"%/T/function-numbering.ll", !0}' > %t1
; RUN: cat %s %t1 > %t2
; RUN: opt -insert-gcov-profiling -S < %t2 | FileCheck --check-prefix GCDA %s
@@ -40,17 +40,17 @@ define void @baz() {
!llvm.module.flags = !{!9, !10}
!llvm.ident = !{!11}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.6.0 \000\00\000\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [function-numbering.ll] [DW_LANG_C99]
-!1 = metadata !{metadata !".../llvm/test/Transforms/GCOVProfiling/function-numbering.ll", metadata !""}
-!2 = metadata !{}
-!3 = metadata !{metadata !4, metadata !7, metadata !8}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\001\000\001\000\000\000\000\001", metadata !1, metadata !5, metadata !6, null, void ()* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/Users/bogner/build/llvm-debug//tmp/foo.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !"0x2e\00bar\00bar\00\002\000\001\000\000\000\000\002", metadata !1, metadata !5, metadata !6, null, void ()* @bar, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 2] [def] [bar]
-!8 = metadata !{metadata !"0x2e\00baz\00baz\00\003\000\001\000\000\000\000\003", metadata !1, metadata !5, metadata !6, null, void ()* @baz, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 3] [def] [baz]
-!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!10 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!11 = metadata !{metadata !"clang version 3.6.0 "}
-!12 = metadata !{i32 1, i32 13, metadata !4, null}
-!13 = metadata !{i32 3, i32 13, metadata !8, null}
+!0 = !{!"0x11\0012\00clang version 3.6.0 \000\00\000\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [function-numbering.ll] [DW_LANG_C99]
+!1 = !{!".../llvm/test/Transforms/GCOVProfiling/function-numbering.ll", !""}
+!2 = !{}
+!3 = !{!4, !7, !8}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\000\000\000\001", !1, !5, !6, null, void ()* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/Users/bogner/build/llvm-debug//tmp/foo.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!"0x2e\00bar\00bar\00\002\000\001\000\000\000\000\002", !1, !5, !6, null, void ()* @bar, null, null, !2} ; [ DW_TAG_subprogram ] [line 2] [def] [bar]
+!8 = !{!"0x2e\00baz\00baz\00\003\000\001\000\000\000\000\003", !1, !5, !6, null, void ()* @baz, null, null, !2} ; [ DW_TAG_subprogram ] [line 3] [def] [baz]
+!9 = !{i32 2, !"Dwarf Version", i32 2}
+!10 = !{i32 2, !"Debug Info Version", i32 2}
+!11 = !{!"clang version 3.6.0 "}
+!12 = !MDLocation(line: 1, column: 13, scope: !4)
+!13 = !MDLocation(line: 3, column: 13, scope: !8)
diff --git a/test/Transforms/GCOVProfiling/global-ctor.ll b/test/Transforms/GCOVProfiling/global-ctor.ll
index 1dff3f0..9a9b7ce 100644
--- a/test/Transforms/GCOVProfiling/global-ctor.ll
+++ b/test/Transforms/GCOVProfiling/global-ctor.ll
@@ -1,4 +1,4 @@
-; RUN: echo '!16 = metadata !{metadata !"%/T/global-ctor.ll", metadata !0}' > %t1
+; RUN: echo '!16 = !{!"%/T/global-ctor.ll", !0}' > %t1
; RUN: cat %s %t1 > %t2
; RUN: opt -insert-gcov-profiling -disable-output < %t2
; RUN: not grep '_GLOBAL__sub_I_global-ctor' %T/global-ctor.gcno
@@ -38,19 +38,19 @@ attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "
!llvm.gcov = !{!16}
!llvm.ident = !{!12}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0 (trunk 210217)\000\00\000\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/home/nlewycky/<stdin>] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"<stdin>", metadata !"/home/nlewycky"}
-!2 = metadata !{}
-!3 = metadata !{metadata !4, metadata !8}
-!4 = metadata !{metadata !"0x2e\00__cxx_global_var_init\00__cxx_global_var_init\00\002\001\001\000\006\00256\000\002", metadata !5, metadata !6, metadata !7, null, void ()* @__cxx_global_var_init, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 2] [local] [def] [__cxx_global_var_init]
-!5 = metadata !{metadata !"global-ctor.ll", metadata !"/home/nlewycky"}
-!6 = metadata !{metadata !"0x29", metadata !5} ; [ DW_TAG_file_type ] [/home/nlewycky/global-ctor.ll]
-!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!8 = metadata !{metadata !"0x2e\00\00\00_GLOBAL__sub_I_global-ctor.ll\000\001\001\000\006\0064\000\000", metadata !1, metadata !9, metadata !7, null, void ()* @_GLOBAL__sub_I_global-ctor.ll, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 0] [local] [def]
-!9 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/home/nlewycky/<stdin>]
-!10 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!11 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!12 = metadata !{metadata !"clang version 3.5.0 (trunk 210217)"}
-!13 = metadata !{i32 2, i32 0, metadata !4, null}
-!14 = metadata !{i32 0, i32 0, metadata !15, null}
-!15 = metadata !{metadata !"0xb\000", metadata !5, metadata !8} ; [ DW_TAG_lexical_block ] [/home/nlewycky/global-ctor.ll]
+!0 = !{!"0x11\004\00clang version 3.5.0 (trunk 210217)\000\00\000\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/home/nlewycky/<stdin>] [DW_LANG_C_plus_plus]
+!1 = !{!"<stdin>", !"/home/nlewycky"}
+!2 = !{}
+!3 = !{!4, !8}
+!4 = !{!"0x2e\00__cxx_global_var_init\00__cxx_global_var_init\00\002\001\001\000\006\00256\000\002", !5, !6, !7, null, void ()* @__cxx_global_var_init, null, null, !2} ; [ DW_TAG_subprogram ] [line 2] [local] [def] [__cxx_global_var_init]
+!5 = !{!"global-ctor.ll", !"/home/nlewycky"}
+!6 = !{!"0x29", !5} ; [ DW_TAG_file_type ] [/home/nlewycky/global-ctor.ll]
+!7 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = !{!"0x2e\00\00\00_GLOBAL__sub_I_global-ctor.ll\000\001\001\000\006\0064\000\000", !1, !9, !7, null, void ()* @_GLOBAL__sub_I_global-ctor.ll, null, null, !2} ; [ DW_TAG_subprogram ] [line 0] [local] [def]
+!9 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/home/nlewycky/<stdin>]
+!10 = !{i32 2, !"Dwarf Version", i32 4}
+!11 = !{i32 2, !"Debug Info Version", i32 2}
+!12 = !{!"clang version 3.5.0 (trunk 210217)"}
+!13 = !MDLocation(line: 2, scope: !4)
+!14 = !MDLocation(line: 0, scope: !15)
+!15 = !{!"0xb\000", !5, !8} ; [ DW_TAG_lexical_block ] [/home/nlewycky/global-ctor.ll]
diff --git a/test/Transforms/GCOVProfiling/linezero.ll b/test/Transforms/GCOVProfiling/linezero.ll
index 50e026c..cf0fcd2 100644
--- a/test/Transforms/GCOVProfiling/linezero.ll
+++ b/test/Transforms/GCOVProfiling/linezero.ll
@@ -19,17 +19,17 @@ entry:
%__begin = alloca i8*, align 8
%__end = alloca i8*, align 8
%spec = alloca i8, align 1
- call void @llvm.dbg.declare(metadata !{%struct.vector** %__range}, metadata !27, metadata !{}), !dbg !30
+ call void @llvm.dbg.declare(metadata %struct.vector** %__range, metadata !27, metadata !{}), !dbg !30
br label %0
; <label>:0 ; preds = %entry
call void @_Z13TagFieldSpecsv(), !dbg !31
store %struct.vector* %ref.tmp, %struct.vector** %__range, align 8, !dbg !31
- call void @llvm.dbg.declare(metadata !{i8** %__begin}, metadata !32, metadata !{}), !dbg !30
+ call void @llvm.dbg.declare(metadata i8** %__begin, metadata !32, metadata !{}), !dbg !30
%1 = load %struct.vector** %__range, align 8, !dbg !31
%call = call i8* @_ZN6vector5beginEv(%struct.vector* %1), !dbg !31
store i8* %call, i8** %__begin, align 8, !dbg !31
- call void @llvm.dbg.declare(metadata !{i8** %__end}, metadata !33, metadata !{}), !dbg !30
+ call void @llvm.dbg.declare(metadata i8** %__end, metadata !33, metadata !{}), !dbg !30
%2 = load %struct.vector** %__range, align 8, !dbg !31
%call1 = call i8* @_ZN6vector3endEv(%struct.vector* %2), !dbg !31
store i8* %call1, i8** %__end, align 8, !dbg !31
@@ -42,7 +42,7 @@ for.cond: ; preds = %for.inc, %0
br i1 %cmp, label %for.body, label %for.end, !dbg !34
for.body: ; preds = %for.cond
- call void @llvm.dbg.declare(metadata !{i8* %spec}, metadata !37, metadata !{}), !dbg !31
+ call void @llvm.dbg.declare(metadata i8* %spec, metadata !37, metadata !{}), !dbg !31
%5 = load i8** %__begin, align 8, !dbg !38
%6 = load i8* %5, align 1, !dbg !38
store i8 %6, i8* %spec, align 1, !dbg !38
@@ -94,49 +94,49 @@ attributes #3 = { noreturn nounwind }
!llvm.gcov = !{!25}
!llvm.ident = !{!26}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0 (trunk 209871)\000\00\000\00\001", metadata !1, metadata !2, metadata !3, metadata !14, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [<stdin>] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"<stdin>", metadata !"PATTERN"}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x13\00vector\0021\008\008\000\000\000", metadata !5, null, null, metadata !6, null, null, metadata !"_ZTS6vector"} ; [ DW_TAG_structure_type ] [vector] [line 21, size 8, align 8, offset 0] [def] [from ]
-!5 = metadata !{metadata !"linezero.cc", metadata !"PATTERN"}
-!6 = metadata !{metadata !7, metadata !13}
-!7 = metadata !{metadata !"0x2e\00begin\00begin\00_ZN6vector5beginEv\0025\000\000\000\006\00256\000\0025", metadata !5, metadata !"_ZTS6vector", metadata !8, null, null, null, i32 0, null} ; [ DW_TAG_subprogram ] [line 25] [begin]
-!8 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !9, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!9 = metadata !{metadata !10, metadata !12}
-!10 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !11} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from char]
-!11 = metadata !{metadata !"0x24\00char\000\008\008\000\000\006", null, null} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
-!12 = metadata !{metadata !"0xf\00\000\0064\0064\000\001088", null, null, metadata !"_ZTS6vector"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS6vector]
-!13 = metadata !{metadata !"0x2e\00end\00end\00_ZN6vector3endEv\0026\000\000\000\006\00256\000\0026", metadata !5, metadata !"_ZTS6vector", metadata !8, null, null, null, i32 0, null} ; [ DW_TAG_subprogram ] [line 26] [end]
-!14 = metadata !{metadata !15, metadata !20}
-!15 = metadata !{metadata !"0x2e\00test\00test\00_Z4testv\0050\000\001\000\006\00256\000\0050", metadata !5, metadata !16, metadata !17, null, i32 ()* @_Z4testv, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 50] [def] [test]
-!16 = metadata !{metadata !"0x29", metadata !5} ; [ DW_TAG_file_type ] [./linezero.cc]
-!17 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!18 = metadata !{metadata !19}
-!19 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!20 = metadata !{metadata !"0x2e\00f1\00f1\00_Z2f1v\0054\000\001\000\006\00256\000\0054", metadata !5, metadata !16, metadata !21, null, void ()* @_Z2f1v, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 54] [def] [f1]
-!21 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !22, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!22 = metadata !{null}
-!23 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!24 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!25 = metadata !{metadata !"PATTERN/linezero.o", metadata !0}
-!26 = metadata !{metadata !"clang version 3.5.0 (trunk 209871)"}
-!27 = metadata !{metadata !"0x100\00__range\000\0064", metadata !28, null, metadata !29} ; [ DW_TAG_auto_variable ] [__range] [line 0]
-!28 = metadata !{metadata !"0xb\0051\000\000", metadata !5, metadata !15} ; [ DW_TAG_lexical_block ] [./linezero.cc]
-!29 = metadata !{metadata !"0x42\00\000\000\000\000\000", null, null, metadata !"_ZTS6vector"} ; [ DW_TAG_rvalue_reference_type ] [line 0, size 0, align 0, offset 0] [from _ZTS6vector]
-!30 = metadata !{i32 0, i32 0, metadata !28, null}
-!31 = metadata !{i32 51, i32 0, metadata !28, null}
-!32 = metadata !{metadata !"0x100\00__begin\000\0064", metadata !28, null, metadata !10} ; [ DW_TAG_auto_variable ] [__begin] [line 0]
-!33 = metadata !{metadata !"0x100\00__end\000\0064", metadata !28, null, metadata !10} ; [ DW_TAG_auto_variable ] [__end] [line 0]
-!34 = metadata !{i32 51, i32 0, metadata !35, null}
-!35 = metadata !{metadata !"0xb\0051\000\005", metadata !5, metadata !36} ; [ DW_TAG_lexical_block ] [./linezero.cc]
-!36 = metadata !{metadata !"0xb\0051\000\001", metadata !5, metadata !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
-!37 = metadata !{metadata !"0x100\00spec\0051\000", metadata !28, metadata !16, metadata !11} ; [ DW_TAG_auto_variable ] [spec] [line 51]
-!38 = metadata !{i32 51, i32 0, metadata !39, null}
-!39 = metadata !{metadata !"0xb\0051\000\002", metadata !5, metadata !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
-!40 = metadata !{i32 51, i32 0, metadata !41, null}
-!41 = metadata !{metadata !"0xb\0051\000\004", metadata !5, metadata !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
-!42 = metadata !{i32 51, i32 0, metadata !43, null}
-!43 = metadata !{metadata !"0xb\0051\000\003", metadata !5, metadata !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
-!44 = metadata !{i32 52, i32 0, metadata !15, null}
-!45 = metadata !{i32 54, i32 0, metadata !20, null}
+!0 = !{!"0x11\004\00clang version 3.5.0 (trunk 209871)\000\00\000\00\001", !1, !2, !3, !14, !2, !2} ; [ DW_TAG_compile_unit ] [<stdin>] [DW_LANG_C_plus_plus]
+!1 = !{!"<stdin>", !"PATTERN"}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x13\00vector\0021\008\008\000\000\000", !5, null, null, !6, null, null, !"_ZTS6vector"} ; [ DW_TAG_structure_type ] [vector] [line 21, size 8, align 8, offset 0] [def] [from ]
+!5 = !{!"linezero.cc", !"PATTERN"}
+!6 = !{!7, !13}
+!7 = !{!"0x2e\00begin\00begin\00_ZN6vector5beginEv\0025\000\000\000\006\00256\000\0025", !5, !"_ZTS6vector", !8, null, null, null, i32 0, null} ; [ DW_TAG_subprogram ] [line 25] [begin]
+!8 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !9, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!9 = !{!10, !12}
+!10 = !{!"0xf\00\000\0064\0064\000\000", null, null, !11} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from char]
+!11 = !{!"0x24\00char\000\008\008\000\000\006", null, null} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
+!12 = !{!"0xf\00\000\0064\0064\000\001088", null, null, !"_ZTS6vector"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS6vector]
+!13 = !{!"0x2e\00end\00end\00_ZN6vector3endEv\0026\000\000\000\006\00256\000\0026", !5, !"_ZTS6vector", !8, null, null, null, i32 0, null} ; [ DW_TAG_subprogram ] [line 26] [end]
+!14 = !{!15, !20}
+!15 = !{!"0x2e\00test\00test\00_Z4testv\0050\000\001\000\006\00256\000\0050", !5, !16, !17, null, i32 ()* @_Z4testv, null, null, !2} ; [ DW_TAG_subprogram ] [line 50] [def] [test]
+!16 = !{!"0x29", !5} ; [ DW_TAG_file_type ] [./linezero.cc]
+!17 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!18 = !{!19}
+!19 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!20 = !{!"0x2e\00f1\00f1\00_Z2f1v\0054\000\001\000\006\00256\000\0054", !5, !16, !21, null, void ()* @_Z2f1v, null, null, !2} ; [ DW_TAG_subprogram ] [line 54] [def] [f1]
+!21 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !22, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!22 = !{null}
+!23 = !{i32 2, !"Dwarf Version", i32 4}
+!24 = !{i32 2, !"Debug Info Version", i32 2}
+!25 = !{!"PATTERN/linezero.o", !0}
+!26 = !{!"clang version 3.5.0 (trunk 209871)"}
+!27 = !{!"0x100\00__range\000\0064", !28, null, !29} ; [ DW_TAG_auto_variable ] [__range] [line 0]
+!28 = !{!"0xb\0051\000\000", !5, !15} ; [ DW_TAG_lexical_block ] [./linezero.cc]
+!29 = !{!"0x42\00\000\000\000\000\000", null, null, !"_ZTS6vector"} ; [ DW_TAG_rvalue_reference_type ] [line 0, size 0, align 0, offset 0] [from _ZTS6vector]
+!30 = !MDLocation(line: 0, scope: !28)
+!31 = !MDLocation(line: 51, scope: !28)
+!32 = !{!"0x100\00__begin\000\0064", !28, null, !10} ; [ DW_TAG_auto_variable ] [__begin] [line 0]
+!33 = !{!"0x100\00__end\000\0064", !28, null, !10} ; [ DW_TAG_auto_variable ] [__end] [line 0]
+!34 = !MDLocation(line: 51, scope: !35)
+!35 = !{!"0xb\0051\000\005", !5, !36} ; [ DW_TAG_lexical_block ] [./linezero.cc]
+!36 = !{!"0xb\0051\000\001", !5, !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
+!37 = !{!"0x100\00spec\0051\000", !28, !16, !11} ; [ DW_TAG_auto_variable ] [spec] [line 51]
+!38 = !MDLocation(line: 51, scope: !39)
+!39 = !{!"0xb\0051\000\002", !5, !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
+!40 = !MDLocation(line: 51, scope: !41)
+!41 = !{!"0xb\0051\000\004", !5, !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
+!42 = !MDLocation(line: 51, scope: !43)
+!43 = !{!"0xb\0051\000\003", !5, !28} ; [ DW_TAG_lexical_block ] [./linezero.cc]
+!44 = !MDLocation(line: 52, scope: !15)
+!45 = !MDLocation(line: 54, scope: !20)
diff --git a/test/Transforms/GCOVProfiling/linkagename.ll b/test/Transforms/GCOVProfiling/linkagename.ll
index 04281b2..c30d4a6 100644
--- a/test/Transforms/GCOVProfiling/linkagename.ll
+++ b/test/Transforms/GCOVProfiling/linkagename.ll
@@ -1,4 +1,4 @@
-; RUN: echo '!9 = metadata !{metadata !"%/T/linkagename.ll", metadata !0}' > %t1
+; RUN: echo '!9 = !{!"%/T/linkagename.ll", !0}' > %t1
; RUN: cat %s %t1 > %t2
; RUN: opt -insert-gcov-profiling -disable-output < %t2
; RUN: grep _Z3foov %T/linkagename.gcno
@@ -13,15 +13,15 @@ entry:
!llvm.module.flags = !{!10}
!llvm.gcov = !{!9}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.3 (trunk 177323)\000\00\000\00\000", metadata !2, metadata !3, metadata !3, metadata !4, metadata !3, metadata !3} ; [ DW_TAG_compile_unit ] [/home/nlewycky/hello.cc] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"0x29", metadata !2} ; [ DW_TAG_file_type ] [/home/nlewycky/hello.cc]
-!2 = metadata !{metadata !"hello.cc", metadata !"/home/nlewycky"}
-!3 = metadata !{i32 0}
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x2e\00foo\00foo\00_Z3foov\001\000\001\000\006\00256\000\001", metadata !1, metadata !1, metadata !6, null, void ()* @_Z3foov, null, null, metadata !3} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{null}
-!8 = metadata !{i32 1, i32 0, metadata !5, null}
+!0 = !{!"0x11\004\00clang version 3.3 (trunk 177323)\000\00\000\00\000", !2, !3, !3, !4, !3, !3} ; [ DW_TAG_compile_unit ] [/home/nlewycky/hello.cc] [DW_LANG_C_plus_plus]
+!1 = !{!"0x29", !2} ; [ DW_TAG_file_type ] [/home/nlewycky/hello.cc]
+!2 = !{!"hello.cc", !"/home/nlewycky"}
+!3 = !{i32 0}
+!4 = !{!5}
+!5 = !{!"0x2e\00foo\00foo\00_Z3foov\001\000\001\000\006\00256\000\001", !1, !1, !6, null, void ()* @_Z3foov, null, null, !3} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{null}
+!8 = !MDLocation(line: 1, scope: !5)
-!10 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!10 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/GCOVProfiling/return-block.ll b/test/Transforms/GCOVProfiling/return-block.ll
new file mode 100644
index 0000000..f0be3d2
--- /dev/null
+++ b/test/Transforms/GCOVProfiling/return-block.ll
@@ -0,0 +1,66 @@
+; Inject metadata to set the .gcno file location
+; RUN: echo '!19 = !{!"%/T/return-block.ll", !0}' > %t1
+; RUN: cat %s %t1 > %t2
+; RUN: opt -insert-gcov-profiling -disable-output %t2
+; RUN: llvm-cov gcov -n -dump %T/return-block.gcno 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global i32 0, align 4
+
+; Function Attrs: nounwind uwtable
+define void @test() #0 {
+entry:
+ tail call void (...)* @f() #2, !dbg !14
+ %0 = load i32* @A, align 4, !dbg !15
+ %tobool = icmp eq i32 %0, 0, !dbg !15
+ br i1 %tobool, label %if.end, label %if.then, !dbg !15
+
+if.then: ; preds = %entry
+ tail call void (...)* @g() #2, !dbg !16
+ br label %if.end, !dbg !16
+
+if.end: ; preds = %entry, %if.then
+ ret void, !dbg !18
+}
+
+declare void @f(...) #1
+
+declare void @g(...) #1
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.gcov = !{!19}
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!11, !12}
+!llvm.ident = !{!13}
+
+!0 = !{!"0x11\0012\00clang version 3.6.0 (trunk 223182)\001\00\000\00\001", !1, !2, !2, !3, !8, !2} ; [ DW_TAG_compile_unit ] [return-block.c] [DW_LANG_C99]
+!1 = !{!".../llvm/test/Transforms/GCOVProfiling/return-block.ll", !""}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00test\00test\00\005\000\001\000\000\000\001\005", !1, !5, !6, null, void ()* @test, null, null, !2} ; [ DW_TAG_subprogram ] [line 5] [def] [test]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [return-block.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{null}
+!8 = !{!9}
+!9 = !{!"0x34\00A\00A\00\003\000\001", null, !5, !10, i32* @A, null} ; [ DW_TAG_variable ] [A] [line 3] [def]
+!10 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!11 = !{i32 2, !"Dwarf Version", i32 4}
+!12 = !{i32 2, !"Debug Info Version", i32 2}
+!13 = !{!"clang version 3.6.0 (trunk 223182)"}
+!14 = !MDLocation(line: 6, column: 3, scope: !4)
+!15 = !MDLocation(line: 7, column: 7, scope: !4)
+!16 = !MDLocation(line: 8, column: 5, scope: !17)
+!17 = !{!"0xb\007\007\000", !1, !4} ; [ DW_TAG_lexical_block ] [return-block.c]
+!18 = !MDLocation(line: 9, column: 1, scope: !4)
+
+; There should be no destination edges for block 1.
+; CHECK: Block : 0 Counter : 0
+; CHECK-NEXT: Destination Edges : 2 (0),
+; CHECK-NEXT: Block : 1 Counter : 0
+; CHECK-NEXT: Source Edges : 4 (0),
+; CHECK-NEXT: Block : 2 Counter : 0
diff --git a/test/Transforms/GCOVProfiling/version.ll b/test/Transforms/GCOVProfiling/version.ll
index 1af684e..9436bd6 100644
--- a/test/Transforms/GCOVProfiling/version.ll
+++ b/test/Transforms/GCOVProfiling/version.ll
@@ -1,4 +1,4 @@
-; RUN: echo '!9 = metadata !{metadata !"%/T/version.ll", metadata !0}' > %t1
+; RUN: echo '!9 = !{!"%/T/version.ll", !0}' > %t1
; RUN: cat %s %t1 > %t2
; RUN: opt -insert-gcov-profiling -disable-output < %t2
; RUN: head -c8 %T/version.gcno | grep '^oncg.204'
@@ -16,15 +16,15 @@ define void @test() {
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!12}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.3 (trunk 176994)\000\00\000\00\000", metadata !11, metadata !3, metadata !3, metadata !4, metadata !3, null} ; [ DW_TAG_compile_unit ] [./version] [DW_LANG_C_plus_plus]
-!2 = metadata !{metadata !"0x29", metadata !11} ; [ DW_TAG_file_type ]
-!3 = metadata !{i32 0}
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x2e\00test\00test\00\001\000\001\000\006\00256\000\001", metadata !10, metadata !6, metadata !7, null, void ()* @test, null, null, metadata !3} ; [ DW_TAG_subprogram ] [line 1] [def] [test]
-!6 = metadata !{metadata !"0x29", metadata !10} ; [ DW_TAG_file_type ]
-!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !3, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!8 = metadata !{i32 1, i32 0, metadata !5, null}
+!0 = !{!"0x11\004\00clang version 3.3 (trunk 176994)\000\00\000\00\000", !11, !3, !3, !4, !3, null} ; [ DW_TAG_compile_unit ] [./version] [DW_LANG_C_plus_plus]
+!2 = !{!"0x29", !11} ; [ DW_TAG_file_type ]
+!3 = !{i32 0}
+!4 = !{!5}
+!5 = !{!"0x2e\00test\00test\00\001\000\001\000\006\00256\000\001", !10, !6, !7, null, void ()* @test, null, null, !3} ; [ DW_TAG_subprogram ] [line 1] [def] [test]
+!6 = !{!"0x29", !10} ; [ DW_TAG_file_type ]
+!7 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !3, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = !MDLocation(line: 1, scope: !5)
;; !9 is added through the echo line at the top.
-!10 = metadata !{metadata !"<stdin>", metadata !"."}
-!11 = metadata !{metadata !"version", metadata !"/usr/local/google/home/nlewycky"}
-!12 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!10 = !{!"<stdin>", !"."}
+!11 = !{!"version", !"/usr/local/google/home/nlewycky"}
+!12 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/GVN/cond_br2.ll b/test/Transforms/GVN/cond_br2.ll
index 27e6f75..a7ca219 100644
--- a/test/Transforms/GVN/cond_br2.ll
+++ b/test/Transforms/GVN/cond_br2.ll
@@ -132,9 +132,9 @@ attributes #1 = { nounwind }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!0 = metadata !{metadata !"any pointer", metadata !1}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA"}
-!3 = metadata !{metadata !"int", metadata !1}
-!4 = metadata !{metadata !0, metadata !0, i64 0}
-!5 = metadata !{metadata !3, metadata !3, i64 0}
+!0 = !{!"any pointer", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"int", !1}
+!4 = !{!0, !0, i64 0}
+!5 = !{!3, !3, i64 0}
diff --git a/test/Transforms/GVN/condprop.ll b/test/Transforms/GVN/condprop.ll
index 708e4b2..845f88e 100644
--- a/test/Transforms/GVN/condprop.ll
+++ b/test/Transforms/GVN/condprop.ll
@@ -144,6 +144,22 @@ different:
ret i1 %cmp3
}
+; CHECK-LABEL: @test6_fp(
+define i1 @test6_fp(float %x, float %y) {
+ %cmp2 = fcmp une float %x, %y
+ %cmp = fcmp oeq float %x, %y
+ %cmp3 = fcmp oeq float %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-LABEL: @test7(
define i1 @test7(i32 %x, i32 %y) {
%cmp = icmp sgt i32 %x, %y
@@ -160,6 +176,22 @@ different:
ret i1 %cmp3
}
+; CHECK-LABEL: @test7_fp(
+define i1 @test7_fp(float %x, float %y) {
+ %cmp = fcmp ogt float %x, %y
+ br i1 %cmp, label %same, label %different
+
+same:
+ %cmp2 = fcmp ule float %x, %y
+; CHECK: ret i1 false
+ ret i1 %cmp2
+
+different:
+ %cmp3 = fcmp ogt float %x, %y
+; CHECK: ret i1 false
+ ret i1 %cmp3
+}
+
; CHECK-LABEL: @test8(
define i1 @test8(i32 %x, i32 %y) {
%cmp2 = icmp sle i32 %x, %y
@@ -176,6 +208,22 @@ different:
ret i1 %cmp3
}
+; CHECK-LABEL: @test8_fp(
+define i1 @test8_fp(float %x, float %y) {
+ %cmp2 = fcmp ule float %x, %y
+ %cmp = fcmp ogt float %x, %y
+ %cmp3 = fcmp ogt float %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-LABEL: @test9(
define i32 @test9(i32 %i, i32 %j) {
diff --git a/test/Transforms/GVN/edge.ll b/test/Transforms/GVN/edge.ll
index 646e10c..0c1a3fb 100644
--- a/test/Transforms/GVN/edge.ll
+++ b/test/Transforms/GVN/edge.ll
@@ -58,3 +58,113 @@ bb2:
; CHECK: call void @g(i1 %y)
ret void
}
+
+define double @fcmp_oeq_not_zero(double %x, double %y) {
+entry:
+ %cmp = fcmp oeq double %y, 2.0
+ br i1 %cmp, label %if, label %return
+
+if:
+ %div = fdiv double %x, %y
+ br label %return
+
+return:
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_oeq_not_zero(
+; CHECK: %div = fdiv double %x, 2.0
+}
+
+define double @fcmp_une_not_zero(double %x, double %y) {
+entry:
+ %cmp = fcmp une double %y, 2.0
+ br i1 %cmp, label %return, label %else
+
+else:
+ %div = fdiv double %x, %y
+ br label %return
+
+return:
+ %retval = phi double [ %div, %else ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_une_not_zero(
+; CHECK: %div = fdiv double %x, 2.0
+}
+
+; PR22376 - We can't propagate zero constants because -0.0
+; compares equal to 0.0. If %y is -0.0 in this test case,
+; we would produce the wrong sign on the infinity return value.
+define double @fcmp_oeq_zero(double %x, double %y) {
+entry:
+ %cmp = fcmp oeq double %y, 0.0
+ br i1 %cmp, label %if, label %return
+
+if:
+ %div = fdiv double %x, %y
+ br label %return
+
+return:
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_oeq_zero(
+; CHECK: %div = fdiv double %x, %y
+}
+
+define double @fcmp_une_zero(double %x, double %y) {
+entry:
+ %cmp = fcmp une double %y, -0.0
+ br i1 %cmp, label %return, label %else
+
+else:
+ %div = fdiv double %x, %y
+ br label %return
+
+return:
+ %retval = phi double [ %div, %else ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_une_zero(
+; CHECK: %div = fdiv double %x, %y
+}
+
+; We also cannot propagate a value if it's not a constant.
+; This is because the value could be 0.0 or -0.0.
+
+define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {
+entry:
+ %z = fadd double %z1, %z2
+ %cmp = fcmp oeq double %y, %z
+ br i1 %cmp, label %if, label %return
+
+if:
+ %div = fdiv double %x, %z
+ br label %return
+
+return:
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(
+; CHECK: %div = fdiv double %x, %z
+}
+
+define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {
+entry:
+ %z = fadd double %z1, %z2
+ %cmp = fcmp une double %y, %z
+ br i1 %cmp, label %return, label %else
+
+else:
+ %div = fdiv double %x, %z
+ br label %return
+
+return:
+ %retval = phi double [ %div, %else ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_une_maybe_zero(
+; CHECK: %div = fdiv double %x, %z
+}
diff --git a/test/Transforms/GVN/fpmath.ll b/test/Transforms/GVN/fpmath.ll
index 403df5c..d164fb5 100644
--- a/test/Transforms/GVN/fpmath.ll
+++ b/test/Transforms/GVN/fpmath.ll
@@ -41,5 +41,5 @@ define double @test4(double %x, double %y) {
ret double %foo
}
-!0 = metadata !{ float 5.0 }
-!1 = metadata !{ float 2.5 }
+!0 = !{ float 5.0 }
+!1 = !{ float 2.5 }
diff --git a/test/Transforms/GVN/invariant-load.ll b/test/Transforms/GVN/invariant-load.ll
index 80e2226..2a83c45 100644
--- a/test/Transforms/GVN/invariant-load.ll
+++ b/test/Transforms/GVN/invariant-load.ll
@@ -27,5 +27,43 @@ entry:
ret i32 %add
}
-!0 = metadata !{ }
+; With the invariant.load metadata, what would otherwise
+; be a case for PRE becomes a full redundancy.
+define i32 @test3(i1 %cnd, i32* %p, i32* %q) {
+; CHECK-LABEL: test3
+; CHECK-NOT: load
+entry:
+ %v1 = load i32* %p
+ br i1 %cnd, label %bb1, label %bb2
+
+bb1:
+ store i32 5, i32* %q
+ br label %bb2
+
+bb2:
+ %v2 = load i32* %p, !invariant.load !0
+ %res = sub i32 %v1, %v2
+ ret i32 %res
+}
+
+; This test is here to document a case which doesn't optimize
+; as well as it could.
+define i32 @test4(i1 %cnd, i32* %p, i32* %q) {
+; CHECK-LABEL: test4
+; %v2 is redundant, but GVN currently doesn't catch that
+entry:
+ %v1 = load i32* %p, !invariant.load !0
+ br i1 %cnd, label %bb1, label %bb2
+
+bb1:
+ store i32 5, i32* %q
+ br label %bb2
+
+bb2:
+ %v2 = load i32* %p
+ %res = sub i32 %v1, %v2
+ ret i32 %res
+}
+
+!0 = !{ }
diff --git a/test/Transforms/GVN/load-from-unreachable-predecessor.ll b/test/Transforms/GVN/load-from-unreachable-predecessor.ll
new file mode 100644
index 0000000..b676d95
--- /dev/null
+++ b/test/Transforms/GVN/load-from-unreachable-predecessor.ll
@@ -0,0 +1,20 @@
+; RUN: opt -gvn -S < %s | FileCheck %s
+
+; Check that an unreachable predecessor to a PHI node doesn't cause a crash.
+; PR21625.
+
+define i32 @f(i32** %f) {
+; CHECK: bb0:
+; Load should be removed, since it's ignored.
+; CHECK-NEXT: br label
+bb0:
+ %bar = load i32** %f
+ br label %bb2
+bb1:
+ %zed = load i32** %f
+ br i1 false, label %bb1, label %bb2
+bb2:
+ %foo = phi i32* [ null, %bb0 ], [ %zed, %bb1 ]
+ %storemerge = load i32* %foo
+ ret i32 %storemerge
+}
diff --git a/test/Transforms/GVN/load-pre-nonlocal.ll b/test/Transforms/GVN/load-pre-nonlocal.ll
index 7bac1b7..ae508b9 100644
--- a/test/Transforms/GVN/load-pre-nonlocal.ll
+++ b/test/Transforms/GVN/load-pre-nonlocal.ll
@@ -79,9 +79,9 @@ if.end:
ret i32 %add1
}
-!1 = metadata !{metadata !2, metadata !2, i64 0}
-!2 = metadata !{metadata !"any pointer", metadata !3, i64 0}
-!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
-!4 = metadata !{metadata !"Simple C/C++ TBAA"}
-!5 = metadata !{metadata !6, metadata !6, i64 0}
-!6 = metadata !{metadata !"int", metadata !3, i64 0}
+!1 = !{!2, !2, i64 0}
+!2 = !{!"any pointer", !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C/C++ TBAA"}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !3, i64 0}
diff --git a/test/Transforms/GVN/noalias.ll b/test/Transforms/GVN/noalias.ll
index a774f38..6c310fa 100644
--- a/test/Transforms/GVN/noalias.ll
+++ b/test/Transforms/GVN/noalias.ll
@@ -37,7 +37,7 @@ define i32 @test3(i32* %p, i32* %q) {
declare i32 @foo(i32*) readonly
-!0 = metadata !{metadata !0}
-!1 = metadata !{metadata !1}
-!2 = metadata !{metadata !0, metadata !1}
+!0 = !{!0}
+!1 = !{!1}
+!2 = !{!0, !1}
diff --git a/test/Transforms/GVN/pre-gep-load.ll b/test/Transforms/GVN/pre-gep-load.ll
new file mode 100644
index 0000000..3ee3a37
--- /dev/null
+++ b/test/Transforms/GVN/pre-gep-load.ll
@@ -0,0 +1,49 @@
+; RUN: opt < %s -basicaa -gvn -enable-load-pre -S | FileCheck %s
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-gnu"
+
+define double @foo(i32 %stat, i32 %i, double** %p) {
+; CHECK-LABEL: @foo(
+entry:
+ switch i32 %stat, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb2
+ ]
+
+sw.bb: ; preds = %entry, %entry
+ %idxprom = sext i32 %i to i64
+ %arrayidx = getelementptr inbounds double** %p, i64 0
+ %0 = load double** %arrayidx, align 8
+ %arrayidx1 = getelementptr inbounds double* %0, i64 %idxprom
+ %1 = load double* %arrayidx1, align 8
+ %sub = fsub double %1, 1.000000e+00
+ %cmp = fcmp olt double %sub, 0.000000e+00
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %sw.bb
+ br label %return
+
+if.end: ; preds = %sw.bb
+ br label %sw.bb2
+
+sw.bb2: ; preds = %if.end, %entry
+ %idxprom3 = sext i32 %i to i64
+ %arrayidx4 = getelementptr inbounds double** %p, i64 0
+ %2 = load double** %arrayidx4, align 8
+ %arrayidx5 = getelementptr inbounds double* %2, i64 %idxprom3
+ %3 = load double* %arrayidx5, align 8
+; CHECK: sw.bb2:
+; CHECK-NEXT-NOT: sext
+; CHECK-NEXT: phi double [
+; CHECK-NOT: load
+ %sub6 = fsub double 3.000000e+00, %3
+ br label %return
+
+sw.default: ; preds = %entry
+ br label %return
+
+return: ; preds = %sw.default, %sw.bb2, %if.then
+ %retval.0 = phi double [ 0.000000e+00, %sw.default ], [ %sub6, %sw.bb2 ], [ %sub, %if.then ]
+ ret double %retval.0
+}
diff --git a/test/Transforms/GVN/pre-no-cost-phi.ll b/test/Transforms/GVN/pre-no-cost-phi.ll
new file mode 100644
index 0000000..4c5afa1
--- /dev/null
+++ b/test/Transforms/GVN/pre-no-cost-phi.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -gvn -S | FileCheck %s
+; This testcase tests insertion of no-cost phis. That is,
+; when the value is already available in every predecessor,
+; and we just need to insert a phi node to merge the available values.
+
+@c = global i32 0, align 4
+@d = global i32 0, align 4
+
+
+define i32 @mai(i32 %foo, i32 %a, i32 %b) {
+ %1 = icmp ne i32 %foo, 0
+ br i1 %1, label %bb1, label %bb2
+
+bb1:
+ %2 = add nsw i32 %a, %b
+ store i32 %2, i32* @c, align 4
+ br label %mergeblock
+
+bb2:
+ %3 = add nsw i32 %a, %b
+ store i32 %3, i32* @d, align 4
+ br label %mergeblock
+
+mergeblock:
+; CHECK: pre-phi = phi i32 [ %3, %bb2 ], [ %2, %bb1 ]
+; CHECK-NEXT: ret i32 %.pre-phi
+ %4 = add nsw i32 %a, %b
+ ret i32 %4
+}
+
+
diff --git a/test/Transforms/GVN/preserve-tbaa.ll b/test/Transforms/GVN/preserve-tbaa.ll
index c52ed96..587d463 100644
--- a/test/Transforms/GVN/preserve-tbaa.ll
+++ b/test/Transforms/GVN/preserve-tbaa.ll
@@ -25,7 +25,7 @@ for.end: ; preds = %for.body, %entry
ret void
}
-!0 = metadata !{metadata !3, metadata !3, i64 0}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
-!3 = metadata !{metadata !"short", metadata !1}
+!0 = !{!3, !3, i64 0}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA", null}
+!3 = !{!"short", !1}
diff --git a/test/Transforms/GVN/range.ll b/test/Transforms/GVN/range.ll
index 2115fe8..3720232 100644
--- a/test/Transforms/GVN/range.ll
+++ b/test/Transforms/GVN/range.ll
@@ -82,20 +82,20 @@ define i32 @test8(i32* %p) {
ret i32 %c
}
-; CHECK: ![[DISJOINT_RANGE]] = metadata !{i32 0, i32 2, i32 3, i32 5}
-; CHECK: ![[MERGED_RANGE]] = metadata !{i32 0, i32 5}
-; CHECK: ![[MERGED_SIGNED_RANGE]] = metadata !{i32 -3, i32 -2, i32 1, i32 2}
-; CHECK: ![[MERGED_TEST6]] = metadata !{i32 10, i32 1}
-; CHECK: ![[MERGED_TEST7]] = metadata !{i32 3, i32 4, i32 5, i32 2}
+; CHECK: ![[DISJOINT_RANGE]] = !{i32 0, i32 2, i32 3, i32 5}
+; CHECK: ![[MERGED_RANGE]] = !{i32 0, i32 5}
+; CHECK: ![[MERGED_SIGNED_RANGE]] = !{i32 -3, i32 -2, i32 1, i32 2}
+; CHECK: ![[MERGED_TEST6]] = !{i32 10, i32 1}
+; CHECK: ![[MERGED_TEST7]] = !{i32 3, i32 4, i32 5, i32 2}
-!0 = metadata !{i32 0, i32 2}
-!1 = metadata !{i32 3, i32 5}
-!2 = metadata !{i32 2, i32 5}
-!3 = metadata !{i32 -3, i32 -2}
-!4 = metadata !{i32 1, i32 2}
-!5 = metadata !{i32 10, i32 1}
-!6 = metadata !{i32 12, i32 13}
-!7 = metadata !{i32 1, i32 2, i32 3, i32 4}
-!8 = metadata !{i32 5, i32 1}
-!9 = metadata !{i32 1, i32 5}
-!10 = metadata !{i32 5, i32 1}
+!0 = !{i32 0, i32 2}
+!1 = !{i32 3, i32 5}
+!2 = !{i32 2, i32 5}
+!3 = !{i32 -3, i32 -2}
+!4 = !{i32 1, i32 2}
+!5 = !{i32 10, i32 1}
+!6 = !{i32 12, i32 13}
+!7 = !{i32 1, i32 2, i32 3, i32 4}
+!8 = !{i32 5, i32 1}
+!9 = !{i32 1, i32 5}
+!10 = !{i32 5, i32 1}
diff --git a/test/Transforms/GVN/tbaa.ll b/test/Transforms/GVN/tbaa.ll
index d6412fc..71fbed41 100644
--- a/test/Transforms/GVN/tbaa.ll
+++ b/test/Transforms/GVN/tbaa.ll
@@ -1,4 +1,4 @@
-; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
+; RUN: opt -tbaa -basicaa -gvn -S < %s | FileCheck %s
define i32 @test1(i8* %p, i8* %q) {
; CHECK: @test1(i8* %p, i8* %q)
@@ -72,20 +72,57 @@ define i32 @test7(i8* %p, i8* %q) {
ret i32 %c
}
+
+
+define i32 @test8(i32* %p, i32* %q) {
+; CHECK-LABEL: test8
+; CHECK-NEXT: store i32 15, i32* %p
+; CHECK-NEXT: ret i32 0
+; Since we know the location is invariant, we can forward the
+; load across the potentially aliasing store.
+
+ %a = load i32* %q, !tbaa !10
+ store i32 15, i32* %p
+ %b = load i32* %q, !tbaa !10
+ %c = sub i32 %a, %b
+ ret i32 %c
+}
+define i32 @test9(i32* %p, i32* %q) {
+; CHECK-LABEL: test9
+; CHECK-NEXT: call void @clobber()
+; CHECK-NEXT: ret i32 0
+; Since we know the location is invariant, we can forward the
+; load across the potentially aliasing store (within the call).
+
+ %a = load i32* %q, !tbaa !10
+ call void @clobber()
+ %b = load i32* %q, !tbaa !10
+ %c = sub i32 %a, %b
+ ret i32 %c
+}
+
+
+declare void @clobber()
declare i32 @foo(i8*) readonly
-; CHECK: [[TAGC]] = metadata !{metadata [[TYPEC:!.*]], metadata [[TYPEC]], i64 0}
-; CHECK: [[TYPEC]] = metadata !{metadata !"C", metadata [[TYPEA:!.*]]}
-; CHECK: [[TYPEA]] = metadata !{metadata !"A", metadata !{{.*}}}
-; CHECK: [[TAGB]] = metadata !{metadata [[TYPEB:!.*]], metadata [[TYPEB]], i64 0}
-; CHECK: [[TYPEB]] = metadata !{metadata !"B", metadata [[TYPEA]]}
-; CHECK: [[TAGA]] = metadata !{metadata [[TYPEA]], metadata [[TYPEA]], i64 0}
-!0 = metadata !{metadata !5, metadata !5, i64 0}
-!1 = metadata !{metadata !6, metadata !6, i64 0}
-!2 = metadata !{metadata !"tbaa root", null}
-!3 = metadata !{metadata !7, metadata !7, i64 0}
-!4 = metadata !{metadata !8, metadata !8, i64 0}
-!5 = metadata !{metadata !"C", metadata !6}
-!6 = metadata !{metadata !"A", metadata !2}
-!7 = metadata !{metadata !"B", metadata !6}
-!8 = metadata !{metadata !"another root", null}
+; CHECK: [[TAGC]] = !{[[TYPEC:!.*]], [[TYPEC]], i64 0}
+; CHECK: [[TYPEC]] = !{!"C", [[TYPEA:!.*]]}
+; CHECK: [[TYPEA]] = !{!"A", !{{.*}}}
+; CHECK: [[TAGB]] = !{[[TYPEB:!.*]], [[TYPEB]], i64 0}
+; CHECK: [[TYPEB]] = !{!"B", [[TYPEA]]}
+; CHECK: [[TAGA]] = !{[[TYPEA]], [[TYPEA]], i64 0}
+!0 = !{!5, !5, i64 0}
+!1 = !{!6, !6, i64 0}
+!2 = !{!"tbaa root", null}
+!3 = !{!7, !7, i64 0}
+!4 = !{!8, !8, i64 0}
+!5 = !{!"C", !6}
+!6 = !{!"A", !2}
+!7 = !{!"B", !6}
+!8 = !{!"another root", null}
+
+
+;; A TBAA structure who's only point is to have a constant location
+!9 = !{!"yet another root"}
+!10 = !{!"node", !9, i64 1}
+
diff --git a/test/Transforms/GVN/volatile.ll b/test/Transforms/GVN/volatile.ll
new file mode 100644
index 0000000..5ba03d9
--- /dev/null
+++ b/test/Transforms/GVN/volatile.ll
@@ -0,0 +1,157 @@
+; Tests that check our handling of volatile instructions encountered
+; when scanning for dependencies
+; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
+
+; Check that we can bypass a volatile load when searching
+; for dependencies of a non-volatile load
+define i32 @test1(i32* nocapture %p, i32* nocapture %q) {
+; CHECK-LABEL: test1
+; CHECK: %0 = load volatile i32* %q
+; CHECK-NEXT: ret i32 0
+entry:
+ %x = load i32* %p
+ load volatile i32* %q
+ %y = load i32* %p
+ %add = sub i32 %y, %x
+ ret i32 %add
+}
+
+; We can not value forward if the query instruction is
+; volatile, this would be (in effect) removing the volatile load
+define i32 @test2(i32* nocapture %p, i32* nocapture %q) {
+; CHECK-LABEL: test2
+; CHECK: %x = load i32* %p
+; CHECK-NEXT: %y = load volatile i32* %p
+; CHECK-NEXT: %add = sub i32 %y, %x
+entry:
+ %x = load i32* %p
+ %y = load volatile i32* %p
+ %add = sub i32 %y, %x
+ ret i32 %add
+}
+
+; If the query instruction is itself volatile, we *cannot*
+; reorder it even if p and q are noalias
+define i32 @test3(i32* noalias nocapture %p, i32* noalias nocapture %q) {
+; CHECK-LABEL: test3
+; CHECK: %x = load i32* %p
+; CHECK-NEXT: %0 = load volatile i32* %q
+; CHECK-NEXT: %y = load volatile i32* %p
+entry:
+ %x = load i32* %p
+ load volatile i32* %q
+ %y = load volatile i32* %p
+ %add = sub i32 %y, %x
+ ret i32 %add
+}
+
+; If an encountered instruction is both volatile and ordered,
+; we need to use the strictest ordering of either. In this
+; case, the ordering prevents forwarding.
+define i32 @test4(i32* noalias nocapture %p, i32* noalias nocapture %q) {
+; CHECK-LABEL: test4
+; CHECK: %x = load i32* %p
+; CHECK-NEXT: %0 = load atomic volatile i32* %q seq_cst
+; CHECK-NEXT: %y = load atomic i32* %p seq_cst
+entry:
+ %x = load i32* %p
+ load atomic volatile i32* %q seq_cst, align 4
+ %y = load atomic i32* %p seq_cst, align 4
+ %add = sub i32 %y, %x
+ ret i32 %add
+}
+
+; Value forwarding from a volatile load is perfectly legal
+define i32 @test5(i32* nocapture %p, i32* nocapture %q) {
+; CHECK-LABEL: test5
+; CHECK: %x = load volatile i32* %p
+; CHECK-NEXT: ret i32 0
+entry:
+ %x = load volatile i32* %p
+ %y = load i32* %p
+ %add = sub i32 %y, %x
+ ret i32 %add
+}
+
+; Does cross block redundancy elimination work with volatiles?
+define i32 @test6(i32* noalias nocapture %p, i32* noalias nocapture %q) {
+; CHECK-LABEL: test6
+; CHECK: %y1 = load i32* %p
+; CHECK-LABEL: header
+; CHECK: %x = load volatile i32* %q
+; CHECK-NEXT: %add = sub i32 %y1, %x
+entry:
+ %y1 = load i32* %p
+ call void @use(i32 %y1)
+ br label %header
+header:
+ %x = load volatile i32* %q
+ %y = load i32* %p
+ %add = sub i32 %y, %x
+ %cnd = icmp eq i32 %add, 0
+ br i1 %cnd, label %exit, label %header
+exit:
+ ret i32 %add
+}
+
+; Does cross block PRE work with volatiles?
+define i32 @test7(i1 %c, i32* noalias nocapture %p, i32* noalias nocapture %q) {
+; CHECK-LABEL: test7
+; CHECK-LABEL: entry.header_crit_edge:
+; CHECK: %y.pre = load i32* %p
+; CHECK-LABEL: skip:
+; CHECK: %y1 = load i32* %p
+; CHECK-LABEL: header:
+; CHECK: %y = phi i32
+; CHECK-NEXT: %x = load volatile i32* %q
+; CHECK-NEXT: %add = sub i32 %y, %x
+entry:
+ br i1 %c, label %header, label %skip
+skip:
+ %y1 = load i32* %p
+ call void @use(i32 %y1)
+ br label %header
+header:
+ %x = load volatile i32* %q
+ %y = load i32* %p
+ %add = sub i32 %y, %x
+ %cnd = icmp eq i32 %add, 0
+ br i1 %cnd, label %exit, label %header
+exit:
+ ret i32 %add
+}
+
+; Another volatile PRE case - two paths through a loop
+; load in preheader, one path read only, one not
+define i32 @test8(i1 %b, i1 %c, i32* noalias %p, i32* noalias %q) {
+; CHECK-LABEL: test8
+; CHECK-LABEL: entry
+; CHECK: %y1 = load i32* %p
+; CHECK-LABEL: header:
+; CHECK: %y = phi i32
+; CHECK-NEXT: %x = load volatile i32* %q
+; CHECK-NOT: load
+; CHECK-LABEL: skip.header_crit_edge:
+; CHECK: %y.pre = load i32* %p
+entry:
+ %y1 = load i32* %p
+ call void @use(i32 %y1)
+ br label %header
+header:
+ %x = load volatile i32* %q
+ %y = load i32* %p
+ call void @use(i32 %y)
+ br i1 %b, label %skip, label %header
+skip:
+ ; escaping the arguments is explicitly required since we marked
+ ; them noalias
+ call void @clobber(i32* %p, i32* %q)
+ br i1 %c, label %header, label %exit
+exit:
+ %add = sub i32 %y, %x
+ ret i32 %add
+}
+
+declare void @use(i32) readonly
+declare void @clobber(i32* %p, i32* %q)
+
diff --git a/test/Transforms/GlobalDCE/pr20981.ll b/test/Transforms/GlobalDCE/pr20981.ll
index 92d2840..0eaa6b8 100644
--- a/test/Transforms/GlobalDCE/pr20981.ll
+++ b/test/Transforms/GlobalDCE/pr20981.ll
@@ -6,10 +6,10 @@ $c1 = comdat any
@a1 = linkonce_odr alias void ()* @f1
; CHECK: @a1 = linkonce_odr alias void ()* @f1
-define linkonce_odr void @f1() comdat $c1 {
+define linkonce_odr void @f1() comdat($c1) {
ret void
}
-; CHECK: define linkonce_odr void @f1() comdat $c1
+; CHECK: define linkonce_odr void @f1() comdat($c1)
define void @g() {
call void @f1()
diff --git a/test/Transforms/GlobalOpt/2009-03-05-dbg.ll b/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
index 0513829..049eef1 100644
--- a/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
+++ b/test/Transforms/GlobalOpt/2009-03-05-dbg.ll
@@ -6,14 +6,14 @@
define i32 @foo(i32 %i) nounwind ssp {
entry:
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !3, metadata !{})
+ call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !3, metadata !{})
%0 = icmp eq i32 %i, 1, !dbg !7 ; <i1> [#uses=1]
br i1 %0, label %bb, label %bb1, !dbg !7
bb: ; preds = %entry
store i32 0, i32* @Stop, align 4, !dbg !9
%1 = mul nsw i32 %i, 42, !dbg !10 ; <i32> [#uses=1]
- call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !3, metadata !{}), !dbg !10
+ call void @llvm.dbg.value(metadata i32 %1, i64 0, metadata !3, metadata !{}), !dbg !10
br label %bb2, !dbg !10
bb1: ; preds = %entry
@@ -55,25 +55,25 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.gv = !{!0}
-!0 = metadata !{metadata !"0x34\00Stop\00Stop\00\002\001\001", metadata !1, metadata !1, metadata !2, i32* @Stop} ; [ DW_TAG_variable ]
-!1 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", metadata !20, metadata !21, metadata !21, null, null, null} ; [ DW_TAG_compile_unit ]
-!2 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !1} ; [ DW_TAG_base_type ]
-!3 = metadata !{metadata !"0x101\00i\004\000", metadata !4, metadata !1, metadata !2} ; [ DW_TAG_arg_variable ]
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00foo\004\000\001\000\006\000\000\000", i32 0, metadata !1, metadata !5, null, null, null, null, null} ; [ DW_TAG_subprogram ]
-!5 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !1, null, null, metadata !6, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!6 = metadata !{metadata !2, metadata !2}
-!7 = metadata !{i32 5, i32 0, metadata !8, null}
-!8 = metadata !{metadata !"0xb\000\000\000", metadata !20, metadata !4} ; [ DW_TAG_lexical_block ]
-!9 = metadata !{i32 6, i32 0, metadata !8, null}
-!10 = metadata !{i32 7, i32 0, metadata !8, null}
-!11 = metadata !{i32 9, i32 0, metadata !8, null}
-!12 = metadata !{i32 11, i32 0, metadata !8, null}
-!13 = metadata !{i32 14, i32 0, metadata !14, null}
-!14 = metadata !{metadata !"0xb\000\000\000", metadata !20, metadata !15} ; [ DW_TAG_lexical_block ]
-!15 = metadata !{metadata !"0x2e\00bar\00bar\00bar\0013\000\001\000\006\000\000\000", i32 0, metadata !1, metadata !16, null, null, null, null, null} ; [ DW_TAG_subprogram ]
-!16 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !1, null, null, metadata !17, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!17 = metadata !{metadata !2}
-!18 = metadata !{i32 15, i32 0, metadata !14, null}
-!19 = metadata !{i32 16, i32 0, metadata !14, null}
-!20 = metadata !{metadata !"g.c", metadata !"/tmp"}
-!21 = metadata !{i32 0}
+!0 = !{!"0x34\00Stop\00Stop\00\002\001\001", !1, !1, !2, i32* @Stop} ; [ DW_TAG_variable ]
+!1 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", !20, !21, !21, null, null, null} ; [ DW_TAG_compile_unit ]
+!2 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !1} ; [ DW_TAG_base_type ]
+!3 = !{!"0x101\00i\004\000", !4, !1, !2} ; [ DW_TAG_arg_variable ]
+!4 = !{!"0x2e\00foo\00foo\00foo\004\000\001\000\006\000\000\000", i32 0, !1, !5, null, null, null, null, null} ; [ DW_TAG_subprogram ]
+!5 = !{!"0x15\00\000\000\000\000\000\000", !1, null, null, !6, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!6 = !{!2, !2}
+!7 = !MDLocation(line: 5, scope: !8)
+!8 = !{!"0xb\000\000\000", !20, !4} ; [ DW_TAG_lexical_block ]
+!9 = !MDLocation(line: 6, scope: !8)
+!10 = !MDLocation(line: 7, scope: !8)
+!11 = !MDLocation(line: 9, scope: !8)
+!12 = !MDLocation(line: 11, scope: !8)
+!13 = !MDLocation(line: 14, scope: !14)
+!14 = !{!"0xb\000\000\000", !20, !15} ; [ DW_TAG_lexical_block ]
+!15 = !{!"0x2e\00bar\00bar\00bar\0013\000\001\000\006\000\000\000", i32 0, !1, !16, null, null, null, null, null} ; [ DW_TAG_subprogram ]
+!16 = !{!"0x15\00\000\000\000\000\000\000", !1, null, null, !17, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!17 = !{!2}
+!18 = !MDLocation(line: 15, scope: !14)
+!19 = !MDLocation(line: 16, scope: !14)
+!20 = !{!"g.c", !"/tmp"}
+!21 = !{i32 0}
diff --git a/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll b/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll
index 9295c20..675211b 100644
--- a/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll
+++ b/test/Transforms/GlobalOpt/externally-initialized-global-ctr.ll
@@ -32,4 +32,4 @@ define void @print() {
ret void
}
-!2009 = metadata !{}
+!2009 = !{}
diff --git a/test/Transforms/GlobalOpt/metadata.ll b/test/Transforms/GlobalOpt/metadata.ll
index ecf3f94..fb60b66 100644
--- a/test/Transforms/GlobalOpt/metadata.ll
+++ b/test/Transforms/GlobalOpt/metadata.ll
@@ -13,14 +13,20 @@ define i32 @main(i32 %argc, i8** %argv) {
}
define void @foo(i32 %x) {
- call void @llvm.foo(metadata !{i8*** @G, i32 %x})
-; CHECK: call void @llvm.foo(metadata !{null, i32 %x})
+; Note: these arguments look like MDNodes, but they're really syntactic sugar
+; for 'MetadataAsValue::get(ValueAsMetadata::get(Value*))'. When @G drops to
+; null, the ValueAsMetadata instance gets replaced by metadata !{}, or
+; MDNode::get({}).
+ call void @llvm.foo(metadata i8*** @G, metadata i32 %x)
+; CHECK: call void @llvm.foo(metadata ![[EMPTY:[0-9]+]], metadata i32 %x)
ret void
}
-declare void @llvm.foo(metadata) nounwind readnone
+declare void @llvm.foo(metadata, metadata) nounwind readnone
!named = !{!0}
+; CHECK: !named = !{![[NULL:[0-9]+]]}
-!0 = metadata !{i8*** @G}
-; CHECK: !0 = metadata !{null}
+!0 = !{i8*** @G}
+; CHECK-DAG: ![[NULL]] = !{null}
+; CHECK-DAG: ![[EMPTY]] = !{}
diff --git a/test/Transforms/GlobalOpt/pr21191.ll b/test/Transforms/GlobalOpt/pr21191.ll
index 39b8eee..34e15cb 100644
--- a/test/Transforms/GlobalOpt/pr21191.ll
+++ b/test/Transforms/GlobalOpt/pr21191.ll
@@ -3,15 +3,15 @@
$c = comdat any
; CHECK: $c = comdat any
-define linkonce_odr void @foo() comdat $c {
+define linkonce_odr void @foo() comdat($c) {
ret void
}
-; CHECK: define linkonce_odr void @foo() comdat $c
+; CHECK: define linkonce_odr void @foo() comdat($c)
-define linkonce_odr void @bar() comdat $c {
+define linkonce_odr void @bar() comdat($c) {
ret void
}
-; CHECK: define linkonce_odr void @bar() comdat $c
+; CHECK: define linkonce_odr void @bar() comdat($c)
define void @zed() {
call void @foo()
diff --git a/test/Transforms/GlobalOpt/preserve-comdats.ll b/test/Transforms/GlobalOpt/preserve-comdats.ll
index 08188b9..0148f00 100644
--- a/test/Transforms/GlobalOpt/preserve-comdats.ll
+++ b/test/Transforms/GlobalOpt/preserve-comdats.ll
@@ -2,9 +2,9 @@
$comdat_global = comdat any
-@comdat_global = weak_odr global i8 0, comdat $comdat_global
+@comdat_global = weak_odr global i8 0, comdat($comdat_global)
@simple_global = internal global i8 0
-; CHECK: @comdat_global = weak_odr global i8 0, comdat $comdat_global
+; CHECK: @comdat_global = weak_odr global i8 0, comdat{{$}}
; CHECK: @simple_global = internal global i8 42
@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [
@@ -20,7 +20,7 @@ define void @init_comdat_global() {
}
; CHECK: define void @init_comdat_global()
-define internal void @init_simple_global() comdat $comdat_global {
+define internal void @init_simple_global() comdat($comdat_global) {
store i8 42, i8* @simple_global
ret void
}
diff --git a/test/Transforms/IRCE/bug-mismatched-types.ll b/test/Transforms/IRCE/bug-mismatched-types.ll
new file mode 100644
index 0000000..9ff7249
--- /dev/null
+++ b/test/Transforms/IRCE/bug-mismatched-types.ll
@@ -0,0 +1,66 @@
+; RUN: opt -irce -S < %s
+
+; These test cases don't check the correctness of the transform, but
+; that the -irce does not crash in the presence of certain things in
+; the IR:
+
+define void @mismatched_types_1() {
+; In this test case, the safe range for the only range check in the
+; loop is of type [i32, i32) while the backedge taken count is of type
+; i64.
+
+; CHECK-LABEL: mismatched_types_1
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]
+ %0 = trunc i64 %indvars.iv to i32
+ %1 = icmp ult i32 %0, 7
+ br i1 %1, label %switch.lookup, label %for.inc
+
+switch.lookup:
+ br label %for.inc
+
+for.inc:
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %cmp55 = icmp slt i64 %indvars.iv.next, 11
+ br i1 %cmp55, label %for.body, label %for.end
+
+for.end:
+ unreachable
+}
+
+define void @mismatched_types_2() {
+; In this test case, there are two range check in the loop, one with a
+; safe range of type [i32, i32) and one with a safe range of type
+; [i64, i64).
+
+; CHECK-LABEL: mismatched_types_2
+entry:
+ br label %for.body.a
+
+for.body.a:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]
+ %cond.a = icmp ult i64 %indvars.iv, 7
+ br i1 %cond.a, label %switch.lookup.a, label %for.body.b
+
+switch.lookup.a:
+ br label %for.body.b
+
+for.body.b:
+ %truncated = trunc i64 %indvars.iv to i32
+ %cond.b = icmp ult i32 %truncated, 7
+ br i1 %cond.b, label %switch.lookup.b, label %for.inc
+
+switch.lookup.b:
+ br label %for.inc
+
+for.inc:
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %cmp55 = icmp slt i64 %indvars.iv.next, 11
+ br i1 %cmp55, label %for.body.a, label %for.end
+
+for.end:
+ unreachable
+}
diff --git a/test/Transforms/IRCE/decrementing-loop.ll b/test/Transforms/IRCE/decrementing-loop.ll
new file mode 100644
index 0000000..877a2c2
--- /dev/null
+++ b/test/Transforms/IRCE/decrementing-loop.ll
@@ -0,0 +1,43 @@
+; RUN: opt -irce -S < %s | FileCheck %s
+
+define void @decrementing_loop(i32 *%arr, i32 *%a_len_ptr, i32 %n) {
+ entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ %start = sub i32 %n, 1
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ %start, %entry ] , [ %idx.dec, %in.bounds ]
+ %idx.dec = sub i32 %idx, 1
+ %abc.high = icmp slt i32 %idx, %len
+ %abc.low = icmp sge i32 %idx, 0
+ %abc = and i1 %abc.low, %abc.high
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+ in.bounds:
+ %addr = getelementptr i32* %arr, i32 %idx
+ store i32 0, i32* %addr
+ %next = icmp sgt i32 %idx.dec, -1
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+
+; CHECK: loop.preheader:
+; CHECK: [[indvar_start:[^ ]+]] = add i32 %n, -1
+; CHECK: [[not_len:[^ ]+]] = sub i32 -1, %len
+; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n
+; CHECK: [[not_len_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_len]], [[not_n]]
+; CHECK: [[not_len_hiclamp:[^ ]+]] = select i1 [[not_len_hiclamp_cmp]], i32 [[not_len]], i32 [[not_n]]
+; CHECK: [[len_hiclamp:[^ ]+]] = sub i32 -1, [[not_len_hiclamp]]
+; CHECK: [[not_exit_preloop_at_cmp:[^ ]+]] = icmp sgt i32 [[len_hiclamp]], 0
+; CHECK: [[not_exit_preloop_at:[^ ]+]] = select i1 [[not_exit_preloop_at_cmp]], i32 [[len_hiclamp]], i32 0
+; CHECK: %exit.preloop.at = add i32 [[not_exit_preloop_at]], -1
+}
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 64, i32 4}
diff --git a/test/Transforms/IRCE/low-becount.ll b/test/Transforms/IRCE/low-becount.ll
new file mode 100644
index 0000000..2ddaf19
--- /dev/null
+++ b/test/Transforms/IRCE/low-becount.ll
@@ -0,0 +1,32 @@
+; RUN: opt -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
+
+; CHECK-NOT: constrained Loop
+
+define void @low_profiled_be_count(i32 *%arr, i32 *%a_len_ptr, i32 %n) {
+ entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %abc = icmp slt i32 %idx, %len
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+ in.bounds:
+ %addr = getelementptr i32* %arr, i32 %idx
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit, !prof !2
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 64, i32 4}
+!2 = !{!"branch_weights", i32 4, i32 64}
diff --git a/test/Transforms/IRCE/multiple-access-no-preloop.ll b/test/Transforms/IRCE/multiple-access-no-preloop.ll
new file mode 100644
index 0000000..304bb4d
--- /dev/null
+++ b/test/Transforms/IRCE/multiple-access-no-preloop.ll
@@ -0,0 +1,66 @@
+; RUN: opt -irce -S < %s | FileCheck %s
+
+define void @multiple_access_no_preloop(
+ i32* %arr_a, i32* %a_len_ptr, i32* %arr_b, i32* %b_len_ptr, i32 %n) {
+
+ entry:
+ %len.a = load i32* %a_len_ptr, !range !0
+ %len.b = load i32* %b_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds.b ]
+ %idx.next = add i32 %idx, 1
+ %abc.a = icmp slt i32 %idx, %len.a
+ br i1 %abc.a, label %in.bounds.a, label %out.of.bounds, !prof !1
+
+ in.bounds.a:
+ %addr.a = getelementptr i32* %arr_a, i32 %idx
+ store i32 0, i32* %addr.a
+ %abc.b = icmp slt i32 %idx, %len.b
+ br i1 %abc.b, label %in.bounds.b, label %out.of.bounds, !prof !1
+
+ in.bounds.b:
+ %addr.b = getelementptr i32* %arr_b, i32 %idx
+ store i32 -1, i32* %addr.b
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+; CHECK-LABEL: multiple_access_no_preloop
+
+; CHECK-LABEL: loop.preheader:
+; CHECK: [[not_len_b:[^ ]+]] = sub i32 -1, %len.b
+; CHECK: [[not_len_a:[^ ]+]] = sub i32 -1, %len.a
+; CHECK: [[smax_not_len_cond:[^ ]+]] = icmp sgt i32 [[not_len_b]], [[not_len_a]]
+; CHECK: [[smax_not_len:[^ ]+]] = select i1 [[smax_not_len_cond]], i32 [[not_len_b]], i32 [[not_len_a]]
+; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n
+; CHECK: [[not_upper_limit_cond_loclamp:[^ ]+]] = icmp sgt i32 [[smax_not_len]], [[not_n]]
+; CHECK: [[not_upper_limit_loclamp:[^ ]+]] = select i1 [[not_upper_limit_cond_loclamp]], i32 [[smax_not_len]], i32 [[not_n]]
+; CHECK: [[upper_limit_loclamp:[^ ]+]] = sub i32 -1, [[not_upper_limit_loclamp]]
+; CHECK: [[upper_limit_cmp:[^ ]+]] = icmp sgt i32 [[upper_limit_loclamp]], 0
+; CHECK: [[upper_limit:[^ ]+]] = select i1 [[upper_limit_cmp]], i32 [[upper_limit_loclamp]], i32 0
+
+; CHECK-LABEL: loop:
+; CHECK: br i1 true, label %in.bounds.a, label %out.of.bounds
+
+; CHECK-LABEL: in.bounds.a:
+; CHECK: br i1 true, label %in.bounds.b, label %out.of.bounds
+
+; CHECK-LABEL: in.bounds.b:
+; CHECK: [[main_loop_cond:[^ ]+]] = icmp slt i32 %idx.next, [[upper_limit]]
+; CHECK: br i1 [[main_loop_cond]], label %loop, label %main.exit.selector
+
+; CHECK-LABEL: in.bounds.b.postloop:
+; CHECK: %next.postloop = icmp slt i32 %idx.next.postloop, %n
+; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 64, i32 4}
diff --git a/test/Transforms/IRCE/not-likely-taken.ll b/test/Transforms/IRCE/not-likely-taken.ll
new file mode 100644
index 0000000..c044530
--- /dev/null
+++ b/test/Transforms/IRCE/not-likely-taken.ll
@@ -0,0 +1,40 @@
+; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s
+
+; CHECK-NOT: constrained Loop
+
+define void @multiple_access_no_preloop(
+ i32* %arr_a, i32* %a_len_ptr, i32* %arr_b, i32* %b_len_ptr, i32 %n) {
+
+ entry:
+ %len.a = load i32* %a_len_ptr, !range !0
+ %len.b = load i32* %b_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds.b ]
+ %idx.next = add i32 %idx, 1
+ %abc.a = icmp slt i32 %idx, %len.a
+ br i1 %abc.a, label %in.bounds.a, label %out.of.bounds, !prof !1
+
+ in.bounds.a:
+ %addr.a = getelementptr i32* %arr_a, i32 %idx
+ store i32 0, i32* %addr.a
+ %abc.b = icmp slt i32 %idx, %len.b
+ br i1 %abc.b, label %in.bounds.b, label %out.of.bounds, !prof !1
+
+ in.bounds.b:
+ %addr.b = getelementptr i32* %arr_b, i32 %idx
+ store i32 -1, i32* %addr.b
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 1, i32 1} \ No newline at end of file
diff --git a/test/Transforms/IRCE/single-access-no-preloop.ll b/test/Transforms/IRCE/single-access-no-preloop.ll
new file mode 100644
index 0000000..4d47ba8
--- /dev/null
+++ b/test/Transforms/IRCE/single-access-no-preloop.ll
@@ -0,0 +1,116 @@
+; RUN: opt -irce -S < %s | FileCheck %s
+
+define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) {
+ entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %abc = icmp slt i32 %idx, %len
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+ in.bounds:
+ %addr = getelementptr i32* %arr, i32 %idx
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+; CHECK-LABEL: single_access_no_preloop
+
+; CHECK-LABEL: loop:
+; CHECK: br i1 true, label %in.bounds, label %out.of.bounds
+
+; CHECK-LABEL: main.exit.selector:
+; CHECK-NEXT: [[continue:%[^ ]+]] = icmp slt i32 %idx.next, %n
+; CHECK-NEXT: br i1 [[continue]], label %main.pseudo.exit, label %exit.loopexit
+
+; CHECK-LABEL: main.pseudo.exit:
+; CHECK-NEXT: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next, %main.exit.selector ]
+; CHECK-NEXT: %indvar.end = phi i32 [ 0, %loop.preheader ], [ %idx.next, %main.exit.selector ]
+; CHECK-NEXT: br label %postloop
+
+; CHECK-LABEL: postloop:
+; CHECK-NEXT: br label %loop.postloop
+
+; CHECK-LABEL: loop.postloop:
+; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.next.postloop, %in.bounds.postloop ], [ %idx.copy, %postloop ]
+; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 1
+; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %len
+; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds
+
+; CHECK-LABEL: in.bounds.postloop:
+; CHECK-NEXT: %addr.postloop = getelementptr i32* %arr, i32 %idx.postloop
+; CHECK-NEXT: store i32 0, i32* %addr.postloop
+; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, %n
+; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit
+
+
+define void @single_access_no_preloop_with_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) {
+ entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %idx.for.abc = add i32 %idx, 4
+ %abc = icmp slt i32 %idx.for.abc, %len
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+ in.bounds:
+ %addr = getelementptr i32* %arr, i32 %idx.for.abc
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+; CHECK-LABEL: single_access_no_preloop_with_offset
+
+; CHECK-LABEL: loop.preheader:
+; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n
+; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len
+; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_n]], [[not_safe_range_end]]
+; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_n]], i32 [[not_safe_range_end]]
+; CHECK: [[exit_main_loop_at_hiclamp:[^ ]+]] = sub i32 -1, [[not_exit_main_loop_at_hiclamp]]
+; CHECK: [[exit_main_loop_at_loclamp_cmp:[^ ]+]] = icmp sgt i32 [[exit_main_loop_at_hiclamp]], 0
+; CHECK: [[exit_main_loop_at_loclamp:[^ ]+]] = select i1 [[exit_main_loop_at_loclamp_cmp]], i32 [[exit_main_loop_at_hiclamp]], i32 0
+; CHECK: [[enter_main_loop:[^ ]+]] = icmp slt i32 0, [[exit_main_loop_at_loclamp]]
+; CHECK: br i1 [[enter_main_loop]], label %loop, label %main.pseudo.exit
+
+; CHECK-LABEL: loop:
+; CHECK: br i1 true, label %in.bounds, label %out.of.bounds
+
+; CHECK-LABEL: in.bounds:
+; CHECK: [[continue_main_loop:[^ ]+]] = icmp slt i32 %idx.next, [[exit_main_loop_at_loclamp]]
+; CHECK: br i1 [[continue_main_loop]], label %loop, label %main.exit.selector
+
+; CHECK-LABEL: main.pseudo.exit:
+; CHECK: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next, %main.exit.selector ]
+; CHECK: br label %postloop
+
+; CHECK-LABEL: loop.postloop:
+; CHECK: %idx.postloop = phi i32 [ %idx.next.postloop, %in.bounds.postloop ], [ %idx.copy, %postloop ]
+
+; CHECK-LABEL: in.bounds.postloop:
+; CHECK: %next.postloop = icmp slt i32 %idx.next.postloop, %n
+; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 64, i32 4}
diff --git a/test/Transforms/IRCE/single-access-with-preloop.ll b/test/Transforms/IRCE/single-access-with-preloop.ll
new file mode 100644
index 0000000..16426b8
--- /dev/null
+++ b/test/Transforms/IRCE/single-access-with-preloop.ll
@@ -0,0 +1,71 @@
+; RUN: opt -irce -S < %s | FileCheck %s
+
+define void @single_access_with_preloop(i32 *%arr, i32 *%a_len_ptr, i32 %n, i32 %offset) {
+ entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %array.idx = add i32 %idx, %offset
+ %abc.high = icmp slt i32 %array.idx, %len
+ %abc.low = icmp sge i32 %array.idx, 0
+ %abc = and i1 %abc.low, %abc.high
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+ in.bounds:
+ %addr = getelementptr i32* %arr, i32 %array.idx
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+; CHECK-LABEL: loop.preheader:
+; CHECK: [[not_safe_start:[^ ]+]] = add i32 %offset, -1
+; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n
+; CHECK: [[not_exit_preloop_at_cond_loclamp:[^ ]+]] = icmp sgt i32 [[not_safe_start]], [[not_n]]
+; CHECK: [[not_exit_preloop_at_loclamp:[^ ]+]] = select i1 [[not_exit_preloop_at_cond_loclamp]], i32 [[not_safe_start]], i32 [[not_n]]
+; CHECK: [[exit_preloop_at_loclamp:[^ ]+]] = sub i32 -1, [[not_exit_preloop_at_loclamp]]
+; CHECK: [[exit_preloop_at_cond:[^ ]+]] = icmp sgt i32 [[exit_preloop_at_loclamp]], 0
+; CHECK: [[exit_preloop_at:[^ ]+]] = select i1 [[exit_preloop_at_cond]], i32 [[exit_preloop_at_loclamp]], i32 0
+
+
+; CHECK: [[not_safe_start_2:[^ ]+]] = add i32 %offset, -1
+; CHECK: [[not_safe_end:[^ ]+]] = sub i32 [[not_safe_start_2]], %len
+; CHECK: [[not_exit_mainloop_at_cond_loclamp:[^ ]+]] = icmp sgt i32 [[not_safe_end]], [[not_n]]
+; CHECK: [[not_exit_mainloop_at_loclamp:[^ ]+]] = select i1 [[not_exit_mainloop_at_cond_loclamp]], i32 [[not_safe_end]], i32 [[not_n]]
+; CHECK: [[exit_mainloop_at_loclamp:[^ ]+]] = sub i32 -1, [[not_exit_mainloop_at_loclamp]]
+; CHECK: [[exit_mainloop_at_cmp:[^ ]+]] = icmp sgt i32 [[exit_mainloop_at_loclamp]], 0
+; CHECK: [[exit_mainloop_at:[^ ]+]] = select i1 [[exit_mainloop_at_cmp]], i32 [[exit_mainloop_at_loclamp]], i32 0
+
+
+; CHECK-LABEL: in.bounds:
+; CHECK: [[continue_mainloop_cond:[^ ]+]] = icmp slt i32 %idx.next, [[exit_mainloop_at]]
+; CHECK: br i1 [[continue_mainloop_cond]], label %loop, label %main.exit.selector
+
+; CHECK-LABEL: main.exit.selector:
+; CHECK: [[mainloop_its_left:[^ ]+]] = icmp slt i32 %idx.next, %n
+; CHECK: br i1 [[mainloop_its_left]], label %main.pseudo.exit, label %exit.loopexit
+
+; CHECK-LABEL: in.bounds.preloop:
+; CHECK: [[continue_preloop_cond:[^ ]+]] = icmp slt i32 %idx.next.preloop, [[exit_preloop_at]]
+; CHECK: br i1 [[continue_preloop_cond]], label %loop.preloop, label %preloop.exit.selector
+
+; CHECK-LABEL: preloop.exit.selector:
+; CHECK: [[preloop_its_left:[^ ]+]] = icmp slt i32 %idx.next.preloop, %n
+; CHECK: br i1 [[preloop_its_left]], label %preloop.pseudo.exit, label %exit.loopexit
+
+; CHECK-LABEL: in.bounds.postloop:
+; CHECK: %next.postloop = icmp slt i32 %idx.next.postloop, %n
+; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 64, i32 4}
diff --git a/test/Transforms/IRCE/unhandled.ll b/test/Transforms/IRCE/unhandled.ll
new file mode 100644
index 0000000..3531c48
--- /dev/null
+++ b/test/Transforms/IRCE/unhandled.ll
@@ -0,0 +1,37 @@
+; RUN: opt -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
+
+; Demonstrates that we don't currently handle the general expression
+; `A * I + B'.
+
+define void @general_affine_expressions(i32 *%arr, i32 *%a_len_ptr, i32 %n,
+ i32 %scale, i32 %offset) {
+; CHECK-NOT: constrained Loop at depth
+ entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %idx.mul = mul i32 %idx, %scale
+ %array.idx = add i32 %idx.mul, %offset
+ %abc.high = icmp slt i32 %array.idx, %len
+ %abc.low = icmp sge i32 %array.idx, 0
+ %abc = and i1 %abc.low, %abc.high
+ br i1 %abc, label %in.bounds, label %out.of.bounds
+
+ in.bounds:
+ %addr = getelementptr i32* %arr, i32 %array.idx
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+ out.of.bounds:
+ ret void
+
+ exit:
+ ret void
+}
+
+!0 = !{i32 0, i32 2147483647}
diff --git a/test/Transforms/IRCE/with-parent-loops.ll b/test/Transforms/IRCE/with-parent-loops.ll
new file mode 100644
index 0000000..f8d6c83
--- /dev/null
+++ b/test/Transforms/IRCE/with-parent-loops.ll
@@ -0,0 +1,345 @@
+; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s
+
+; This test checks if we update the LoopInfo correctly in the presence
+; of parents, uncles and cousins.
+
+; Function Attrs: alwaysinline
+define void @inner_loop(i32* %arr, i32* %a_len_ptr, i32 %n) #0 {
+; CHECK: irce: in function inner_loop: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
+
+entry:
+ %len = load i32* %a_len_ptr, !range !0
+ %first.itr.check = icmp sgt i32 %n, 0
+ br i1 %first.itr.check, label %loop, label %exit
+
+loop: ; preds = %in.bounds, %entry
+ %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
+ %idx.next = add i32 %idx, 1
+ %abc = icmp slt i32 %idx, %len
+ br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
+
+in.bounds: ; preds = %loop
+ %addr = getelementptr i32* %arr, i32 %idx
+ store i32 0, i32* %addr
+ %next = icmp slt i32 %idx.next, %n
+ br i1 %next, label %loop, label %exit
+
+out.of.bounds: ; preds = %loop
+ ret void
+
+exit: ; preds = %in.bounds, %entry
+ ret void
+}
+
+; Function Attrs: alwaysinline
+define void @with_parent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
+; CHECK: irce: in function with_parent: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
+
+entry:
+ br label %loop
+
+loop: ; preds = %inner_loop.exit, %entry
+ %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit ]
+ %idx.next = add i32 %idx, 1
+ %next = icmp ult i32 %idx.next, %parent.count
+ %len.i = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i, label %loop.i, label %exit.i
+
+loop.i: ; preds = %in.bounds.i, %loop
+ %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
+ %idx.next.i = add i32 %idx.i, 1
+ %abc.i = icmp slt i32 %idx.i, %len.i
+ br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
+
+in.bounds.i: ; preds = %loop.i
+ %addr.i = getelementptr i32* %arr, i32 %idx.i
+ store i32 0, i32* %addr.i
+ %next.i = icmp slt i32 %idx.next.i, %n
+ br i1 %next.i, label %loop.i, label %exit.i
+
+out.of.bounds.i: ; preds = %loop.i
+ br label %inner_loop.exit
+
+exit.i: ; preds = %in.bounds.i, %loop
+ br label %inner_loop.exit
+
+inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i
+ br i1 %next, label %loop, label %exit
+
+exit: ; preds = %inner_loop.exit
+ ret void
+}
+
+; Function Attrs: alwaysinline
+define void @with_grandparent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
+; CHECK: irce: in function with_grandparent: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
+
+entry:
+ br label %loop
+
+loop: ; preds = %with_parent.exit, %entry
+ %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
+ %idx.next = add i32 %idx, 1
+ %next = icmp ult i32 %idx.next, %grandparent.count
+ br label %loop.i
+
+loop.i: ; preds = %inner_loop.exit.i, %loop
+ %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
+ %idx.next.i = add i32 %idx.i, 1
+ %next.i = icmp ult i32 %idx.next.i, %parent.count
+ %len.i.i = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i.i = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
+
+loop.i.i: ; preds = %in.bounds.i.i, %loop.i
+ %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
+ %idx.next.i.i = add i32 %idx.i.i, 1
+ %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
+ br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
+
+in.bounds.i.i: ; preds = %loop.i.i
+ %addr.i.i = getelementptr i32* %arr, i32 %idx.i.i
+ store i32 0, i32* %addr.i.i
+ %next.i.i = icmp slt i32 %idx.next.i.i, %n
+ br i1 %next.i.i, label %loop.i.i, label %exit.i.i
+
+out.of.bounds.i.i: ; preds = %loop.i.i
+ br label %inner_loop.exit.i
+
+exit.i.i: ; preds = %in.bounds.i.i, %loop.i
+ br label %inner_loop.exit.i
+
+inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i
+ br i1 %next.i, label %loop.i, label %with_parent.exit
+
+with_parent.exit: ; preds = %inner_loop.exit.i
+ br i1 %next, label %loop, label %exit
+
+exit: ; preds = %with_parent.exit
+ ret void
+}
+
+; Function Attrs: alwaysinline
+define void @with_sibling(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
+; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
+; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i6<header><exiting>,%in.bounds.i9<latch><exiting>
+
+entry:
+ br label %loop
+
+loop: ; preds = %inner_loop.exit12, %entry
+ %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit12 ]
+ %idx.next = add i32 %idx, 1
+ %next = icmp ult i32 %idx.next, %parent.count
+ %len.i = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i, label %loop.i, label %exit.i
+
+loop.i: ; preds = %in.bounds.i, %loop
+ %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
+ %idx.next.i = add i32 %idx.i, 1
+ %abc.i = icmp slt i32 %idx.i, %len.i
+ br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
+
+in.bounds.i: ; preds = %loop.i
+ %addr.i = getelementptr i32* %arr, i32 %idx.i
+ store i32 0, i32* %addr.i
+ %next.i = icmp slt i32 %idx.next.i, %n
+ br i1 %next.i, label %loop.i, label %exit.i
+
+out.of.bounds.i: ; preds = %loop.i
+ br label %inner_loop.exit
+
+exit.i: ; preds = %in.bounds.i, %loop
+ br label %inner_loop.exit
+
+inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i
+ %len.i1 = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i2 = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i2, label %loop.i6, label %exit.i11
+
+loop.i6: ; preds = %in.bounds.i9, %inner_loop.exit
+ %idx.i3 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i4, %in.bounds.i9 ]
+ %idx.next.i4 = add i32 %idx.i3, 1
+ %abc.i5 = icmp slt i32 %idx.i3, %len.i1
+ br i1 %abc.i5, label %in.bounds.i9, label %out.of.bounds.i10, !prof !1
+
+in.bounds.i9: ; preds = %loop.i6
+ %addr.i7 = getelementptr i32* %arr, i32 %idx.i3
+ store i32 0, i32* %addr.i7
+ %next.i8 = icmp slt i32 %idx.next.i4, %n
+ br i1 %next.i8, label %loop.i6, label %exit.i11
+
+out.of.bounds.i10: ; preds = %loop.i6
+ br label %inner_loop.exit12
+
+exit.i11: ; preds = %in.bounds.i9, %inner_loop.exit
+ br label %inner_loop.exit12
+
+inner_loop.exit12: ; preds = %exit.i11, %out.of.bounds.i10
+ br i1 %next, label %loop, label %exit
+
+exit: ; preds = %inner_loop.exit12
+ ret void
+}
+
+; Function Attrs: alwaysinline
+define void @with_cousin(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
+; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
+; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i10<header><exiting>,%in.bounds.i.i13<latch><exiting>
+
+entry:
+ br label %loop
+
+loop: ; preds = %with_parent.exit17, %entry
+ %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit17 ]
+ %idx.next = add i32 %idx, 1
+ %next = icmp ult i32 %idx.next, %grandparent.count
+ br label %loop.i
+
+loop.i: ; preds = %inner_loop.exit.i, %loop
+ %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
+ %idx.next.i = add i32 %idx.i, 1
+ %next.i = icmp ult i32 %idx.next.i, %parent.count
+ %len.i.i = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i.i = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
+
+loop.i.i: ; preds = %in.bounds.i.i, %loop.i
+ %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
+ %idx.next.i.i = add i32 %idx.i.i, 1
+ %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
+ br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
+
+in.bounds.i.i: ; preds = %loop.i.i
+ %addr.i.i = getelementptr i32* %arr, i32 %idx.i.i
+ store i32 0, i32* %addr.i.i
+ %next.i.i = icmp slt i32 %idx.next.i.i, %n
+ br i1 %next.i.i, label %loop.i.i, label %exit.i.i
+
+out.of.bounds.i.i: ; preds = %loop.i.i
+ br label %inner_loop.exit.i
+
+exit.i.i: ; preds = %in.bounds.i.i, %loop.i
+ br label %inner_loop.exit.i
+
+inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i
+ br i1 %next.i, label %loop.i, label %with_parent.exit
+
+with_parent.exit: ; preds = %inner_loop.exit.i
+ br label %loop.i6
+
+loop.i6: ; preds = %inner_loop.exit.i16, %with_parent.exit
+ %idx.i1 = phi i32 [ 0, %with_parent.exit ], [ %idx.next.i2, %inner_loop.exit.i16 ]
+ %idx.next.i2 = add i32 %idx.i1, 1
+ %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
+ %len.i.i4 = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i.i5 = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i.i5, label %loop.i.i10, label %exit.i.i15
+
+loop.i.i10: ; preds = %in.bounds.i.i13, %loop.i6
+ %idx.i.i7 = phi i32 [ 0, %loop.i6 ], [ %idx.next.i.i8, %in.bounds.i.i13 ]
+ %idx.next.i.i8 = add i32 %idx.i.i7, 1
+ %abc.i.i9 = icmp slt i32 %idx.i.i7, %len.i.i4
+ br i1 %abc.i.i9, label %in.bounds.i.i13, label %out.of.bounds.i.i14, !prof !1
+
+in.bounds.i.i13: ; preds = %loop.i.i10
+ %addr.i.i11 = getelementptr i32* %arr, i32 %idx.i.i7
+ store i32 0, i32* %addr.i.i11
+ %next.i.i12 = icmp slt i32 %idx.next.i.i8, %n
+ br i1 %next.i.i12, label %loop.i.i10, label %exit.i.i15
+
+out.of.bounds.i.i14: ; preds = %loop.i.i10
+ br label %inner_loop.exit.i16
+
+exit.i.i15: ; preds = %in.bounds.i.i13, %loop.i6
+ br label %inner_loop.exit.i16
+
+inner_loop.exit.i16: ; preds = %exit.i.i15, %out.of.bounds.i.i14
+ br i1 %next.i3, label %loop.i6, label %with_parent.exit17
+
+with_parent.exit17: ; preds = %inner_loop.exit.i16
+ br i1 %next, label %loop, label %exit
+
+exit: ; preds = %with_parent.exit17
+ ret void
+}
+
+; Function Attrs: alwaysinline
+define void @with_uncle(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
+; CHECK: irce: in function with_uncle: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
+; CHECK: irce: in function with_uncle: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
+
+entry:
+ br label %loop
+
+loop: ; preds = %with_parent.exit, %entry
+ %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
+ %idx.next = add i32 %idx, 1
+ %next = icmp ult i32 %idx.next, %grandparent.count
+ %len.i = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i, label %loop.i, label %exit.i
+
+loop.i: ; preds = %in.bounds.i, %loop
+ %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
+ %idx.next.i = add i32 %idx.i, 1
+ %abc.i = icmp slt i32 %idx.i, %len.i
+ br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
+
+in.bounds.i: ; preds = %loop.i
+ %addr.i = getelementptr i32* %arr, i32 %idx.i
+ store i32 0, i32* %addr.i
+ %next.i = icmp slt i32 %idx.next.i, %n
+ br i1 %next.i, label %loop.i, label %exit.i
+
+out.of.bounds.i: ; preds = %loop.i
+ br label %inner_loop.exit
+
+exit.i: ; preds = %in.bounds.i, %loop
+ br label %inner_loop.exit
+
+inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i
+ br label %loop.i4
+
+loop.i4: ; preds = %inner_loop.exit.i, %inner_loop.exit
+ %idx.i1 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i2, %inner_loop.exit.i ]
+ %idx.next.i2 = add i32 %idx.i1, 1
+ %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
+ %len.i.i = load i32* %a_len_ptr, !range !0
+ %first.itr.check.i.i = icmp sgt i32 %n, 0
+ br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
+
+loop.i.i: ; preds = %in.bounds.i.i, %loop.i4
+ %idx.i.i = phi i32 [ 0, %loop.i4 ], [ %idx.next.i.i, %in.bounds.i.i ]
+ %idx.next.i.i = add i32 %idx.i.i, 1
+ %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
+ br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
+
+in.bounds.i.i: ; preds = %loop.i.i
+ %addr.i.i = getelementptr i32* %arr, i32 %idx.i.i
+ store i32 0, i32* %addr.i.i
+ %next.i.i = icmp slt i32 %idx.next.i.i, %n
+ br i1 %next.i.i, label %loop.i.i, label %exit.i.i
+
+out.of.bounds.i.i: ; preds = %loop.i.i
+ br label %inner_loop.exit.i
+
+exit.i.i: ; preds = %in.bounds.i.i, %loop.i4
+ br label %inner_loop.exit.i
+
+inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i
+ br i1 %next.i3, label %loop.i4, label %with_parent.exit
+
+with_parent.exit: ; preds = %inner_loop.exit.i
+ br i1 %next, label %loop, label %exit
+
+exit: ; preds = %with_parent.exit
+ ret void
+}
+
+attributes #0 = { alwaysinline }
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{!"branch_weights", i32 64, i32 4}
diff --git a/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll b/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
index 64fef10..82b2120 100644
--- a/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
+++ b/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
@@ -17,7 +17,7 @@ for.body11: ; preds = %entry
for.body153: ; preds = %for.body153, %for.body11
br i1 undef, label %for.body170, label %for.body153
-; CHECK: add nsw i64 %indvars.iv, 1
+; CHECK: add nuw nsw i64 %indvars.iv, 1
; CHECK: sub nsw i64 %indvars.iv, 2
; CHECK: sub nsw i64 4, %indvars.iv
; CHECK: mul nsw i64 %indvars.iv, 8
diff --git a/test/Transforms/IndVarSimplify/backedge-on-min-max.ll b/test/Transforms/IndVarSimplify/backedge-on-min-max.ll
new file mode 100644
index 0000000..250ff9a
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/backedge-on-min-max.ll
@@ -0,0 +1,453 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+
+;; --- signed ---
+
+define void @min.signed.1(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @min.signed.1
+ entry:
+ %smin.cmp = icmp slt i32 %a_len, %n
+ %smin = select i1 %smin.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp slt i32 0, %smin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp slt i32 %idx, %a_len
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp slt i32 %idx.inc, %smin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @min.signed.2(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @min.signed.2
+ entry:
+ %smin.cmp = icmp slt i32 %a_len, %n
+ %smin = select i1 %smin.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp slt i32 0, %smin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp sgt i32 %a_len, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp slt i32 %idx.inc, %smin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @min.signed.3(i32* %a, i32 %n) {
+; CHECK-LABEL: @min.signed.3
+ entry:
+ %smin.cmp = icmp slt i32 42, %n
+ %smin = select i1 %smin.cmp, i32 42, i32 %n
+ %entry.cond = icmp slt i32 0, %smin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp slt i32 %idx, 42
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp slt i32 %idx.inc, %smin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @min.signed.4(i32* %a, i32 %n) {
+; CHECK-LABEL: @min.signed.4
+ entry:
+ %smin.cmp = icmp slt i32 42, %n
+ %smin = select i1 %smin.cmp, i32 42, i32 %n
+ %entry.cond = icmp slt i32 0, %smin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp sgt i32 42, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp slt i32 %idx.inc, %smin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.signed.1(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @max.signed.1
+ entry:
+ %smax.cmp = icmp sgt i32 %a_len, %n
+ %smax = select i1 %smax.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp sgt i32 0, %smax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp sgt i32 %idx, %a_len
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp sgt i32 %idx.inc, %smax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.signed.2(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @max.signed.2
+ entry:
+ %smax.cmp = icmp sgt i32 %a_len, %n
+ %smax = select i1 %smax.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp sgt i32 0, %smax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp slt i32 %a_len, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp sgt i32 %idx.inc, %smax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.signed.3(i32* %a, i32 %n, i32 %init) {
+; CHECK-LABEL: @max.signed.3
+ entry:
+ %smax.cmp = icmp sgt i32 42, %n
+ %smax = select i1 %smax.cmp, i32 42, i32 %n
+ %entry.cond = icmp sgt i32 %init, %smax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp sgt i32 %idx, 42
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp sgt i32 %idx.inc, %smax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.signed.4(i32* %a, i32 %n, i32 %init) {
+; CHECK-LABEL: @max.signed.4
+ entry:
+ %smax.cmp = icmp sgt i32 42, %n
+ %smax = select i1 %smax.cmp, i32 42, i32 %n
+ %entry.cond = icmp sgt i32 %init, %smax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp slt i32 42, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp sgt i32 %idx.inc, %smax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+;; --- unsigned ---
+
+define void @min.unsigned.1(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @min.unsigned.1
+ entry:
+ %umin.cmp = icmp ult i32 %a_len, %n
+ %umin = select i1 %umin.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp ult i32 5, %umin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ult i32 %idx, %a_len
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ult i32 %idx.inc, %umin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @min.unsigned.2(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @min.unsigned.2
+ entry:
+ %umin.cmp = icmp ult i32 %a_len, %n
+ %umin = select i1 %umin.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp ult i32 5, %umin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ugt i32 %a_len, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ult i32 %idx.inc, %umin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @min.unsigned.3(i32* %a, i32 %n) {
+; CHECK-LABEL: @min.unsigned.3
+ entry:
+ %umin.cmp = icmp ult i32 42, %n
+ %umin = select i1 %umin.cmp, i32 42, i32 %n
+ %entry.cond = icmp ult i32 5, %umin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ult i32 %idx, 42
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ult i32 %idx.inc, %umin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @min.unsigned.4(i32* %a, i32 %n) {
+; CHECK-LABEL: @min.unsigned.4
+ entry:
+ %umin.cmp = icmp ult i32 42, %n
+ %umin = select i1 %umin.cmp, i32 42, i32 %n
+ %entry.cond = icmp ult i32 5, %umin
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ugt i32 42, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ult i32 %idx.inc, %umin
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.unsigned.1(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @max.unsigned.1
+ entry:
+ %umax.cmp = icmp ugt i32 %a_len, %n
+ %umax = select i1 %umax.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp ugt i32 5, %umax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ugt i32 %idx, %a_len
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ugt i32 %idx.inc, %umax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.unsigned.2(i32* %a, i32 %a_len, i32 %n) {
+; CHECK-LABEL: @max.unsigned.2
+ entry:
+ %umax.cmp = icmp ugt i32 %a_len, %n
+ %umax = select i1 %umax.cmp, i32 %a_len, i32 %n
+ %entry.cond = icmp ugt i32 5, %umax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ult i32 %a_len, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ugt i32 %idx.inc, %umax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.unsigned.3(i32* %a, i32 %n, i32 %init) {
+; CHECK-LABEL: @max.unsigned.3
+ entry:
+ %umax.cmp = icmp ugt i32 42, %n
+ %umax = select i1 %umax.cmp, i32 42, i32 %n
+ %entry.cond = icmp ugt i32 %init, %umax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ugt i32 %idx, 42
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ugt i32 %idx.inc, %umax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
+
+define void @max.unsigned.4(i32* %a, i32 %n, i32 %init) {
+; CHECK-LABEL: @max.unsigned.4
+ entry:
+ %umax.cmp = icmp ugt i32 42, %n
+ %umax = select i1 %umax.cmp, i32 42, i32 %n
+ %entry.cond = icmp ugt i32 %init, %umax
+ br i1 %entry.cond, label %loop, label %exit
+
+ loop:
+ %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
+ %idx.inc = add i32 %idx, 1
+ %in.bounds = icmp ult i32 42, %idx
+ br i1 %in.bounds, label %ok, label %latch
+; CHECK: br i1 true, label %ok, label %latch
+
+ ok:
+ %addr = getelementptr i32* %a, i32 %idx
+ store i32 %idx, i32* %addr
+ br label %latch
+
+ latch:
+ %be.cond = icmp ugt i32 %idx.inc, %umax
+ br i1 %be.cond, label %loop, label %exit
+
+ exit:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/overflowcheck.ll b/test/Transforms/IndVarSimplify/overflowcheck.ll
index 2603f36..3864c6c 100644
--- a/test/Transforms/IndVarSimplify/overflowcheck.ll
+++ b/test/Transforms/IndVarSimplify/overflowcheck.ll
@@ -9,7 +9,7 @@ target triple = "x86_64-apple-macosx"
; CHECK: @llvm.sadd.with.overflow
; CHECK-LABEL: loop2:
; CHECK-NOT: extractvalue
-; CHECK: add nuw nsw
+; CHECK: add nuw
; CHECK: @llvm.sadd.with.overflow
; CHECK-LABEL: loop3:
; CHECK-NOT: extractvalue
diff --git a/test/Transforms/IndVarSimplify/pr20680.ll b/test/Transforms/IndVarSimplify/pr20680.ll
index 88a7fd7..716e013 100644
--- a/test/Transforms/IndVarSimplify/pr20680.ll
+++ b/test/Transforms/IndVarSimplify/pr20680.ll
@@ -204,8 +204,8 @@ for.cond2.for.inc13_crit_edge: ; preds = %for.cond2.for.inc13
br label %for.inc13
; CHECK: [[for_inc13]]:
-; CHECK-NEXT: %[[indvars_iv_next]] = add nuw nsw i32 %[[indvars_iv]], 1
-; CHECK-NEXT: %[[exitcond4:.*]] = icmp ne i32 %[[indvars_iv]], -1
+; CHECK-NEXT: %[[indvars_iv_next]] = add nsw i32 %[[indvars_iv]], 1
+; CHECK-NEXT: %[[exitcond4:.*]] = icmp ne i32 %[[indvars_iv_next]], 0
; CHECK-NEXT: br i1 %[[exitcond4]], label %[[for_cond2_preheader]], label %[[for_end15:.*]]
for.inc13: ; preds = %for.cond2.for.inc13_crit_edge, %for.cond2.preheader
%inc14 = add i8 %storemerge15, 1
diff --git a/test/Transforms/IndVarSimplify/pr22222.ll b/test/Transforms/IndVarSimplify/pr22222.ll
new file mode 100644
index 0000000..ccdfe53
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr22222.ll
@@ -0,0 +1,46 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+@b = common global i32 0, align 4
+@c = common global i32 0, align 4
+@a = common global i32 0, align 4
+
+declare void @abort() #1
+
+; Function Attrs: nounwind ssp uwtable
+define i32 @main() {
+entry:
+ %a.promoted13 = load i32* @a, align 4
+ br label %for.cond1.preheader
+
+for.cond1.preheader: ; preds = %entry, %for.end
+ %or.lcssa14 = phi i32 [ %a.promoted13, %entry ], [ %or.lcssa, %for.end ]
+ %d.010 = phi i32 [ 1, %entry ], [ 0, %for.end ]
+ br label %for.body3
+
+for.body3: ; preds = %for.cond1.preheader, %for.body3
+ %inc12 = phi i32 [ 0, %for.cond1.preheader ], [ %inc, %for.body3 ]
+ %or11 = phi i32 [ %or.lcssa14, %for.cond1.preheader ], [ %or, %for.body3 ]
+; CHECK-NOT: sub nuw i32 %inc12, %d.010
+; CHECK: sub i32 %inc12, %d.010
+ %add = sub i32 %inc12, %d.010
+ %or = or i32 %or11, %add
+ %inc = add i32 %inc12, 1
+ br i1 false, label %for.body3, label %for.end
+
+for.end: ; preds = %for.body3
+ %or.lcssa = phi i32 [ %or, %for.body3 ]
+ br i1 false, label %for.cond1.preheader, label %for.end6
+
+for.end6: ; preds = %for.end
+ %or.lcssa.lcssa = phi i32 [ %or.lcssa, %for.end ]
+ store i32 %or.lcssa.lcssa, i32* @a, align 4
+ %cmp7 = icmp eq i32 %or.lcssa.lcssa, -1
+ br i1 %cmp7, label %if.end, label %if.then
+
+if.then: ; preds = %for.end6
+ tail call void @abort() #2
+ unreachable
+
+if.end: ; preds = %for.end6
+ ret i32 0
+}
diff --git a/test/Transforms/IndVarSimplify/sharpen-range.ll b/test/Transforms/IndVarSimplify/sharpen-range.ll
index 6a9d352..5392dbc 100644
--- a/test/Transforms/IndVarSimplify/sharpen-range.ll
+++ b/test/Transforms/IndVarSimplify/sharpen-range.ll
@@ -110,4 +110,4 @@ exit:
ret void
}
-!0 = metadata !{i32 0, i32 100}
+!0 = !{i32 0, i32 100}
diff --git a/test/Transforms/IndVarSimplify/strengthen-overflow.ll b/test/Transforms/IndVarSimplify/strengthen-overflow.ll
new file mode 100644
index 0000000..2bafe96
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/strengthen-overflow.ll
@@ -0,0 +1,108 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+
+define i32 @test.signed.add.0(i32* %array, i32 %length, i32 %init) {
+; CHECK-LABEL: @test.signed.add.0
+ entry:
+ %upper = icmp slt i32 %init, %length
+ br i1 %upper, label %loop, label %exit
+
+ loop:
+; CHECK-LABEL: loop
+ %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
+ %civ.inc = add i32 %civ, 1
+; CHECK: %civ.inc = add nsw i32 %civ, 1
+ %cmp = icmp slt i32 %civ.inc, %length
+ br i1 %cmp, label %latch, label %break
+
+ latch:
+ store i32 0, i32* %array
+ %check = icmp slt i32 %civ.inc, %length
+ br i1 %check, label %loop, label %break
+
+ break:
+ ret i32 %civ.inc
+
+ exit:
+ ret i32 42
+}
+
+define i32 @test.signed.add.1(i32* %array, i32 %length, i32 %init) {
+; CHECK-LABEL: @test.signed.add.1
+ entry:
+ %upper = icmp sle i32 %init, %length
+ br i1 %upper, label %loop, label %exit
+
+ loop:
+; CHECK-LABEL: loop
+ %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
+ %civ.inc = add i32 %civ, 1
+; CHECK: %civ.inc = add i32 %civ, 1
+ %cmp = icmp slt i32 %civ.inc, %length
+ br i1 %cmp, label %latch, label %break
+
+ latch:
+ store i32 0, i32* %array
+ %check = icmp slt i32 %civ.inc, %length
+ br i1 %check, label %loop, label %break
+
+ break:
+ ret i32 %civ.inc
+
+ exit:
+ ret i32 42
+}
+
+define i32 @test.unsigned.add.0(i32* %array, i32 %length, i32 %init) {
+; CHECK-LABEL: @test.unsigned.add.0
+ entry:
+ %upper = icmp ult i32 %init, %length
+ br i1 %upper, label %loop, label %exit
+
+ loop:
+; CHECK-LABEL: loop
+ %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
+ %civ.inc = add i32 %civ, 1
+; CHECK: %civ.inc = add nuw i32 %civ, 1
+ %cmp = icmp slt i32 %civ.inc, %length
+ br i1 %cmp, label %latch, label %break
+
+ latch:
+ store i32 0, i32* %array
+ %check = icmp ult i32 %civ.inc, %length
+ br i1 %check, label %loop, label %break
+
+ break:
+ ret i32 %civ.inc
+
+ exit:
+ ret i32 42
+}
+
+define i32 @test.unsigned.add.1(i32* %array, i32 %length, i32 %init) {
+; CHECK-LABEL: @test.unsigned.add.1
+ entry:
+ %upper = icmp ule i32 %init, %length
+ br i1 %upper, label %loop, label %exit
+
+ loop:
+; CHECK-LABEL: loop
+ %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
+ %civ.inc = add i32 %civ, 1
+; CHECK: %civ.inc = add i32 %civ, 1
+ %cmp = icmp slt i32 %civ.inc, %length
+ br i1 %cmp, label %latch, label %break
+
+ latch:
+ store i32 0, i32* %array
+ %check = icmp ult i32 %civ.inc, %length
+ br i1 %check, label %loop, label %break
+
+ break:
+ ret i32 %civ.inc
+
+ exit:
+ ret i32 42
+}
+
+!0 = !{i32 0, i32 2}
+!1 = !{i32 0, i32 42}
diff --git a/test/Transforms/IndVarSimplify/use-range-metadata.ll b/test/Transforms/IndVarSimplify/use-range-metadata.ll
index 7ac4f11..ea3b12d 100644
--- a/test/Transforms/IndVarSimplify/use-range-metadata.ll
+++ b/test/Transforms/IndVarSimplify/use-range-metadata.ll
@@ -34,4 +34,4 @@ oob:
ret i1 false
}
-!0 = metadata !{i32 1, i32 100}
+!0 = !{i32 1, i32 100}
diff --git a/test/Transforms/Inline/alloca-dbgdeclare.ll b/test/Transforms/Inline/alloca-dbgdeclare.ll
new file mode 100644
index 0000000..6809e41
--- /dev/null
+++ b/test/Transforms/Inline/alloca-dbgdeclare.ll
@@ -0,0 +1,141 @@
+; RUN: opt -inline -S < %s | FileCheck %s
+; struct A {
+; int arg0;
+; double arg1[2];
+; } a, b;
+;
+; void fn3(A p1) {
+; if (p1.arg0)
+; a = p1;
+; }
+;
+; void fn4() { fn3(b); }
+;
+; void fn5() {
+; while (1)
+; fn4();
+; }
+; ModuleID = 'test.cpp'
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-apple-darwin"
+
+%struct.A = type { i32, [2 x double] }
+
+@a = global %struct.A zeroinitializer, align 8
+@b = global %struct.A zeroinitializer, align 8
+
+; Function Attrs: nounwind
+declare void @_Z3fn31A(%struct.A* nocapture readonly %p1) #0
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+; Function Attrs: nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #2
+
+; Function Attrs: nounwind
+define void @_Z3fn4v() #0 {
+entry:
+; Test that the dbg.declare is moved together with the alloca.
+; CHECK: define void @_Z3fn5v()
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %agg.tmp.sroa.3.i = alloca [20 x i8], align 4
+; CHECK-NEXT: call void @llvm.dbg.declare(metadata [20 x i8]* %agg.tmp.sroa.3.i,
+ %agg.tmp.sroa.3 = alloca [20 x i8], align 4
+ tail call void @llvm.dbg.declare(metadata [20 x i8]* %agg.tmp.sroa.3, metadata !46, metadata !48), !dbg !49
+ %agg.tmp.sroa.0.0.copyload = load i32* getelementptr inbounds (%struct.A* @b, i64 0, i32 0), align 8, !dbg !50
+ tail call void @llvm.dbg.value(metadata i32 %agg.tmp.sroa.0.0.copyload, i64 0, metadata !46, metadata !51), !dbg !49
+ %agg.tmp.sroa.3.0..sroa_idx = getelementptr inbounds [20 x i8]* %agg.tmp.sroa.3, i64 0, i64 0, !dbg !50
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %agg.tmp.sroa.3.0..sroa_idx, i8* getelementptr (i8* bitcast (%struct.A* @b to i8*), i64 4), i64 20, i32 4, i1 false), !dbg !50
+ tail call void @llvm.dbg.declare(metadata %struct.A* undef, metadata !46, metadata !31) #2, !dbg !49
+ %tobool.i = icmp eq i32 %agg.tmp.sroa.0.0.copyload, 0, !dbg !52
+ br i1 %tobool.i, label %_Z3fn31A.exit, label %if.then.i, !dbg !53
+
+if.then.i: ; preds = %entry
+ store i32 %agg.tmp.sroa.0.0.copyload, i32* getelementptr inbounds (%struct.A* @a, i64 0, i32 0), align 8, !dbg !54
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr (i8* bitcast (%struct.A* @a to i8*), i64 4), i8* %agg.tmp.sroa.3.0..sroa_idx, i64 20, i32 4, i1 false), !dbg !54
+ br label %_Z3fn31A.exit, !dbg !54
+
+_Z3fn31A.exit: ; preds = %entry, %if.then.i
+ ret void, !dbg !50
+}
+
+; Function Attrs: noreturn nounwind
+define void @_Z3fn5v() #3 {
+entry:
+ br label %while.body, !dbg !55
+
+while.body: ; preds = %entry, %while.body
+ call void @_Z3fn4v(), !dbg !56
+ br label %while.body, !dbg !55
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+attributes #2 = { nounwind }
+attributes #3 = { noreturn nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!28, !29}
+!llvm.ident = !{!30}
+
+!0 = !{!"0x11\004\00clang version 3.7.0 (trunk 227480) (llvm/trunk 227517)\001\00\000\00\001", !1, !2, !3, !14, !25, !2} ; [ DW_TAG_compile_unit ] [/<stdin>] [DW_LANG_C_plus_plus]
+!1 = !{!"<stdin>", !""}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x13\00A\001\00192\0064\000\000\000", !5, null, null, !6, null, null, !"_ZTS1A"} ; [ DW_TAG_structure_type ] [A] [line 1, size 192, align 64, offset 0] [def] [from ]
+!5 = !{!"test.cpp", !""}
+!6 = !{!7, !9}
+!7 = !{!"0xd\00arg0\002\0032\0032\000\000", !5, !"_ZTS1A", !8} ; [ DW_TAG_member ] [arg0] [line 2, size 32, align 32, offset 0] [from int]
+!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!9 = !{!"0xd\00arg1\003\00128\0064\0064\000", !5, !"_ZTS1A", !10} ; [ DW_TAG_member ] [arg1] [line 3, size 128, align 64, offset 64] [from ]
+!10 = !{!"0x1\00\000\00128\0064\000\000\000", null, null, !11, !12, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 128, align 64, offset 0] [from double]
+!11 = !{!"0x24\00double\000\0064\0064\000\000\004", null, null} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
+!12 = !{!13}
+!13 = !{!"0x21\000\002"} ; [ DW_TAG_subrange_type ] [0, 1]
+!14 = !{!15, !21, !24}
+!15 = !{!"0x2e\00fn3\00fn3\00_Z3fn31A\006\000\001\000\000\00256\001\006", !5, !16, !17, null, void (%struct.A*)* @_Z3fn31A, null, null, !19} ; [ DW_TAG_subprogram ] [line 6] [def] [fn3]
+!16 = !{!"0x29", !5} ; [ DW_TAG_file_type ] [/test.cpp]
+!17 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !18, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!18 = !{null, !"_ZTS1A"}
+!19 = !{!20}
+!20 = !{!"0x101\00p1\0016777222\000", !15, !16, !"_ZTS1A"} ; [ DW_TAG_arg_variable ] [p1] [line 6]
+!21 = !{!"0x2e\00fn4\00fn4\00_Z3fn4v\0011\000\001\000\000\00256\001\0011", !5, !16, !22, null, void ()* @_Z3fn4v, null, null, !2} ; [ DW_TAG_subprogram ] [line 11] [def] [fn4]
+!22 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !23, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!23 = !{null}
+!24 = !{!"0x2e\00fn5\00fn5\00_Z3fn5v\0013\000\001\000\000\00256\001\0013", !5, !16, !22, null, void ()* @_Z3fn5v, null, null, !2} ; [ DW_TAG_subprogram ] [line 13] [def] [fn5]
+!25 = !{!26, !27}
+!26 = !{!"0x34\00a\00a\00\004\000\001", null, !16, !"_ZTS1A", %struct.A* @a, null} ; [ DW_TAG_variable ] [a] [line 4] [def]
+!27 = !{!"0x34\00b\00b\00\004\000\001", null, !16, !"_ZTS1A", %struct.A* @b, null} ; [ DW_TAG_variable ] [b] [line 4] [def]
+!28 = !{i32 2, !"Dwarf Version", i32 4}
+!29 = !{i32 2, !"Debug Info Version", i32 2}
+!30 = !{!"clang version 3.7.0 (trunk 227480) (llvm/trunk 227517)"}
+!31 = !{!"0x102\006"} ; [ DW_TAG_expression ] [DW_OP_deref]
+!32 = !MDLocation(line: 6, scope: !15)
+!33 = !MDLocation(line: 7, scope: !34)
+!34 = !{!"0xb\007\000\000", !5, !15} ; [ DW_TAG_lexical_block ] [/test.cpp]
+!35 = !{!36, !37, i64 0}
+!36 = !{!"_ZTS1A", !37, i64 0, !38, i64 8}
+!37 = !{!"int", !38, i64 0}
+!38 = !{!"omnipotent char", !39, i64 0}
+!39 = !{!"Simple C/C++ TBAA"}
+!40 = !MDLocation(line: 7, scope: !15)
+!41 = !MDLocation(line: 8, scope: !34)
+!42 = !{i64 0, i64 4, !43, i64 8, i64 16, !44}
+!43 = !{!37, !37, i64 0}
+!44 = !{!38, !38, i64 0}
+!45 = !MDLocation(line: 9, scope: !15)
+!46 = !{!"0x101\00p1\0016777222\000", !15, !16, !"_ZTS1A", !47} ; [ DW_TAG_arg_variable ] [p1] [line 6]
+!47 = distinct !MDLocation(line: 11, scope: !21)
+!48 = !{!"0x102\00147\004\0020"} ; [ DW_TAG_expression ] [DW_OP_piece offset=4, size=20]
+!49 = !MDLocation(line: 6, scope: !15, inlinedAt: !47)
+!50 = !MDLocation(line: 11, scope: !21)
+!51 = !{!"0x102\00147\000\004"} ; [ DW_TAG_expression ] [DW_OP_piece offset=0, size=4]
+!52 = !MDLocation(line: 7, scope: !34, inlinedAt: !47)
+!53 = !MDLocation(line: 7, scope: !15, inlinedAt: !47)
+!54 = !MDLocation(line: 8, scope: !34, inlinedAt: !47)
+!55 = !MDLocation(line: 14, scope: !24)
+!56 = !MDLocation(line: 15, scope: !24)
diff --git a/test/Transforms/Inline/debug-info-duplicate-calls.ll b/test/Transforms/Inline/debug-info-duplicate-calls.ll
new file mode 100644
index 0000000..2363693
--- /dev/null
+++ b/test/Transforms/Inline/debug-info-duplicate-calls.ll
@@ -0,0 +1,121 @@
+; RUN: opt < %s -always-inline -S | FileCheck %s
+
+; Original input generated from clang -emit-llvm -S -c -mllvm -disable-llvm-optzns
+;
+; #define CALLS1 f2(); f2();
+; #define CALLS2 f4(); f4();
+; void f1();
+; inline __attribute__((always_inline)) void f2() {
+; f1();
+; }
+; inline __attribute__((always_inline)) void f3() {
+; CALLS1
+; }
+; inline __attribute__((always_inline)) void f4() {
+; f3();
+; }
+; void f() {
+; CALLS2
+; }
+
+; There should be unique locations for all 4 of these instructions, correctly
+; describing the inlining that has occurred, even in the face of duplicate call
+; site locations.
+
+; The nomenclature used for the tags here is <function name>[cs<number>] where
+; 'cs' is an abbreviation for 'call site' and the number indicates which call
+; site from within the named function this is. (so, given the above inlining, we
+; should have 4 calls to 'f1', two from the first call to f4 and two from the
+; second call to f4)
+
+; CHECK: call void @_Z2f1v(), !dbg [[fcs1_f4_f3cs1_f2:![0-9]+]]
+; CHECK: call void @_Z2f1v(), !dbg [[fcs1_f4_f3cs2_f2:![0-9]+]]
+; CHECK: call void @_Z2f1v(), !dbg [[fcs2_f4_f3cs1_f2:![0-9]+]]
+; CHECK: call void @_Z2f1v(), !dbg [[fcs2_f4_f3cs2_f2:![0-9]+]]
+
+; CHECK-DAG: [[F:![0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [f]
+; CHECK-DAG: [[F2:![0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [f2]
+; CHECK-DAG: [[F3:![0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [f3]
+; CHECK-DAG: [[F4:![0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [f4]
+
+; CHECK: [[fcs1_f4_f3cs1_f2]] = {{.*}}, scope: [[F2]], inlinedAt: [[fcs1_f4_f3cs1:![0-9]+]])
+; CHECK: [[fcs1_f4_f3cs1]] = {{.*}}, scope: [[F3]], inlinedAt: [[fcs1_f4:![0-9]+]])
+; CHECK: [[fcs1_f4]] = {{.*}}, scope: [[F4]], inlinedAt: [[fcs1:![0-9]+]])
+; CHECK: [[fcs1]] = {{.*}}, scope: [[F]])
+; CHECK: [[fcs1_f4_f3cs2_f2]] = {{.*}}, scope: [[F2]], inlinedAt: [[fcs1_f4_f3cs2:![0-9]+]])
+; CHECK: [[fcs1_f4_f3cs2]] = {{.*}}, scope: [[F3]], inlinedAt: [[fcs1_f4]])
+
+; CHECK: [[fcs2_f4_f3cs1_f2]] = {{.*}}, scope: [[F2]], inlinedAt: [[fcs2_f4_f3cs1:![0-9]+]])
+; CHECK: [[fcs2_f4_f3cs1]] = {{.*}}, scope: [[F3]], inlinedAt: [[fcs2_f4:![0-9]+]])
+; CHECK: [[fcs2_f4]] = {{.*}}, scope: [[F4]], inlinedAt: [[fcs2:![0-9]+]])
+; CHECK: [[fcs2]] = {{.*}}, scope: [[F]])
+; CHECK: [[fcs2_f4_f3cs2_f2]] = {{.*}}, scope: [[F2]], inlinedAt: [[fcs2_f4_f3cs2:![0-9]+]])
+; CHECK: [[fcs2_f4_f3cs2]] = {{.*}}, scope: [[F3]], inlinedAt: [[fcs2_f4]])
+
+$_Z2f4v = comdat any
+
+$_Z2f3v = comdat any
+
+$_Z2f2v = comdat any
+
+; Function Attrs: uwtable
+define void @_Z1fv() #0 {
+entry:
+ call void @_Z2f4v(), !dbg !13
+ call void @_Z2f4v(), !dbg !13
+ ret void, !dbg !14
+}
+
+; Function Attrs: alwaysinline inlinehint uwtable
+define linkonce_odr void @_Z2f4v() #1 comdat {
+entry:
+ call void @_Z2f3v(), !dbg !15
+ ret void, !dbg !16
+}
+
+; Function Attrs: alwaysinline inlinehint uwtable
+define linkonce_odr void @_Z2f3v() #1 comdat {
+entry:
+ call void @_Z2f2v(), !dbg !17
+ call void @_Z2f2v(), !dbg !17
+ ret void, !dbg !18
+}
+
+; Function Attrs: alwaysinline inlinehint uwtable
+define linkonce_odr void @_Z2f2v() #1 comdat {
+entry:
+ call void @_Z2f1v(), !dbg !19
+ ret void, !dbg !20
+}
+
+declare void @_Z2f1v() #2
+
+attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { alwaysinline inlinehint uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!10, !11}
+!llvm.ident = !{!12}
+
+!0 = !{!"0x11\004\00clang version 3.7.0 (trunk 226474) (llvm/trunk 226478)\000\00\000\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/debug-info-duplicate-calls.cpp] [DW_LANG_C_plus_plus]
+!1 = !{!"debug-info-duplicate-calls.cpp", !"/tmp/dbginfo"}
+!2 = !{}
+!3 = !{!4, !7, !8, !9}
+!4 = !{!"0x2e\00f\00f\00\0013\000\001\000\000\00256\000\0013", !1, !5, !6, null, void ()* @_Z1fv, null, null, !2} ; [ DW_TAG_subprogram ] [line 13] [def] [f]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/tmp/dbginfo/debug-info-duplicate-calls.cpp]
+!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!"0x2e\00f4\00f4\00\0010\000\001\000\000\00256\000\0010", !1, !5, !6, null, void ()* @_Z2f4v, null, null, !2} ; [ DW_TAG_subprogram ] [line 10] [def] [f4]
+!8 = !{!"0x2e\00f3\00f3\00\007\000\001\000\000\00256\000\007", !1, !5, !6, null, void ()* @_Z2f3v, null, null, !2} ; [ DW_TAG_subprogram ] [line 7] [def] [f3]
+!9 = !{!"0x2e\00f2\00f2\00\004\000\001\000\000\00256\000\004", !1, !5, !6, null, void ()* @_Z2f2v, null, null, !2} ; [ DW_TAG_subprogram ] [line 4] [def] [f2]
+!10 = !{i32 2, !"Dwarf Version", i32 4}
+!11 = !{i32 2, !"Debug Info Version", i32 2}
+!12 = !{!"clang version 3.7.0 (trunk 226474) (llvm/trunk 226478)"}
+!13 = !MDLocation(line: 14, column: 3, scope: !4)
+!14 = !MDLocation(line: 15, column: 1, scope: !4)
+!15 = !MDLocation(line: 11, column: 3, scope: !7)
+!16 = !MDLocation(line: 12, column: 1, scope: !7)
+!17 = !MDLocation(line: 8, column: 3, scope: !8)
+!18 = !MDLocation(line: 9, column: 1, scope: !8)
+!19 = !MDLocation(line: 5, column: 3, scope: !9)
+!20 = !MDLocation(line: 6, column: 1, scope: !9)
diff --git a/test/Transforms/Inline/debug-invoke.ll b/test/Transforms/Inline/debug-invoke.ll
index 0de2d22..74ba9dc 100644
--- a/test/Transforms/Inline/debug-invoke.ll
+++ b/test/Transforms/Inline/debug-invoke.ll
@@ -4,9 +4,9 @@
; CHECK: invoke void @test()
; CHECK-NEXT: to label {{.*}} unwind label {{.*}}, !dbg [[INL_LOC:!.*]]
-; CHECK: [[EMPTY:.*]] = metadata !{}
-; CHECK: [[INL_LOC]] = metadata !{i32 1, i32 0, metadata [[EMPTY]], metadata [[INL_AT:.*]]}
-; CHECK: [[INL_AT]] = metadata !{i32 2, i32 0, metadata [[EMPTY]], null}
+; CHECK: [[EMPTY:.*]] = !{}
+; CHECK: [[INL_LOC]] = !MDLocation(line: 1, scope: [[EMPTY]], inlinedAt: [[INL_AT:.*]])
+; CHECK: [[INL_AT]] = distinct !MDLocation(line: 2, scope: [[EMPTY]])
declare void @test()
declare i32 @__gxx_personality_v0(...)
@@ -31,7 +31,7 @@ lpad:
}
!llvm.module.flags = !{!1}
-!1 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!2 = metadata !{}
-!3 = metadata !{i32 1, i32 0, metadata !2, null}
-!4 = metadata !{i32 2, i32 0, metadata !2, null}
+!1 = !{i32 2, !"Debug Info Version", i32 2}
+!2 = !{}
+!3 = !MDLocation(line: 1, scope: !2)
+!4 = !MDLocation(line: 2, scope: !2)
diff --git a/test/Transforms/Inline/ignore-debug-info.ll b/test/Transforms/Inline/ignore-debug-info.ll
index 428b5d5..8bd6e7c 100644
--- a/test/Transforms/Inline/ignore-debug-info.ll
+++ b/test/Transforms/Inline/ignore-debug-info.ll
@@ -47,9 +47,9 @@ attributes #0 = { nounwind readnone }
!llvm.module.flags = !{!3, !4}
!llvm.ident = !{!5}
-!0 = metadata !{metadata !"0x11\004\00\000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !{}, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ]
-!1 = metadata !{metadata !"", metadata !""}
-!2 = metadata !{i32 0}
-!3 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!4 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!5 = metadata !{metadata !""}
+!0 = !{!"0x11\004\00\000\00\000\00\000", !1, !2, !2, !{}, !2, !2} ; [ DW_TAG_compile_unit ]
+!1 = !{!"", !""}
+!2 = !{i32 0}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 1, !"Debug Info Version", i32 2}
+!5 = !{!""}
diff --git a/test/Transforms/Inline/inline-fast-math-flags.ll b/test/Transforms/Inline/inline-fast-math-flags.ll
new file mode 100644
index 0000000..c6a1487
--- /dev/null
+++ b/test/Transforms/Inline/inline-fast-math-flags.ll
@@ -0,0 +1,34 @@
+; RUN: opt < %s -S -inline -inline-threshold=20 | FileCheck %s
+; Check that we don't drop FastMathFlag when estimating inlining profitability.
+;
+; In this test we should inline 'foo' to 'boo', because it'll fold to a
+; constant.
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+define float @foo(float* %a, float %b) {
+entry:
+ %a0 = load float* %a, align 4
+ %mul = fmul fast float %a0, %b
+ %tobool = fcmp une float %mul, 0.000000e+00
+ br i1 %tobool, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %a1 = load float* %a, align 8
+ %arrayidx1 = getelementptr inbounds float* %a, i64 1
+ %a2 = load float* %arrayidx1, align 4
+ %add = fadd fast float %a1, %a2
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %storemerge = phi float [ %add, %if.then ], [ 1.000000e+00, %entry ]
+ ret float %storemerge
+}
+
+; CHECK-LABEL: @boo
+; CHECK-NOT: call float @foo
+define float @boo(float* %a) {
+entry:
+ %call = call float @foo(float* %a, float 0.000000e+00)
+ ret float %call
+}
diff --git a/test/Transforms/Inline/inline-fp.ll b/test/Transforms/Inline/inline-fp.ll
new file mode 100644
index 0000000..4d18ce8
--- /dev/null
+++ b/test/Transforms/Inline/inline-fp.ll
@@ -0,0 +1,136 @@
+; RUN: opt -S -inline < %s | FileCheck %s
+; Make sure that soft float implementations are calculated as being more expensive
+; to the inliner.
+
+define i32 @test_nofp() #0 {
+; f_nofp() has the "use-soft-float" attribute, so it should never get inlined.
+; CHECK-LABEL: test_nofp
+; CHECK: call float @f_nofp
+entry:
+ %responseX = alloca i32, align 4
+ %responseY = alloca i32, align 4
+ %responseZ = alloca i32, align 4
+ %valueX = alloca i8, align 1
+ %valueY = alloca i8, align 1
+ %valueZ = alloca i8, align 1
+
+ call void @getX(i32* %responseX, i8* %valueX)
+ call void @getY(i32* %responseY, i8* %valueY)
+ call void @getZ(i32* %responseZ, i8* %valueZ)
+
+ %0 = load i32* %responseX
+ %1 = load i8* %valueX
+ %call = call float @f_nofp(i32 %0, i8 zeroext %1)
+ %2 = load i32* %responseZ
+ %3 = load i8* %valueZ
+ %call2 = call float @f_nofp(i32 %2, i8 zeroext %3)
+ %call3 = call float @fabsf(float %call)
+ %cmp = fcmp ogt float %call3, 0x3FC1EB8520000000
+ br i1 %cmp, label %if.end12, label %if.else
+
+if.else: ; preds = %entry
+ %4 = load i32* %responseY
+ %5 = load i8* %valueY
+ %call1 = call float @f_nofp(i32 %4, i8 zeroext %5)
+ %call4 = call float @fabsf(float %call1)
+ %cmp5 = fcmp ogt float %call4, 0x3FC1EB8520000000
+ br i1 %cmp5, label %if.end12, label %if.else7
+
+if.else7: ; preds = %if.else
+ %call8 = call float @fabsf(float %call2)
+ %cmp9 = fcmp ogt float %call8, 0x3FC1EB8520000000
+ br i1 %cmp9, label %if.then10, label %if.end12
+
+if.then10: ; preds = %if.else7
+ br label %if.end12
+
+if.end12: ; preds = %if.else, %entry, %if.then10, %if.else7
+ %success.0 = phi i32 [ 0, %if.then10 ], [ 1, %if.else7 ], [ 0, %entry ], [ 0, %if.else ]
+ ret i32 %success.0
+}
+
+define i32 @test_hasfp() #0 {
+; f_hasfp() does not have the "use-soft-float" attribute, so it should get inlined.
+; CHECK-LABEL: test_hasfp
+; CHECK-NOT: call float @f_hasfp
+entry:
+ %responseX = alloca i32, align 4
+ %responseY = alloca i32, align 4
+ %responseZ = alloca i32, align 4
+ %valueX = alloca i8, align 1
+ %valueY = alloca i8, align 1
+ %valueZ = alloca i8, align 1
+
+ call void @getX(i32* %responseX, i8* %valueX)
+ call void @getY(i32* %responseY, i8* %valueY)
+ call void @getZ(i32* %responseZ, i8* %valueZ)
+
+ %0 = load i32* %responseX
+ %1 = load i8* %valueX
+ %call = call float @f_hasfp(i32 %0, i8 zeroext %1)
+ %2 = load i32* %responseZ
+ %3 = load i8* %valueZ
+ %call2 = call float @f_hasfp(i32 %2, i8 zeroext %3)
+ %call3 = call float @fabsf(float %call)
+ %cmp = fcmp ogt float %call3, 0x3FC1EB8520000000
+ br i1 %cmp, label %if.end12, label %if.else
+
+if.else: ; preds = %entry
+ %4 = load i32* %responseY
+ %5 = load i8* %valueY
+ %call1 = call float @f_hasfp(i32 %4, i8 zeroext %5)
+ %call4 = call float @fabsf(float %call1)
+ %cmp5 = fcmp ogt float %call4, 0x3FC1EB8520000000
+ br i1 %cmp5, label %if.end12, label %if.else7
+
+if.else7: ; preds = %if.else
+ %call8 = call float @fabsf(float %call2)
+ %cmp9 = fcmp ogt float %call8, 0x3FC1EB8520000000
+ br i1 %cmp9, label %if.then10, label %if.end12
+
+if.then10: ; preds = %if.else7
+ br label %if.end12
+
+if.end12: ; preds = %if.else, %entry, %if.then10, %if.else7
+ %success.0 = phi i32 [ 0, %if.then10 ], [ 1, %if.else7 ], [ 0, %entry ], [ 0, %if.else ]
+ ret i32 %success.0
+}
+
+declare void @getX(i32*, i8*) #0
+
+declare void @getY(i32*, i8*) #0
+
+declare void @getZ(i32*, i8*) #0
+
+define internal float @f_hasfp(i32 %response, i8 zeroext %value1) #0 {
+entry:
+ %conv = zext i8 %value1 to i32
+ %sub = add nsw i32 %conv, -1
+ %conv1 = sitofp i32 %sub to float
+ %0 = tail call float @llvm.pow.f32(float 0x3FF028F5C0000000, float %conv1)
+ %mul = fmul float %0, 2.620000e+03
+ %conv2 = sitofp i32 %response to float
+ %sub3 = fsub float %conv2, %mul
+ %div = fdiv float %sub3, %mul
+ ret float %div
+}
+
+define internal float @f_nofp(i32 %response, i8 zeroext %value1) #1 {
+entry:
+ %conv = zext i8 %value1 to i32
+ %sub = add nsw i32 %conv, -1
+ %conv1 = sitofp i32 %sub to float
+ %0 = tail call float @llvm.pow.f32(float 0x3FF028F5C0000000, float %conv1)
+ %mul = fmul float %0, 2.620000e+03
+ %conv2 = sitofp i32 %response to float
+ %sub3 = fsub float %conv2, %mul
+ %div = fdiv float %sub3, %mul
+ ret float %div
+}
+
+declare float @fabsf(float) optsize minsize
+
+declare float @llvm.pow.f32(float, float) optsize minsize
+
+attributes #0 = { minsize optsize }
+attributes #1 = { minsize optsize "use-soft-float"="true" }
diff --git a/test/Transforms/Inline/inline-indirect.ll b/test/Transforms/Inline/inline-indirect.ll
new file mode 100644
index 0000000..f6eb528
--- /dev/null
+++ b/test/Transforms/Inline/inline-indirect.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -inline -disable-output 2>/dev/null
+; This test used to trigger an assertion in the assumption cache when
+; inlining the indirect call
+declare void @llvm.assume(i1)
+
+define void @foo() {
+ ret void
+}
+
+define void @bar(void ()*) {
+ call void @llvm.assume(i1 true)
+ call void %0();
+ ret void
+}
+
+define void @baz() {
+ call void @bar(void ()* @foo)
+ ret void
+}
diff --git a/test/Transforms/Inline/inline-vla.ll b/test/Transforms/Inline/inline-vla.ll
index dc9deaa..7da448b 100644
--- a/test/Transforms/Inline/inline-vla.ll
+++ b/test/Transforms/Inline/inline-vla.ll
@@ -35,4 +35,4 @@ attributes #2 = { nounwind }
!llvm.ident = !{!0}
-!0 = metadata !{metadata !"clang version 3.5.0 (trunk 205695) (llvm/trunk 205706)"}
+!0 = !{!"clang version 3.5.0 (trunk 205695) (llvm/trunk 205706)"}
diff --git a/test/Transforms/Inline/inline_dbg_declare.ll b/test/Transforms/Inline/inline_dbg_declare.ll
new file mode 100644
index 0000000..d296678
--- /dev/null
+++ b/test/Transforms/Inline/inline_dbg_declare.ll
@@ -0,0 +1,97 @@
+; RUN: opt < %s -S -inline | FileCheck %s
+;
+; The purpose of this test is to check that inline pass preserves debug info
+; for variable using the dbg.declare intrinsic.
+;
+;; This test was generated by running this command:
+;; clang.exe -S -O0 -emit-llvm -g foo.c
+;;
+;; foo.c
+;; ==========================
+;; float foo(float x)
+;; {
+;; return x;
+;; }
+;;
+;; void bar(float *dst)
+;; {
+;; dst[0] = foo(dst[0]);
+;; }
+;; ==========================
+
+target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
+target triple = "i686-pc-windows-msvc"
+
+; Function Attrs: nounwind
+define float @foo(float %x) #0 {
+entry:
+ %x.addr = alloca float, align 4
+ store float %x, float* %x.addr, align 4
+ call void @llvm.dbg.declare(metadata float* %x.addr, metadata !16, metadata !17), !dbg !18
+ %0 = load float* %x.addr, align 4, !dbg !19
+ ret float %0, !dbg !19
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+; CHECK: define void @bar
+
+; Function Attrs: nounwind
+define void @bar(float* %dst) #0 {
+entry:
+
+; CHECK: [[x_addr_i:%[a-zA-Z0-9.]+]] = alloca float, align 4
+
+ %dst.addr = alloca float*, align 4
+ store float* %dst, float** %dst.addr, align 4
+ call void @llvm.dbg.declare(metadata float** %dst.addr, metadata !20, metadata !17), !dbg !21
+ %0 = load float** %dst.addr, align 4, !dbg !22
+ %arrayidx = getelementptr inbounds float* %0, i32 0, !dbg !22
+ %1 = load float* %arrayidx, align 4, !dbg !22
+ %call = call float @foo(float %1), !dbg !22
+
+; CHECK-NOT: call float @foo
+; CHECK: void @llvm.dbg.declare(metadata float* [[x_addr_i]], metadata [[m23:![0-9]+]], metadata !17), !dbg [[m24:![0-9]+]]
+
+ %2 = load float** %dst.addr, align 4, !dbg !22
+ %arrayidx1 = getelementptr inbounds float* %2, i32 0, !dbg !22
+ store float %call, float* %arrayidx1, align 4, !dbg !22
+ ret void, !dbg !23
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!13, !14}
+!llvm.ident = !{!15}
+
+!0 = !{!"0x11\0012\00clang version 3.6.0 (trunk)\000\00\000\00\001", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [foo.c] [DW_LANG_C99]
+!1 = !{!"foo.c", !""}
+!2 = !{}
+!3 = !{!4, !9}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\000\00256\000\002", !1, !5, !6, null, float (float)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [scope 2] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [foo.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!8, !8}
+!8 = !{!"0x24\00float\000\0032\0032\000\000\004", null, null} ; [ DW_TAG_base_type ] [float] [line 0, size 32, align 32, offset 0, enc DW_ATE_float]
+!9 = !{!"0x2e\00bar\00bar\00\006\000\001\000\000\00256\000\007", !1, !5, !10, null, void (float*)* @bar, null, null, !2} ; [ DW_TAG_subprogram ] [line 6] [def] [scope 7] [bar]
+!10 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !11, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!11 = !{null, !12}
+!12 = !{!"0xf\00\000\0032\0032\000\000", null, null, !8} ; [ DW_TAG_pointer_type ] [line 0, size 32, align 32, offset 0] [from float]
+!13 = !{i32 2, !"Dwarf Version", i32 4}
+!14 = !{i32 2, !"Debug Info Version", i32 2}
+!15 = !{!"clang version 3.6.0 (trunk)"}
+!16 = !{!"0x101\00x\0016777217\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [x] [line 1]
+!17 = !{!"0x102"} ; [ DW_TAG_expression ]
+!18 = !MDLocation(line: 1, column: 17, scope: !4)
+!19 = !MDLocation(line: 3, column: 5, scope: !4)
+!20 = !{!"0x101\00dst\0016777222\000", !9, !5, !12} ; [ DW_TAG_arg_variable ] [dst] [line 6]
+!21 = !MDLocation(line: 6, column: 17, scope: !9)
+!22 = !MDLocation(line: 8, column: 14, scope: !9)
+!23 = !MDLocation(line: 9, column: 1, scope: !9)
+
+; CHECK: [[CALL_SITE:![0-9]+]] = distinct !MDLocation(line: 8, column: 14, scope: !9)
+; CHECK: [[m23]] = !{!"0x101\00x\0016777217\000", !4, !5, !8, [[CALL_SITE]]} ; [ DW_TAG_arg_variable ] [x] [line 1]
+; CHECK: [[m24]] = !MDLocation(line: 1, column: 17, scope: !4, inlinedAt: [[CALL_SITE]])
diff --git a/test/Transforms/Inline/noalias-calls.ll b/test/Transforms/Inline/noalias-calls.ll
index 13408e4..c09d2a6 100644
--- a/test/Transforms/Inline/noalias-calls.ll
+++ b/test/Transforms/Inline/noalias-calls.ll
@@ -35,10 +35,10 @@ entry:
attributes #0 = { nounwind }
attributes #1 = { nounwind uwtable }
-; CHECK: !0 = metadata !{metadata !1}
-; CHECK: !1 = metadata !{metadata !1, metadata !2, metadata !"hello: %c"}
-; CHECK: !2 = metadata !{metadata !2, metadata !"hello"}
-; CHECK: !3 = metadata !{metadata !4}
-; CHECK: !4 = metadata !{metadata !4, metadata !2, metadata !"hello: %a"}
-; CHECK: !5 = metadata !{metadata !4, metadata !1}
+; CHECK: !0 = !{!1}
+; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
+; CHECK: !2 = distinct !{!2, !"hello"}
+; CHECK: !3 = !{!4}
+; CHECK: !4 = distinct !{!4, !2, !"hello: %a"}
+; CHECK: !5 = !{!4, !1}
diff --git a/test/Transforms/Inline/noalias-cs.ll b/test/Transforms/Inline/noalias-cs.ll
index acd9021..da5ddd6 100644
--- a/test/Transforms/Inline/noalias-cs.ll
+++ b/test/Transforms/Inline/noalias-cs.ll
@@ -46,39 +46,39 @@ entry:
attributes #0 = { nounwind uwtable }
-!0 = metadata !{metadata !1}
-!1 = metadata !{metadata !1, metadata !2, metadata !"hello: %a"}
-!2 = metadata !{metadata !2, metadata !"hello"}
-!3 = metadata !{metadata !4, metadata !6}
-!4 = metadata !{metadata !4, metadata !5, metadata !"hello2: %a"}
-!5 = metadata !{metadata !5, metadata !"hello2"}
-!6 = metadata !{metadata !6, metadata !5, metadata !"hello2: %b"}
-!7 = metadata !{metadata !4}
-!8 = metadata !{metadata !6}
+!0 = !{!1}
+!1 = distinct !{!1, !2, !"hello: %a"}
+!2 = distinct !{!2, !"hello"}
+!3 = !{!4, !6}
+!4 = distinct !{!4, !5, !"hello2: %a"}
+!5 = distinct !{!5, !"hello2"}
+!6 = distinct !{!6, !5, !"hello2: %b"}
+!7 = !{!4}
+!8 = !{!6}
-; CHECK: !0 = metadata !{metadata !1, metadata !3}
-; CHECK: !1 = metadata !{metadata !1, metadata !2, metadata !"hello2: %a"}
-; CHECK: !2 = metadata !{metadata !2, metadata !"hello2"}
-; CHECK: !3 = metadata !{metadata !3, metadata !2, metadata !"hello2: %b"}
-; CHECK: !4 = metadata !{metadata !1}
-; CHECK: !5 = metadata !{metadata !3}
-; CHECK: !6 = metadata !{metadata !7, metadata !9, metadata !10}
-; CHECK: !7 = metadata !{metadata !7, metadata !8, metadata !"hello2: %a"}
-; CHECK: !8 = metadata !{metadata !8, metadata !"hello2"}
-; CHECK: !9 = metadata !{metadata !9, metadata !8, metadata !"hello2: %b"}
-; CHECK: !10 = metadata !{metadata !10, metadata !11, metadata !"hello: %a"}
-; CHECK: !11 = metadata !{metadata !11, metadata !"hello"}
-; CHECK: !12 = metadata !{metadata !7}
-; CHECK: !13 = metadata !{metadata !9, metadata !10}
-; CHECK: !14 = metadata !{metadata !9}
-; CHECK: !15 = metadata !{metadata !7, metadata !10}
-; CHECK: !16 = metadata !{metadata !10}
-; CHECK: !17 = metadata !{metadata !18, metadata !20}
-; CHECK: !18 = metadata !{metadata !18, metadata !19, metadata !"hello2: %a"}
-; CHECK: !19 = metadata !{metadata !19, metadata !"hello2"}
-; CHECK: !20 = metadata !{metadata !20, metadata !19, metadata !"hello2: %b"}
-; CHECK: !21 = metadata !{metadata !18, metadata !10}
-; CHECK: !22 = metadata !{metadata !20}
-; CHECK: !23 = metadata !{metadata !20, metadata !10}
-; CHECK: !24 = metadata !{metadata !18}
+; CHECK: !0 = !{!1, !3}
+; CHECK: !1 = distinct !{!1, !2, !"hello2: %a"}
+; CHECK: !2 = distinct !{!2, !"hello2"}
+; CHECK: !3 = distinct !{!3, !2, !"hello2: %b"}
+; CHECK: !4 = !{!1}
+; CHECK: !5 = !{!3}
+; CHECK: !6 = !{!7, !9, !10}
+; CHECK: !7 = distinct !{!7, !8, !"hello2: %a"}
+; CHECK: !8 = distinct !{!8, !"hello2"}
+; CHECK: !9 = distinct !{!9, !8, !"hello2: %b"}
+; CHECK: !10 = distinct !{!10, !11, !"hello: %a"}
+; CHECK: !11 = distinct !{!11, !"hello"}
+; CHECK: !12 = !{!7}
+; CHECK: !13 = !{!9, !10}
+; CHECK: !14 = !{!9}
+; CHECK: !15 = !{!7, !10}
+; CHECK: !16 = !{!10}
+; CHECK: !17 = !{!18, !20}
+; CHECK: !18 = distinct !{!18, !19, !"hello2: %a"}
+; CHECK: !19 = distinct !{!19, !"hello2"}
+; CHECK: !20 = distinct !{!20, !19, !"hello2: %b"}
+; CHECK: !21 = !{!18, !10}
+; CHECK: !22 = !{!20}
+; CHECK: !23 = !{!20, !10}
+; CHECK: !24 = !{!18}
diff --git a/test/Transforms/Inline/noalias.ll b/test/Transforms/Inline/noalias.ll
index 7a54d5d..674da1e 100644
--- a/test/Transforms/Inline/noalias.ll
+++ b/test/Transforms/Inline/noalias.ll
@@ -64,13 +64,13 @@ entry:
attributes #0 = { nounwind uwtable }
-; CHECK: !0 = metadata !{metadata !1}
-; CHECK: !1 = metadata !{metadata !1, metadata !2, metadata !"hello: %a"}
-; CHECK: !2 = metadata !{metadata !2, metadata !"hello"}
-; CHECK: !3 = metadata !{metadata !4, metadata !6}
-; CHECK: !4 = metadata !{metadata !4, metadata !5, metadata !"hello2: %a"}
-; CHECK: !5 = metadata !{metadata !5, metadata !"hello2"}
-; CHECK: !6 = metadata !{metadata !6, metadata !5, metadata !"hello2: %b"}
-; CHECK: !7 = metadata !{metadata !4}
-; CHECK: !8 = metadata !{metadata !6}
+; CHECK: !0 = !{!1}
+; CHECK: !1 = distinct !{!1, !2, !"hello: %a"}
+; CHECK: !2 = distinct !{!2, !"hello"}
+; CHECK: !3 = !{!4, !6}
+; CHECK: !4 = distinct !{!4, !5, !"hello2: %a"}
+; CHECK: !5 = distinct !{!5, !"hello2"}
+; CHECK: !6 = distinct !{!6, !5, !"hello2: %b"}
+; CHECK: !7 = !{!4}
+; CHECK: !8 = !{!6}
diff --git a/test/Transforms/Inline/noalias2.ll b/test/Transforms/Inline/noalias2.ll
index a4b38b0..9c8f8e2 100644
--- a/test/Transforms/Inline/noalias2.ll
+++ b/test/Transforms/Inline/noalias2.ll
@@ -71,27 +71,27 @@ entry:
; CHECK: ret void
; CHECK: }
-; CHECK: !0 = metadata !{metadata !1}
-; CHECK: !1 = metadata !{metadata !1, metadata !2, metadata !"hello: %c"}
-; CHECK: !2 = metadata !{metadata !2, metadata !"hello"}
-; CHECK: !3 = metadata !{metadata !4}
-; CHECK: !4 = metadata !{metadata !4, metadata !2, metadata !"hello: %a"}
-; CHECK: !5 = metadata !{metadata !6, metadata !8}
-; CHECK: !6 = metadata !{metadata !6, metadata !7, metadata !"hello: %c"}
-; CHECK: !7 = metadata !{metadata !7, metadata !"hello"}
-; CHECK: !8 = metadata !{metadata !8, metadata !9, metadata !"foo: %c"}
-; CHECK: !9 = metadata !{metadata !9, metadata !"foo"}
-; CHECK: !10 = metadata !{metadata !11, metadata !12}
-; CHECK: !11 = metadata !{metadata !11, metadata !7, metadata !"hello: %a"}
-; CHECK: !12 = metadata !{metadata !12, metadata !9, metadata !"foo: %a"}
-; CHECK: !13 = metadata !{metadata !8}
-; CHECK: !14 = metadata !{metadata !12}
-; CHECK: !15 = metadata !{metadata !16, metadata !18}
-; CHECK: !16 = metadata !{metadata !16, metadata !17, metadata !"hello2: %a"}
-; CHECK: !17 = metadata !{metadata !17, metadata !"hello2"}
-; CHECK: !18 = metadata !{metadata !18, metadata !17, metadata !"hello2: %b"}
-; CHECK: !19 = metadata !{metadata !16}
-; CHECK: !20 = metadata !{metadata !18}
+; CHECK: !0 = !{!1}
+; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
+; CHECK: !2 = distinct !{!2, !"hello"}
+; CHECK: !3 = !{!4}
+; CHECK: !4 = distinct !{!4, !2, !"hello: %a"}
+; CHECK: !5 = !{!6, !8}
+; CHECK: !6 = distinct !{!6, !7, !"hello: %c"}
+; CHECK: !7 = distinct !{!7, !"hello"}
+; CHECK: !8 = distinct !{!8, !9, !"foo: %c"}
+; CHECK: !9 = distinct !{!9, !"foo"}
+; CHECK: !10 = !{!11, !12}
+; CHECK: !11 = distinct !{!11, !7, !"hello: %a"}
+; CHECK: !12 = distinct !{!12, !9, !"foo: %a"}
+; CHECK: !13 = !{!8}
+; CHECK: !14 = !{!12}
+; CHECK: !15 = !{!16, !18}
+; CHECK: !16 = distinct !{!16, !17, !"hello2: %a"}
+; CHECK: !17 = distinct !{!17, !"hello2"}
+; CHECK: !18 = distinct !{!18, !17, !"hello2: %b"}
+; CHECK: !19 = !{!16}
+; CHECK: !20 = !{!18}
attributes #0 = { nounwind uwtable }
diff --git a/test/Transforms/Inline/optimization-remarks.ll b/test/Transforms/Inline/optimization-remarks.ll
index 9108f3a..fb1b047 100644
--- a/test/Transforms/Inline/optimization-remarks.ll
+++ b/test/Transforms/Inline/optimization-remarks.ll
@@ -57,4 +57,4 @@ attributes #2 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointe
!llvm.ident = !{!0}
-!0 = metadata !{metadata !"clang version 3.5.0 "}
+!0 = !{!"clang version 3.5.0 "}
diff --git a/test/Transforms/Inline/pr21206.ll b/test/Transforms/Inline/pr21206.ll
index 1a4366e..e460030 100644
--- a/test/Transforms/Inline/pr21206.ll
+++ b/test/Transforms/Inline/pr21206.ll
@@ -3,15 +3,15 @@
$c = comdat any
; CHECK: $c = comdat any
-define linkonce_odr void @foo() comdat $c {
+define linkonce_odr void @foo() comdat($c) {
ret void
}
-; CHECK: define linkonce_odr void @foo() comdat $c
+; CHECK: define linkonce_odr void @foo() comdat($c)
-define linkonce_odr void @bar() comdat $c {
+define linkonce_odr void @bar() comdat($c) {
ret void
}
-; CHECK: define linkonce_odr void @bar() comdat $c
+; CHECK: define linkonce_odr void @bar() comdat($c)
define void()* @zed() {
ret void()* @foo
diff --git a/test/Transforms/InstCombine/2008-05-23-CompareFold.ll b/test/Transforms/InstCombine/2008-05-23-CompareFold.ll
index acb259b..b729677 100644
--- a/test/Transforms/InstCombine/2008-05-23-CompareFold.ll
+++ b/test/Transforms/InstCombine/2008-05-23-CompareFold.ll
@@ -1,5 +1,8 @@
-; RUN: opt < %s -instcombine -S | grep "ret i1 false"
+; RUN: opt -instcombine -S < %s | FileCheck %s
; PR2359
+
+; CHECK-LABEL: @f(
+; CHECK: ret i1 false
define i1 @f(i8* %x) {
entry:
%tmp462 = load i8* %x, align 1 ; <i8> [#uses=1]
diff --git a/test/Transforms/InstCombine/2008-11-08-FCmp.ll b/test/Transforms/InstCombine/2008-11-08-FCmp.ll
index f33a1f5..f1af7ce 100644
--- a/test/Transforms/InstCombine/2008-11-08-FCmp.ll
+++ b/test/Transforms/InstCombine/2008-11-08-FCmp.ll
@@ -4,6 +4,7 @@
; When inst combining an FCMP with the LHS coming from a uitofp instruction, we
; can't lower it to signed ICMP instructions.
+; CHECK-LABEL: @test1(
define i1 @test1(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp ole double %1, 0.000000e+00
@@ -11,6 +12,7 @@ define i1 @test1(i32 %val) {
ret i1 %2
}
+; CHECK-LABEL: @test2(
define i1 @test2(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp olt double %1, 0.000000e+00
@@ -18,6 +20,7 @@ define i1 @test2(i32 %val) {
; CHECK: ret i1 false
}
+; CHECK-LABEL: @test3(
define i1 @test3(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp oge double %1, 0.000000e+00
@@ -25,6 +28,7 @@ define i1 @test3(i32 %val) {
; CHECK: ret i1 true
}
+; CHECK-LABEL: @test4(
define i1 @test4(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp ogt double %1, 0.000000e+00
@@ -32,6 +36,7 @@ define i1 @test4(i32 %val) {
ret i1 %2
}
+; CHECK-LABEL: @test5(
define i1 @test5(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp ogt double %1, -4.400000e+00
@@ -39,6 +44,7 @@ define i1 @test5(i32 %val) {
; CHECK: ret i1 true
}
+; CHECK-LABEL: @test6(
define i1 @test6(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp olt double %1, -4.400000e+00
@@ -48,6 +54,7 @@ define i1 @test6(i32 %val) {
; Check that optimizing unsigned >= comparisons correctly distinguishes
; positive and negative constants. <rdar://problem/12029145>
+; CHECK-LABEL: @test7(
define i1 @test7(i32 %val) {
%1 = uitofp i32 %val to double
%2 = fcmp oge double %1, 3.200000e+00
diff --git a/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll b/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll
index 895b260..c8f0351 100644
--- a/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll
+++ b/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll
@@ -50,7 +50,8 @@ define void @fu2(i32 %parm) nounwind ssp {
%7 = add i32 %6, 2048
; CHECK: alloca i8
%8 = alloca i8, i32 %7
-; CHECK-NEXT: bitcast i8*
+; CHECK-NEXT: bitcast double**
+; CHECK-NEXT: store i8*
%9 = bitcast i8* %8 to double*
store double* %9, double** %ptr, align 4
br label %10
diff --git a/test/Transforms/InstCombine/AddOverFlow.ll b/test/Transforms/InstCombine/AddOverFlow.ll
index 8f3d429..bebfd62 100644
--- a/test/Transforms/InstCombine/AddOverFlow.ll
+++ b/test/Transforms/InstCombine/AddOverFlow.ll
@@ -36,8 +36,8 @@ define i16 @zero_sign_bit2(i16 %a, i16 %b) {
declare i16 @bounded(i16 %input);
declare i32 @__gxx_personality_v0(...);
-!0 = metadata !{i16 0, i16 32768} ; [0, 32767]
-!1 = metadata !{i16 0, i16 32769} ; [0, 32768]
+!0 = !{i16 0, i16 32768} ; [0, 32767]
+!1 = !{i16 0, i16 32769} ; [0, 32768]
define i16 @add_bounded_values(i16 %a, i16 %b) {
; CHECK-LABEL: @add_bounded_values(
diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll
index 10af4bc..0d42f7c 100644
--- a/test/Transforms/InstCombine/LandingPadClauses.ll
+++ b/test/Transforms/InstCombine/LandingPadClauses.ll
@@ -7,6 +7,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 i32 @__C_specific_handler(...)
declare void @bar()
@@ -231,3 +232,54 @@ lpad.d:
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
}
+
+define void @foo_seh() {
+; CHECK-LABEL: @foo_seh(
+ 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 (...)* @__C_specific_handler
+ catch i32* null
+ catch i32* @T1
+ unreachable
+; CHECK: %a = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+
+lpad.b:
+ %b = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
+ filter [1 x i32*] zeroinitializer
+ unreachable
+; CHECK: %b = landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: unreachable
+
+lpad.c:
+ %c = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
+ 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 (...)* @__C_specific_handler
+ cleanup
+ catch i32* null
+ unreachable
+; CHECK: %d = landingpad
+; CHECK-NEXT: null
+; CHECK-NEXT: unreachable
+}
diff --git a/test/Transforms/InstCombine/add2.ll b/test/Transforms/InstCombine/add2.ll
index a166e5f..fbbba59 100644
--- a/test/Transforms/InstCombine/add2.ll
+++ b/test/Transforms/InstCombine/add2.ll
@@ -219,7 +219,7 @@ define i16 @mul_add_to_mul_1(i16 %x) {
%add2 = add nsw i16 %x, %mul1
ret i16 %add2
; CHECK-LABEL: @mul_add_to_mul_1(
-; CHECK-NEXT: %add2 = mul i16 %x, 9
+; CHECK-NEXT: %add2 = mul nsw i16 %x, 9
; CHECK-NEXT: ret i16 %add2
}
@@ -228,7 +228,7 @@ define i16 @mul_add_to_mul_2(i16 %x) {
%add2 = add nsw i16 %mul1, %x
ret i16 %add2
; CHECK-LABEL: @mul_add_to_mul_2(
-; CHECK-NEXT: %add2 = mul i16 %x, 9
+; CHECK-NEXT: %add2 = mul nsw i16 %x, 9
; CHECK-NEXT: ret i16 %add2
}
@@ -248,7 +248,7 @@ define i16 @mul_add_to_mul_4(i16 %a) {
%add = add nsw i16 %mul1, %mul2
ret i16 %add
; CHECK-LABEL: @mul_add_to_mul_4(
-; CHECK-NEXT: %add = mul i16 %a, 9
+; CHECK-NEXT: %add = mul nsw i16 %a, 9
; CHECK-NEXT: ret i16 %add
}
@@ -294,7 +294,7 @@ define i16 @add_cttz(i16 %a) {
ret i16 %b
}
declare i16 @llvm.cttz.i16(i16, i1)
-!0 = metadata !{i16 0, i16 8}
+!0 = !{i16 0, i16 8}
; Similar to @add_cttz, but in this test, the range implied by the
; intrinsic is more strict. Therefore, ValueTracking uses that range.
@@ -312,7 +312,7 @@ define i16 @add_cttz_2(i16 %a) {
; CHECK: or i16 %cttz, -16
ret i16 %b
}
-!1 = metadata !{i16 0, i16 32}
+!1 = !{i16 0, i16 32}
define i32 @add_or_and(i32 %x, i32 %y) {
%or = or i32 %x, %y
diff --git a/test/Transforms/InstCombine/addnegneg.ll b/test/Transforms/InstCombine/addnegneg.ll
index ad8791d..90f6baf 100644
--- a/test/Transforms/InstCombine/addnegneg.ll
+++ b/test/Transforms/InstCombine/addnegneg.ll
@@ -9,4 +9,3 @@ entry:
%sub6 = add i32 %sub4, %d ; <i32> [#uses=1]
ret i32 %sub6
}
-
diff --git a/test/Transforms/InstCombine/alias-recursion.ll b/test/Transforms/InstCombine/alias-recursion.ll
new file mode 100644
index 0000000..fa63726
--- /dev/null
+++ b/test/Transforms/InstCombine/alias-recursion.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+%class.A = type { i32 (...)** }
+
+@0 = constant [1 x i8*] zeroinitializer
+
+@vtbl = alias getelementptr inbounds ([1 x i8*]* @0, i32 0, i32 0)
+
+define i32 (%class.A*)* @test() {
+; CHECK-LABEL: test
+entry:
+ br i1 undef, label %for.body, label %for.end
+
+for.body: ; preds = %for.body, %entry
+ br i1 undef, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ %A = phi i32 (%class.A*)** [ bitcast (i8** @vtbl to i32 (%class.A*)**), %for.body ], [ null, %entry ]
+ %B = load i32 (%class.A*)** %A
+ ret i32 (%class.A*)* %B
+}
diff --git a/test/Transforms/InstCombine/aligned-altivec.ll b/test/Transforms/InstCombine/aligned-altivec.ll
new file mode 100644
index 0000000..6ac2691
--- /dev/null
+++ b/test/Transforms/InstCombine/aligned-altivec.ll
@@ -0,0 +1,131 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+declare <4 x i32> @llvm.ppc.altivec.lvx(i8*) #1
+
+define <4 x i32> @test1(<4 x i32>* %h) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ %vl = call <4 x i32> @llvm.ppc.altivec.lvx(i8* %hv)
+
+; CHECK-LABEL: @test1
+; CHECK: @llvm.ppc.altivec.lvx
+; CHECK: ret <4 x i32>
+
+ %v0 = load <4 x i32>* %h, align 8
+ %a = add <4 x i32> %v0, %vl
+ ret <4 x i32> %a
+}
+
+define <4 x i32> @test1a(<4 x i32>* align 16 %h) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ %vl = call <4 x i32> @llvm.ppc.altivec.lvx(i8* %hv)
+
+; CHECK-LABEL: @test1a
+; CHECK-NOT: @llvm.ppc.altivec.lvx
+; CHECK: ret <4 x i32>
+
+ %v0 = load <4 x i32>* %h, align 8
+ %a = add <4 x i32> %v0, %vl
+ ret <4 x i32> %a
+}
+
+declare void @llvm.ppc.altivec.stvx(<4 x i32>, i8*) #0
+
+define <4 x i32> @test2(<4 x i32>* %h, <4 x i32> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ call void @llvm.ppc.altivec.stvx(<4 x i32> %d, i8* %hv)
+
+ %v0 = load <4 x i32>* %h, align 8
+ ret <4 x i32> %v0
+
+; CHECK-LABEL: @test2
+; CHECK: @llvm.ppc.altivec.stvx
+; CHECK: ret <4 x i32>
+}
+
+define <4 x i32> @test2a(<4 x i32>* align 16 %h, <4 x i32> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ call void @llvm.ppc.altivec.stvx(<4 x i32> %d, i8* %hv)
+
+ %v0 = load <4 x i32>* %h, align 8
+ ret <4 x i32> %v0
+
+; CHECK-LABEL: @test2
+; CHECK-NOT: @llvm.ppc.altivec.stvx
+; CHECK: ret <4 x i32>
+}
+
+declare <4 x i32> @llvm.ppc.altivec.lvxl(i8*) #1
+
+define <4 x i32> @test1l(<4 x i32>* %h) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ %vl = call <4 x i32> @llvm.ppc.altivec.lvxl(i8* %hv)
+
+; CHECK-LABEL: @test1l
+; CHECK: @llvm.ppc.altivec.lvxl
+; CHECK: ret <4 x i32>
+
+ %v0 = load <4 x i32>* %h, align 8
+ %a = add <4 x i32> %v0, %vl
+ ret <4 x i32> %a
+}
+
+define <4 x i32> @test1la(<4 x i32>* align 16 %h) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ %vl = call <4 x i32> @llvm.ppc.altivec.lvxl(i8* %hv)
+
+; CHECK-LABEL: @test1la
+; CHECK-NOT: @llvm.ppc.altivec.lvxl
+; CHECK: ret <4 x i32>
+
+ %v0 = load <4 x i32>* %h, align 8
+ %a = add <4 x i32> %v0, %vl
+ ret <4 x i32> %a
+}
+
+declare void @llvm.ppc.altivec.stvxl(<4 x i32>, i8*) #0
+
+define <4 x i32> @test2l(<4 x i32>* %h, <4 x i32> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ call void @llvm.ppc.altivec.stvxl(<4 x i32> %d, i8* %hv)
+
+ %v0 = load <4 x i32>* %h, align 8
+ ret <4 x i32> %v0
+
+; CHECK-LABEL: @test2l
+; CHECK: @llvm.ppc.altivec.stvxl
+; CHECK: ret <4 x i32>
+}
+
+define <4 x i32> @test2la(<4 x i32>* align 16 %h, <4 x i32> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x i32>* %h, i64 1
+ %hv = bitcast <4 x i32>* %h1 to i8*
+ call void @llvm.ppc.altivec.stvxl(<4 x i32> %d, i8* %hv)
+
+ %v0 = load <4 x i32>* %h, align 8
+ ret <4 x i32> %v0
+
+; CHECK-LABEL: @test2l
+; CHECK-NOT: @llvm.ppc.altivec.stvxl
+; CHECK: ret <4 x i32>
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readonly }
+
diff --git a/test/Transforms/InstCombine/aligned-qpx.ll b/test/Transforms/InstCombine/aligned-qpx.ll
new file mode 100644
index 0000000..c8a1f6f
--- /dev/null
+++ b/test/Transforms/InstCombine/aligned-qpx.ll
@@ -0,0 +1,162 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+declare <4 x double> @llvm.ppc.qpx.qvlfs(i8*) #1
+
+define <4 x double> @test1(<4 x float>* %h) #0 {
+entry:
+ %h1 = getelementptr <4 x float>* %h, i64 1
+ %hv = bitcast <4 x float>* %h1 to i8*
+ %vl = call <4 x double> @llvm.ppc.qpx.qvlfs(i8* %hv)
+
+; CHECK-LABEL: @test1
+; CHECK: @llvm.ppc.qpx.qvlfs
+; CHECK: ret <4 x double>
+
+ %v0 = load <4 x float>* %h, align 8
+ %v0e = fpext <4 x float> %v0 to <4 x double>
+ %a = fadd <4 x double> %v0e, %vl
+ ret <4 x double> %a
+}
+
+define <4 x double> @test1a(<4 x float>* align 16 %h) #0 {
+entry:
+ %h1 = getelementptr <4 x float>* %h, i64 1
+ %hv = bitcast <4 x float>* %h1 to i8*
+ %vl = call <4 x double> @llvm.ppc.qpx.qvlfs(i8* %hv)
+
+; CHECK-LABEL: @test1a
+; CHECK-NOT: @llvm.ppc.qpx.qvlfs
+; CHECK: ret <4 x double>
+
+ %v0 = load <4 x float>* %h, align 8
+ %v0e = fpext <4 x float> %v0 to <4 x double>
+ %a = fadd <4 x double> %v0e, %vl
+ ret <4 x double> %a
+}
+
+declare void @llvm.ppc.qpx.qvstfs(<4 x double>, i8*) #0
+
+define <4 x float> @test2(<4 x float>* %h, <4 x double> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x float>* %h, i64 1
+ %hv = bitcast <4 x float>* %h1 to i8*
+ call void @llvm.ppc.qpx.qvstfs(<4 x double> %d, i8* %hv)
+
+ %v0 = load <4 x float>* %h, align 8
+ ret <4 x float> %v0
+
+; CHECK-LABEL: @test2
+; CHECK: @llvm.ppc.qpx.qvstfs
+; CHECK: ret <4 x float>
+}
+
+define <4 x float> @test2a(<4 x float>* align 16 %h, <4 x double> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x float>* %h, i64 1
+ %hv = bitcast <4 x float>* %h1 to i8*
+ call void @llvm.ppc.qpx.qvstfs(<4 x double> %d, i8* %hv)
+
+ %v0 = load <4 x float>* %h, align 8
+ ret <4 x float> %v0
+
+; CHECK-LABEL: @test2
+; CHECK-NOT: @llvm.ppc.qpx.qvstfs
+; CHECK: ret <4 x float>
+}
+
+declare <4 x double> @llvm.ppc.qpx.qvlfd(i8*) #1
+
+define <4 x double> @test1l(<4 x double>* %h) #0 {
+entry:
+ %h1 = getelementptr <4 x double>* %h, i64 1
+ %hv = bitcast <4 x double>* %h1 to i8*
+ %vl = call <4 x double> @llvm.ppc.qpx.qvlfd(i8* %hv)
+
+; CHECK-LABEL: @test1l
+; CHECK: @llvm.ppc.qpx.qvlfd
+; CHECK: ret <4 x double>
+
+ %v0 = load <4 x double>* %h, align 8
+ %a = fadd <4 x double> %v0, %vl
+ ret <4 x double> %a
+}
+
+define <4 x double> @test1ln(<4 x double>* align 16 %h) #0 {
+entry:
+ %h1 = getelementptr <4 x double>* %h, i64 1
+ %hv = bitcast <4 x double>* %h1 to i8*
+ %vl = call <4 x double> @llvm.ppc.qpx.qvlfd(i8* %hv)
+
+; CHECK-LABEL: @test1ln
+; CHECK: @llvm.ppc.qpx.qvlfd
+; CHECK: ret <4 x double>
+
+ %v0 = load <4 x double>* %h, align 8
+ %a = fadd <4 x double> %v0, %vl
+ ret <4 x double> %a
+}
+
+define <4 x double> @test1la(<4 x double>* align 32 %h) #0 {
+entry:
+ %h1 = getelementptr <4 x double>* %h, i64 1
+ %hv = bitcast <4 x double>* %h1 to i8*
+ %vl = call <4 x double> @llvm.ppc.qpx.qvlfd(i8* %hv)
+
+; CHECK-LABEL: @test1la
+; CHECK-NOT: @llvm.ppc.qpx.qvlfd
+; CHECK: ret <4 x double>
+
+ %v0 = load <4 x double>* %h, align 8
+ %a = fadd <4 x double> %v0, %vl
+ ret <4 x double> %a
+}
+
+declare void @llvm.ppc.qpx.qvstfd(<4 x double>, i8*) #0
+
+define <4 x double> @test2l(<4 x double>* %h, <4 x double> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x double>* %h, i64 1
+ %hv = bitcast <4 x double>* %h1 to i8*
+ call void @llvm.ppc.qpx.qvstfd(<4 x double> %d, i8* %hv)
+
+ %v0 = load <4 x double>* %h, align 8
+ ret <4 x double> %v0
+
+; CHECK-LABEL: @test2l
+; CHECK: @llvm.ppc.qpx.qvstfd
+; CHECK: ret <4 x double>
+}
+
+define <4 x double> @test2ln(<4 x double>* align 16 %h, <4 x double> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x double>* %h, i64 1
+ %hv = bitcast <4 x double>* %h1 to i8*
+ call void @llvm.ppc.qpx.qvstfd(<4 x double> %d, i8* %hv)
+
+ %v0 = load <4 x double>* %h, align 8
+ ret <4 x double> %v0
+
+; CHECK-LABEL: @test2ln
+; CHECK: @llvm.ppc.qpx.qvstfd
+; CHECK: ret <4 x double>
+}
+
+define <4 x double> @test2la(<4 x double>* align 32 %h, <4 x double> %d) #0 {
+entry:
+ %h1 = getelementptr <4 x double>* %h, i64 1
+ %hv = bitcast <4 x double>* %h1 to i8*
+ call void @llvm.ppc.qpx.qvstfd(<4 x double> %d, i8* %hv)
+
+ %v0 = load <4 x double>* %h, align 8
+ ret <4 x double> %v0
+
+; CHECK-LABEL: @test2l
+; CHECK-NOT: @llvm.ppc.qpx.qvstfd
+; CHECK: ret <4 x double>
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readonly }
+
diff --git a/test/Transforms/InstCombine/and-compare.ll b/test/Transforms/InstCombine/and-compare.ll
index c30a245..037641b 100644
--- a/test/Transforms/InstCombine/and-compare.ll
+++ b/test/Transforms/InstCombine/and-compare.ll
@@ -1,11 +1,15 @@
; RUN: opt < %s -instcombine -S | \
-; RUN: grep and | count 1
+; RUN: FileCheck %s
; Should be optimized to one and.
define i1 @test1(i32 %a, i32 %b) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: %1 = xor i32 %a, %b
+; CHECK-NEXT: %2 = and i32 %1, 65280
+; CHECK-NEXT: %tmp = icmp ne i32 %2, 0
+; CHECK-NEXT: ret i1 %tmp
%tmp1 = and i32 %a, 65280 ; <i32> [#uses=1]
%tmp3 = and i32 %b, 65280 ; <i32> [#uses=1]
%tmp = icmp ne i32 %tmp1, %tmp3 ; <i1> [#uses=1]
ret i1 %tmp
}
-
diff --git a/test/Transforms/InstCombine/and-xor-merge.ll b/test/Transforms/InstCombine/and-xor-merge.ll
index e432a9a..b9a6a53 100644
--- a/test/Transforms/InstCombine/and-xor-merge.ll
+++ b/test/Transforms/InstCombine/and-xor-merge.ll
@@ -1,8 +1,11 @@
-; RUN: opt < %s -instcombine -S | grep and | count 1
-; RUN: opt < %s -instcombine -S | grep xor | count 2
+; RUN: opt < %s -instcombine -S | FileCheck %s
; (x&z) ^ (y&z) -> (x^y)&z
define i32 @test1(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: %tmp61 = xor i32 %x, %y
+; CHECK-NEXT: %tmp7 = and i32 %tmp61, %z
+; CHECK-NEXT: ret i32 %tmp7
%tmp3 = and i32 %z, %x
%tmp6 = and i32 %z, %y
%tmp7 = xor i32 %tmp3, %tmp6
@@ -11,9 +14,11 @@ define i32 @test1(i32 %x, i32 %y, i32 %z) {
; (x & y) ^ (x|y) -> x^y
define i32 @test2(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: %tmp7 = xor i32 %y, %x
+; CHECK-NEXT: ret i32 %tmp7
%tmp3 = and i32 %y, %x
%tmp6 = or i32 %y, %x
%tmp7 = xor i32 %tmp3, %tmp6
ret i32 %tmp7
}
-
diff --git a/test/Transforms/InstCombine/apint-call-cast-target.ll b/test/Transforms/InstCombine/apint-call-cast-target.ll
index 4e98f9b..f3a66c3 100644
--- a/test/Transforms/InstCombine/apint-call-cast-target.ll
+++ b/test/Transforms/InstCombine/apint-call-cast-target.ll
@@ -5,15 +5,18 @@ target triple = "i686-pc-linux-gnu"
define i32 @main() {
; CHECK-LABEL: @main(
-; CHECK: call i32 bitcast
+; CHECK: %[[call:.*]] = call i7* @ctime(i999* null)
+; CHECK: %[[cast:.*]] = ptrtoint i7* %[[call]] to i32
+; CHECK: ret i32 %[[cast]]
entry:
%tmp = call i32 bitcast (i7* (i999*)* @ctime to i32 (i99*)*)( i99* null )
ret i32 %tmp
}
define i7* @ctime(i999*) {
-; CHECK-LABEL: @ctime(
-; CHECK: call i7* bitcast
+; CHECK-LABEL: define i7* @ctime(
+; CHECK: %[[call:.*]] = call i32 @main()
+; CHECK: %[[cast:.*]] = inttoptr i32 %[[call]] to i7*
entry:
%tmp = call i7* bitcast (i32 ()* @main to i7* ()*)( )
ret i7* %tmp
diff --git a/test/Transforms/InstCombine/bitcast-alias-function.ll b/test/Transforms/InstCombine/bitcast-alias-function.ll
index bc36b25..cfec092 100644
--- a/test/Transforms/InstCombine/bitcast-alias-function.ll
+++ b/test/Transforms/InstCombine/bitcast-alias-function.ll
@@ -94,7 +94,8 @@ entry:
; CHECK: load i32*
; CHECK-NOT: fptoui
; CHECK-NOT: uitofp
-; CHECK: bitcast i32 %call to float
+; CHECK: bitcast float* %dest to i32*
+; CHECK: store i32
%tmp = load float* %source, align 8
%call = call float @alias_i32_to_f32(float %tmp) nounwind
store float %call, float* %dest, align 8
@@ -109,7 +110,8 @@ entry:
; CHECK: load <2 x i32>*
; CHECK-NOT: fptoui
; CHECK-NOT: uitofp
-; CHECK: bitcast <2 x i32> %call to <2 x float>
+; CHECK: bitcast <2 x float>* %dest to <2 x i32>*
+; CHECK: store <2 x i32>
%tmp = load <2 x float>* %source, align 8
%call = call <2 x float> @alias_v2i32_to_v2f32(<2 x float> %tmp) nounwind
store <2 x float> %call, <2 x float>* %dest, align 8
@@ -123,7 +125,8 @@ entry:
; CHECK: bitcast <2 x float>* %source to i64*
; CHECK: load i64*
; CHECK: %call = call i64 @func_i64
-; CHECK: bitcast i64 %call to <2 x float>
+; CHECK: bitcast <2 x float>* %dest to i64*
+; CHECK: store i64
%tmp = load <2 x float>* %source, align 8
%call = call <2 x float> @alias_v2f32_to_i64(<2 x float> %tmp) nounwind
store <2 x float> %call, <2 x float>* %dest, align 8
@@ -136,7 +139,8 @@ entry:
; CHECK: bitcast i64* %source to <2 x float>*
; CHECK: load <2 x float>*
; CHECK: call <2 x float> @func_v2f32
-; CHECK: bitcast <2 x float> %call to i64
+; CHECK: bitcast i64* %dest to <2 x float>*
+; CHECK: store <2 x float>
%tmp = load i64* %source, align 8
%call = call i64 @alias_i64_to_v2f32(i64 %tmp) nounwind
store i64 %call, i64* %dest, align 8
@@ -149,7 +153,8 @@ entry:
; CHECK: bitcast <2 x i64*>* %source to <2 x i32*>*
; CHECK: load <2 x i32*>*
; CHECK: call <2 x i32*> @func_v2i32p
-; CHECK: bitcast <2 x i32*> %call to <2 x i64*>
+; CHECK: bitcast <2 x i64*>* %dest to <2 x i32*>*
+; CHECK: store <2 x i32*>
%tmp = load <2 x i64*>* %source, align 8
%call = call <2 x i64*> @alias_v2i32p_to_v2i64p(<2 x i64*> %tmp) nounwind
store <2 x i64*> %call, <2 x i64*>* %dest, align 8
diff --git a/test/Transforms/InstCombine/bitcast-store.ll b/test/Transforms/InstCombine/bitcast-store.ll
index e46b5c8..ea4d680 100644
--- a/test/Transforms/InstCombine/bitcast-store.ll
+++ b/test/Transforms/InstCombine/bitcast-store.ll
@@ -10,11 +10,11 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
@G = external constant [5 x i8*]
; CHECK-LABEL: @foo
-; CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 16, !tag !0
-define void @foo(%struct.A* %a) nounwind {
+; CHECK: store i32 %x, i32* %{{.*}}, align 16, !noalias !0
+define void @foo(i32 %x, float* %p) nounwind {
entry:
- %0 = bitcast %struct.A* %a to i8***
- store i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2), i8*** %0, align 16, !tag !0
+ %x.cast = bitcast i32 %x to float
+ store float %x.cast, float* %p, align 16, !noalias !0
ret void
}
@@ -32,4 +32,4 @@ entry:
ret void
}
-!0 = metadata !{metadata !"hello"}
+!0 = !{!0}
diff --git a/test/Transforms/InstCombine/bswap-fold.ll b/test/Transforms/InstCombine/bswap-fold.ll
index 442ce58..63b0775 100644
--- a/test/Transforms/InstCombine/bswap-fold.ll
+++ b/test/Transforms/InstCombine/bswap-fold.ll
@@ -1,63 +1,79 @@
-; RUN: opt < %s -instcombine -S | not grep call.*bswap
+; RUN: opt < %s -instcombine -S | FileCheck %s
define i1 @test1(i16 %tmp2) {
+; CHECK-LABEL: @test1
+; CHECK-NEXT: %tmp = icmp eq i16 %tmp2, 256
+; CHECK-NEXT: ret i1 %tmp
%tmp10 = call i16 @llvm.bswap.i16( i16 %tmp2 )
%tmp = icmp eq i16 %tmp10, 1
ret i1 %tmp
}
define i1 @test2(i32 %tmp) {
+; CHECK-LABEL: @test2
+; CHECK-NEXT: %tmp.upgrd.1 = icmp eq i32 %tmp, 16777216
+; CHECK-NEXT: ret i1 %tmp.upgrd.1
%tmp34 = tail call i32 @llvm.bswap.i32( i32 %tmp )
%tmp.upgrd.1 = icmp eq i32 %tmp34, 1
ret i1 %tmp.upgrd.1
}
-declare i32 @llvm.bswap.i32(i32)
-
define i1 @test3(i64 %tmp) {
+; CHECK-LABEL: @test3
+; CHECK-NEXT: %tmp.upgrd.2 = icmp eq i64 %tmp, 72057594037927936
+; CHECK-NEXT: ret i1 %tmp.upgrd.2
%tmp34 = tail call i64 @llvm.bswap.i64( i64 %tmp )
%tmp.upgrd.2 = icmp eq i64 %tmp34, 1
ret i1 %tmp.upgrd.2
}
-declare i64 @llvm.bswap.i64(i64)
-
-declare i16 @llvm.bswap.i16(i16)
-
; rdar://5992453
; A & 255
define i32 @test4(i32 %a) nounwind {
-entry:
- %tmp2 = tail call i32 @llvm.bswap.i32( i32 %a )
+; CHECK-LABEL: @test4
+; CHECK-NEXT: %tmp2 = and i32 %a, 255
+; CHECK-NEXT: ret i32 %tmp2
+ %tmp2 = tail call i32 @llvm.bswap.i32( i32 %a )
%tmp4 = lshr i32 %tmp2, 24
ret i32 %tmp4
}
; A
-define i32 @test5(i32 %a) nounwind {
-entry:
+define i32 @test5(i32 %a) nounwind {
+; CHECK-LABEL: @test5
+; CHECK-NEXT: ret i32 %a
%tmp2 = tail call i32 @llvm.bswap.i32( i32 %a )
%tmp4 = tail call i32 @llvm.bswap.i32( i32 %tmp2 )
ret i32 %tmp4
}
; a >> 24
-define i32 @test6(i32 %a) nounwind {
-entry:
- %tmp2 = tail call i32 @llvm.bswap.i32( i32 %a )
+define i32 @test6(i32 %a) nounwind {
+; CHECK-LABEL: @test6
+; CHECK-NEXT: %tmp2 = lshr i32 %a, 24
+; CHECK-NEXT ret i32 %tmp4
+ %tmp2 = tail call i32 @llvm.bswap.i32( i32 %a )
%tmp4 = and i32 %tmp2, 255
ret i32 %tmp4
}
; PR5284
define i16 @test7(i32 %A) {
- %B = tail call i32 @llvm.bswap.i32(i32 %A) nounwind
+; CHECK-LABEL: @test7
+; CHECK-NEXT: %1 = lshr i32 %A, 16
+; CHECK-NEXT: %D = trunc i32 %1 to i16
+; CHECK-NEXT ret i16 %D
+ %B = tail call i32 @llvm.bswap.i32(i32 %A) nounwind
%C = trunc i32 %B to i16
%D = tail call i16 @llvm.bswap.i16(i16 %C) nounwind
ret i16 %D
}
define i16 @test8(i64 %A) {
+; CHECK-LABEL: @test8
+; CHECK-NEXT: %1 = lshr i64 %A, 48
+; CHECK-NEXT: %D = trunc i64 %1 to i16
+; CHECK-NEXT ret i16 %D
%B = tail call i64 @llvm.bswap.i64(i64 %A) nounwind
%C = trunc i64 %B to i16
%D = tail call i16 @llvm.bswap.i16(i16 %C) nounwind
@@ -66,6 +82,144 @@ define i16 @test8(i64 %A) {
; Misc: Fold bswap(undef) to undef.
define i64 @foo() {
+; CHECK-LABEL: @foo
+; CHECK-NEXT: ret i64 undef
%a = call i64 @llvm.bswap.i64(i64 undef)
ret i64 %a
}
+
+; PR15782
+; Fold: OP( BSWAP(x), BSWAP(y) ) -> BSWAP( OP(x, y) )
+; Fold: OP( BSWAP(x), CONSTANT ) -> BSWAP( OP(x, BSWAP(CONSTANT) ) )
+define i16 @bs_and16i(i16 %a, i16 %b) #0 {
+; CHECK-LABEL: @bs_and16i
+; CHECK-NEXT: %1 = and i16 %a, 4391
+; CHECK-NEXT: %2 = call i16 @llvm.bswap.i16(i16 %1)
+; CHECK-NEXT: ret i16 %2
+ %1 = tail call i16 @llvm.bswap.i16(i16 %a)
+ %2 = and i16 %1, 10001
+ ret i16 %2
+}
+
+define i16 @bs_and16(i16 %a, i16 %b) #0 {
+; CHECK-LABEL: @bs_and16
+; CHECK-NEXT: %1 = and i16 %a, %b
+; CHECK-NEXT: %2 = call i16 @llvm.bswap.i16(i16 %1)
+; CHECK-NEXT: ret i16 %2
+ %tmp1 = tail call i16 @llvm.bswap.i16(i16 %a)
+ %tmp2 = tail call i16 @llvm.bswap.i16(i16 %b)
+ %tmp3 = and i16 %tmp1, %tmp2
+ ret i16 %tmp3
+}
+
+define i16 @bs_or16(i16 %a, i16 %b) #0 {
+; CHECK-LABEL: @bs_or16
+; CHECK-NEXT: %1 = or i16 %a, %b
+; CHECK-NEXT: %2 = call i16 @llvm.bswap.i16(i16 %1)
+; CHECK-NEXT: ret i16 %2
+ %tmp1 = tail call i16 @llvm.bswap.i16(i16 %a)
+ %tmp2 = tail call i16 @llvm.bswap.i16(i16 %b)
+ %tmp3 = or i16 %tmp1, %tmp2
+ ret i16 %tmp3
+}
+
+define i16 @bs_xor16(i16 %a, i16 %b) #0 {
+; CHECK-LABEL: @bs_xor16
+; CHECK-NEXT: %1 = xor i16 %a, %b
+; CHECK-NEXT: %2 = call i16 @llvm.bswap.i16(i16 %1)
+; CHECK-NEXT: ret i16 %2
+ %tmp1 = tail call i16 @llvm.bswap.i16(i16 %a)
+ %tmp2 = tail call i16 @llvm.bswap.i16(i16 %b)
+ %tmp3 = xor i16 %tmp1, %tmp2
+ ret i16 %tmp3
+}
+
+define i32 @bs_and32i(i32 %a, i32 %b) #0 {
+; CHECK-LABEL: @bs_and32i
+; CHECK-NEXT: %1 = and i32 %a, -1585053440
+; CHECK-NEXT: %2 = call i32 @llvm.bswap.i32(i32 %1)
+; CHECK-NEXT: ret i32 %2
+ %tmp1 = tail call i32 @llvm.bswap.i32(i32 %a)
+ %tmp2 = and i32 %tmp1, 100001
+ ret i32 %tmp2
+}
+
+define i32 @bs_and32(i32 %a, i32 %b) #0 {
+; CHECK-LABEL: @bs_and32
+; CHECK-NEXT: %1 = and i32 %a, %b
+; CHECK-NEXT: %2 = call i32 @llvm.bswap.i32(i32 %1)
+; CHECK-NEXT: ret i32 %2
+ %tmp1 = tail call i32 @llvm.bswap.i32(i32 %a)
+ %tmp2 = tail call i32 @llvm.bswap.i32(i32 %b)
+ %tmp3 = and i32 %tmp1, %tmp2
+ ret i32 %tmp3
+}
+
+define i32 @bs_or32(i32 %a, i32 %b) #0 {
+; CHECK-LABEL: @bs_or32
+; CHECK-NEXT: %1 = or i32 %a, %b
+; CHECK-NEXT: %2 = call i32 @llvm.bswap.i32(i32 %1)
+; CHECK-NEXT: ret i32 %2
+ %tmp1 = tail call i32 @llvm.bswap.i32(i32 %a)
+ %tmp2 = tail call i32 @llvm.bswap.i32(i32 %b)
+ %tmp3 = or i32 %tmp1, %tmp2
+ ret i32 %tmp3
+}
+
+define i32 @bs_xor32(i32 %a, i32 %b) #0 {
+; CHECK-LABEL: @bs_xor32
+; CHECK-NEXT: %1 = xor i32 %a, %b
+; CHECK-NEXT: %2 = call i32 @llvm.bswap.i32(i32 %1)
+; CHECK-NEXT: ret i32 %2
+ %tmp1 = tail call i32 @llvm.bswap.i32(i32 %a)
+ %tmp2 = tail call i32 @llvm.bswap.i32(i32 %b)
+ %tmp3 = xor i32 %tmp1, %tmp2
+ ret i32 %tmp3
+}
+
+define i64 @bs_and64i(i64 %a, i64 %b) #0 {
+; CHECK-LABEL: @bs_and64i
+; CHECK-NEXT: %1 = and i64 %a, 129085117527228416
+; CHECK-NEXT: %2 = call i64 @llvm.bswap.i64(i64 %1)
+; CHECK-NEXT: ret i64 %2
+ %tmp1 = tail call i64 @llvm.bswap.i64(i64 %a)
+ %tmp2 = and i64 %tmp1, 1000000001
+ ret i64 %tmp2
+}
+
+define i64 @bs_and64(i64 %a, i64 %b) #0 {
+; CHECK-LABEL: @bs_and64
+; CHECK-NEXT: %1 = and i64 %a, %b
+; CHECK-NEXT: %2 = call i64 @llvm.bswap.i64(i64 %1)
+; CHECK-NEXT: ret i64 %2
+ %tmp1 = tail call i64 @llvm.bswap.i64(i64 %a)
+ %tmp2 = tail call i64 @llvm.bswap.i64(i64 %b)
+ %tmp3 = and i64 %tmp1, %tmp2
+ ret i64 %tmp3
+}
+
+define i64 @bs_or64(i64 %a, i64 %b) #0 {
+; CHECK-LABEL: @bs_or64
+; CHECK-NEXT: %1 = or i64 %a, %b
+; CHECK-NEXT: %2 = call i64 @llvm.bswap.i64(i64 %1)
+; CHECK-NEXT: ret i64 %2
+ %tmp1 = tail call i64 @llvm.bswap.i64(i64 %a)
+ %tmp2 = tail call i64 @llvm.bswap.i64(i64 %b)
+ %tmp3 = or i64 %tmp1, %tmp2
+ ret i64 %tmp3
+}
+
+define i64 @bs_xor64(i64 %a, i64 %b) #0 {
+; CHECK-LABEL: @bs_xor64
+; CHECK-NEXT: %1 = xor i64 %a, %b
+; CHECK-NEXT: %2 = call i64 @llvm.bswap.i64(i64 %1)
+; CHECK-NEXT: ret i64 %2
+ %tmp1 = tail call i64 @llvm.bswap.i64(i64 %a)
+ %tmp2 = tail call i64 @llvm.bswap.i64(i64 %b)
+ %tmp3 = xor i64 %tmp1, %tmp2
+ ret i64 %tmp3
+}
+
+declare i16 @llvm.bswap.i16(i16)
+declare i32 @llvm.bswap.i32(i32)
+declare i64 @llvm.bswap.i64(i64)
diff --git a/test/Transforms/InstCombine/call-cast-target.ll b/test/Transforms/InstCombine/call-cast-target.ll
index 1af3317..4a5c949 100644
--- a/test/Transforms/InstCombine/call-cast-target.ll
+++ b/test/Transforms/InstCombine/call-cast-target.ll
@@ -5,7 +5,9 @@ target triple = "i686-pc-linux-gnu"
define i32 @main() {
; CHECK-LABEL: @main
-; CHECK: call i32 bitcast
+; CHECK: %[[call:.*]] = call i8* @ctime(i32* null)
+; CHECK: %[[cast:.*]] = ptrtoint i8* %[[call]] to i32
+; CHECK: ret i32 %[[cast]]
entry:
%tmp = call i32 bitcast (i8* (i32*)* @ctime to i32 (i32*)*)( i32* null ) ; <i32> [#uses=1]
ret i32 %tmp
@@ -25,3 +27,48 @@ entry:
%0 = call { i8 } bitcast ({ i8 } (i32*)* @foo to { i8 } (i16*)*)(i16* null)
ret void
}
+
+declare i32 @fn1(i32)
+
+define i32 @test1(i32* %a) {
+; CHECK-LABEL: @test1
+; CHECK: %[[cast:.*]] = ptrtoint i32* %a to i32
+; CHECK-NEXT: %[[call:.*]] = tail call i32 @fn1(i32 %[[cast]])
+; CHECK-NEXT: ret i32 %[[call]]
+entry:
+ %call = tail call i32 bitcast (i32 (i32)* @fn1 to i32 (i32*)*)(i32* %a)
+ ret i32 %call
+}
+
+declare i32 @fn2(i16)
+
+define i32 @test2(i32* %a) {
+; CHECK-LABEL: @test2
+; CHECK: %[[call:.*]] = tail call i32 bitcast (i32 (i16)* @fn2 to i32 (i32*)*)(i32* %a)
+; CHECK-NEXT: ret i32 %[[call]]
+entry:
+ %call = tail call i32 bitcast (i32 (i16)* @fn2 to i32 (i32*)*)(i32* %a)
+ ret i32 %call
+}
+
+declare i32 @fn3(i64)
+
+define i32 @test3(i32* %a) {
+; CHECK-LABEL: @test3
+; CHECK: %[[call:.*]] = tail call i32 bitcast (i32 (i64)* @fn3 to i32 (i32*)*)(i32* %a)
+; CHECK-NEXT: ret i32 %[[call]]
+entry:
+ %call = tail call i32 bitcast (i32 (i64)* @fn3 to i32 (i32*)*)(i32* %a)
+ ret i32 %call
+}
+
+declare i32 @fn4(i32) "thunk"
+
+define i32 @test4(i32* %a) {
+; CHECK-LABEL: @test4
+; CHECK: %[[call:.*]] = tail call i32 bitcast (i32 (i32)* @fn4 to i32 (i32*)*)(i32* %a)
+; CHECK-NEXT: ret i32 %[[call]]
+entry:
+ %call = tail call i32 bitcast (i32 (i32)* @fn4 to i32 (i32*)*)(i32* %a)
+ ret i32 %call
+}
diff --git a/test/Transforms/InstCombine/canonicalize_branch.ll b/test/Transforms/InstCombine/canonicalize_branch.ll
index b62b143..29fd51a 100644
--- a/test/Transforms/InstCombine/canonicalize_branch.ll
+++ b/test/Transforms/InstCombine/canonicalize_branch.ll
@@ -57,10 +57,10 @@ F:
ret i32 123
}
-!0 = metadata !{metadata !"branch_weights", i32 1, i32 2}
-!1 = metadata !{metadata !"branch_weights", i32 3, i32 4}
-!2 = metadata !{metadata !"branch_weights", i32 5, i32 6}
-!3 = metadata !{metadata !"branch_weights", i32 7, i32 8}
+!0 = !{!"branch_weights", i32 1, i32 2}
+!1 = !{!"branch_weights", i32 3, i32 4}
+!2 = !{!"branch_weights", i32 5, i32 6}
+!3 = !{!"branch_weights", i32 7, i32 8}
; Base case shouldn't change.
; CHECK: !0 = {{.*}} i32 1, i32 2}
; Ensure that the branch metadata is reversed to match the reversals above.
diff --git a/test/Transforms/InstCombine/cast-int-fcmp-eq-0.ll b/test/Transforms/InstCombine/cast-int-fcmp-eq-0.ll
new file mode 100644
index 0000000..551d0ef
--- /dev/null
+++ b/test/Transforms/InstCombine/cast-int-fcmp-eq-0.ll
@@ -0,0 +1,454 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_0_uitofp(
+; CHECK-NEXT: icmp eq i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_n0_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+define i1 @i32_cast_cmp_oeq_int_n0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_0_sitofp(
+; CHECK-NEXT: icmp eq i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_n0_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+define i1 @i32_cast_cmp_oeq_int_n0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_one_int_0_uitofp(
+; CHECK-NEXT: icmp ne i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_one_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp one float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_one_int_n0_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp one
+define i1 @i32_cast_cmp_one_int_n0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp one float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_one_int_0_sitofp(
+; CHECK-NEXT: icmp ne i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_one_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp one float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_one_int_n0_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp one
+define i1 @i32_cast_cmp_one_int_n0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp one float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ueq_int_0_uitofp(
+; CHECK-NEXT: icmp eq i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_ueq_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp ueq float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ueq_int_n0_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp ueq
+define i1 @i32_cast_cmp_ueq_int_n0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp ueq float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ueq_int_0_sitofp(
+; CHECK-NEXT: icmp eq i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_ueq_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp ueq float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ueq_int_n0_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp ueq
+define i1 @i32_cast_cmp_ueq_int_n0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp ueq float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_une_int_0_uitofp(
+; CHECK-NEXT: icmp ne i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_une_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp une float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_une_int_n0_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp une
+define i1 @i32_cast_cmp_une_int_n0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp une float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_une_int_0_sitofp(
+; CHECK-NEXT: icmp ne i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_une_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp une float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_une_int_n0_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp une
+define i1 @i32_cast_cmp_une_int_n0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp une float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ogt_int_0_uitofp(
+; CHECK: icmp ne i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_ogt_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp ogt float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ogt_int_n0_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp ogt
+define i1 @i32_cast_cmp_ogt_int_n0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp ogt float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ogt_int_0_sitofp(
+; CHECK: icmp sgt i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_ogt_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp ogt float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ogt_int_n0_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp ogt
+define i1 @i32_cast_cmp_ogt_int_n0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp ogt float %f, -0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ole_int_0_uitofp(
+; CHECK: icmp eq i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_ole_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp ole float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ole_int_0_sitofp(
+; CHECK: icmp slt i32 %i, 1
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_ole_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp ole float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_olt_int_0_uitofp(
+; CHECK: ret i1 false
+define i1 @i32_cast_cmp_olt_int_0_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp olt float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_olt_int_0_sitofp(
+; CHECK: icmp slt i32 %i, 0
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_olt_int_0_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp olt float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i64_cast_cmp_oeq_int_0_uitofp(
+; CHECK-NEXT: icmp eq i64 %i, 0
+; CHECK-NEXT: ret
+define i1 @i64_cast_cmp_oeq_int_0_uitofp(i64 %i) {
+ %f = uitofp i64 %i to float
+ %cmp = fcmp oeq float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i64_cast_cmp_oeq_int_0_sitofp(
+; CHECK-NEXT: icmp eq i64 %i, 0
+; CHECK-NEXT: ret
+define i1 @i64_cast_cmp_oeq_int_0_sitofp(i64 %i) {
+ %f = sitofp i64 %i to float
+ %cmp = fcmp oeq float %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i64_cast_cmp_oeq_int_0_uitofp_half(
+; CHECK-NEXT: icmp eq i64 %i, 0
+; CHECK-NEXT: ret
+define i1 @i64_cast_cmp_oeq_int_0_uitofp_half(i64 %i) {
+ %f = uitofp i64 %i to half
+ %cmp = fcmp oeq half %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i64_cast_cmp_oeq_int_0_sitofp_half(
+; CHECK-NEXT: icmp eq i64 %i, 0
+; CHECK-NEXT: ret
+define i1 @i64_cast_cmp_oeq_int_0_sitofp_half(i64 %i) {
+ %f = sitofp i64 %i to half
+ %cmp = fcmp oeq half %f, 0.0
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_0_uitofp_ppcf128(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_0_uitofp_ppcf128(i32 %i) {
+ %f = uitofp i32 %i to ppc_fp128
+ %cmp = fcmp oeq ppc_fp128 %f, 0xM00000000000000000000000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i24max_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+
+; XCHECK: icmp eq i32 %i, 16777215
+; XCHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i24max_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x416FFFFFE0000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i24max_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+
+; XCHECK: icmp eq i32 %i, 16777215
+; XCHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i24max_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x416FFFFFE0000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i24maxp1_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+
+; XCHECK: icmp eq i32 %i, 16777216
+; XCHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i24maxp1_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x4170000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i24maxp1_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+
+; XCHECK: icmp eq i32 %i, 16777216
+; XCHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i24maxp1_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x4170000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i32umax_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i32umax_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x41F0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i32umax_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i32umax_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x41F0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i32imin_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i32imin_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0xC1E0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i32imin_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i32imin_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0xC1E0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i32imax_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i32imax_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x41E0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_i32imax_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_i32imax_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0x41E0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_negi32umax_uitofp(
+; CHECK: uitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_negi32umax_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0xC1F0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_int_negi32umax_sitofp(
+; CHECK: sitofp
+; CHECK: fcmp oeq
+; CHECK-NEXT: ret
+define i1 @i32_cast_cmp_oeq_int_negi32umax_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0xC1F0000000000000
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_half_uitofp(
+; CHECK: ret i1 false
+define i1 @i32_cast_cmp_oeq_half_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_oeq_half_sitofp(
+; CHECK: ret i1 false
+define i1 @i32_cast_cmp_oeq_half_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp oeq float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_one_half_uitofp(
+; CHECK: ret i1 true
+define i1 @i32_cast_cmp_one_half_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp one float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_one_half_sitofp(
+; CHECK: ret i1 true
+define i1 @i32_cast_cmp_one_half_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp one float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ueq_half_uitofp(
+; CHECK: ret i1 false
+define i1 @i32_cast_cmp_ueq_half_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp ueq float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_ueq_half_sitofp(
+; CHECK: ret i1 false
+define i1 @i32_cast_cmp_ueq_half_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp ueq float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_une_half_uitofp(
+; CHECK: ret i1 true
+define i1 @i32_cast_cmp_une_half_uitofp(i32 %i) {
+ %f = uitofp i32 %i to float
+ %cmp = fcmp une float %f, 0.5
+ ret i1 %cmp
+}
+
+; CHECK-LABEL: @i32_cast_cmp_une_half_sitofp(
+; CHECK: ret i1 true
+define i1 @i32_cast_cmp_une_half_sitofp(i32 %i) {
+ %f = sitofp i32 %i to float
+ %cmp = fcmp une float %f, 0.5
+ ret i1 %cmp
+}
diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll
index 578b16d..aac7a53 100644
--- a/test/Transforms/InstCombine/cast.ll
+++ b/test/Transforms/InstCombine/cast.ll
@@ -99,6 +99,26 @@ define void @test11(i32* %P) {
; CHECK: ret void
}
+declare i32 @__gxx_personality_v0(...)
+define void @test_invoke_vararg_cast(i32* %a, i32* %b) {
+entry:
+ %0 = bitcast i32* %b to i8*
+ %1 = bitcast i32* %a to i64*
+ invoke void (i32, ...)* @varargs(i32 1, i8* %0, i64* %1)
+ to label %invoke.cont unwind label %lpad
+
+invoke.cont: ; preds = %entry
+ ret void
+
+lpad: ; preds = %entry
+ %2 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ ret void
+; CHECK-LABEL: test_invoke_vararg_cast
+; CHECK-LABEL: entry:
+; CHECK: invoke void (i32, ...)* @varargs(i32 1, i32* %b, i32* %a)
+}
+
define i8* @test13(i64 %A) {
%c = getelementptr [0 x i8]* bitcast ([32832 x i8]* @inbuf to [0 x i8]*), i64 0, i64 %A ; <i8*> [#uses=1]
ret i8* %c
@@ -199,15 +219,6 @@ define i1 @test24(i1 %C) {
; CHECK: ret i1 true
}
-define void @test25(i32** %P) {
- %c = bitcast i32** %P to float** ; <float**> [#uses=1]
- ;; Fold cast into null
- store float* null, float** %c
- ret void
-; CHECK: store i32* null, i32** %P
-; CHECK: ret void
-}
-
define i32 @test26(float %F) {
;; no need to cast from float->double.
%c = fpext float %F to double ; <double> [#uses=1]
diff --git a/test/Transforms/InstCombine/cast_ptr.ll b/test/Transforms/InstCombine/cast_ptr.ll
index 23006a8..cc7a2bf 100644
--- a/test/Transforms/InstCombine/cast_ptr.ll
+++ b/test/Transforms/InstCombine/cast_ptr.ll
@@ -3,6 +3,8 @@
target datalayout = "p:32:32-p1:32:32-p2:16:16"
+@global = global i8 0
+
; This shouldn't convert to getelementptr because the relationship
; between the arithmetic and the layout of allocated memory is
; entirely unknown.
@@ -47,10 +49,29 @@ define i1 @test2_as2_larger(i8 addrspace(2)* %a, i8 addrspace(2)* %b) {
ret i1 %r
}
+; These casts should not be folded away.
+; CHECK-LABEL: @test2_diff_as
+; CHECK: icmp sge i32 %i0, %i1
+define i1 @test2_diff_as(i8* %p, i8 addrspace(1)* %q) {
+ %i0 = ptrtoint i8* %p to i32
+ %i1 = ptrtoint i8 addrspace(1)* %q to i32
+ %r0 = icmp sge i32 %i0, %i1
+ ret i1 %r0
+}
+
+; These casts should not be folded away.
+; CHECK-LABEL: @test2_diff_as_global
+; CHECK: icmp sge i32 %i1
+define i1 @test2_diff_as_global(i8 addrspace(1)* %q) {
+ %i0 = ptrtoint i8* @global to i32
+ %i1 = ptrtoint i8 addrspace(1)* %q to i32
+ %r0 = icmp sge i32 %i1, %i0
+ ret i1 %r0
+}
+
; These casts should also be folded away.
; CHECK-LABEL: @test3(
; CHECK: icmp eq i8* %a, @global
-@global = global i8 0
define i1 @test3(i8* %a) {
%tmpa = ptrtoint i8* %a to i32
%r = icmp eq i32 %tmpa, ptrtoint (i8* @global to i32)
diff --git a/test/Transforms/InstCombine/debug-line.ll b/test/Transforms/InstCombine/debug-line.ll
index 309843f..1946576 100644
--- a/test/Transforms/InstCombine/debug-line.ll
+++ b/test/Transforms/InstCombine/debug-line.ll
@@ -15,14 +15,14 @@ declare i32 @printf(i8*, ...)
!llvm.module.flags = !{!10}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\004\000\001\000\006\000\000\000", metadata !8, metadata !1, metadata !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ]
-!1 = metadata !{metadata !"0x29", metadata !8} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang\001\00\000\00\000", metadata !8, metadata !4, metadata !4, metadata !9, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !8, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{i32 5, i32 2, metadata !6, null}
-!6 = metadata !{metadata !"0xb\004\0012\000", metadata !8, metadata !0} ; [ DW_TAG_lexical_block ]
-!7 = metadata !{i32 6, i32 1, metadata !6, null}
-!8 = metadata !{metadata !"m.c", metadata !"/private/tmp"}
-!9 = metadata !{metadata !0}
-!10 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00\004\000\001\000\006\000\000\000", !8, !1, !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ]
+!1 = !{!"0x29", !8} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang\001\00\000\00\000", !8, !4, !4, !9, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !8, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !MDLocation(line: 5, column: 2, scope: !6)
+!6 = !{!"0xb\004\0012\000", !8, !0} ; [ DW_TAG_lexical_block ]
+!7 = !MDLocation(line: 6, column: 1, scope: !6)
+!8 = !{!"m.c", !"/private/tmp"}
+!9 = !{!0}
+!10 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/InstCombine/debuginfo.ll b/test/Transforms/InstCombine/debuginfo.ll
index a7a491e..ae72f70 100644
--- a/test/Transforms/InstCombine/debuginfo.ll
+++ b/test/Transforms/InstCombine/debuginfo.ll
@@ -14,11 +14,11 @@ entry:
store i8* %__dest, i8** %__dest.addr, align 8
; CHECK-NOT: call void @llvm.dbg.declare
; CHECK: call void @llvm.dbg.value
- call void @llvm.dbg.declare(metadata !{i8** %__dest.addr}, metadata !0, metadata !{}), !dbg !16
+ call void @llvm.dbg.declare(metadata i8** %__dest.addr, metadata !0, metadata !{}), !dbg !16
store i32 %__val, i32* %__val.addr, align 4
- call void @llvm.dbg.declare(metadata !{i32* %__val.addr}, metadata !7, metadata !{}), !dbg !18
+ call void @llvm.dbg.declare(metadata i32* %__val.addr, metadata !7, metadata !{}), !dbg !18
store i64 %__len, i64* %__len.addr, align 8
- call void @llvm.dbg.declare(metadata !{i64* %__len.addr}, metadata !9, metadata !{}), !dbg !20
+ call void @llvm.dbg.declare(metadata i64* %__len.addr, metadata !9, metadata !{}), !dbg !20
%tmp = load i8** %__dest.addr, align 8, !dbg !21
%tmp1 = load i32* %__val.addr, align 4, !dbg !21
%tmp2 = load i64* %__len.addr, align 8, !dbg !21
@@ -31,29 +31,29 @@ entry:
!llvm.dbg.cu = !{!3}
!llvm.module.flags = !{!30}
-!0 = metadata !{metadata !"0x101\00__dest\0016777294\000", metadata !1, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ]
-!1 = metadata !{metadata !"0x2e\00foobar\00foobar\00\0079\001\001\000\006\00256\001\0079", metadata !27, metadata !2, metadata !4, null, i8* (i8*, i32, i64)* @foobar, null, null, metadata !25} ; [ DW_TAG_subprogram ] [line 79] [local] [def] [foobar]
-!2 = metadata !{metadata !"0x29", metadata !27} ; [ DW_TAG_file_type ]
-!3 = metadata !{metadata !"0x11\0012\00clang version 3.0 (trunk 127710)\001\00\000\00\000", metadata !28, metadata !29, metadata !29, metadata !24, null, null} ; [ DW_TAG_compile_unit ]
-!4 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !27, metadata !2, null, metadata !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!5 = metadata !{metadata !6}
-!6 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, metadata !3, null} ; [ DW_TAG_pointer_type ]
-!7 = metadata !{metadata !"0x101\00__val\0033554510\000", metadata !1, metadata !2, metadata !8} ; [ DW_TAG_arg_variable ]
-!8 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !3} ; [ DW_TAG_base_type ]
-!9 = metadata !{metadata !"0x101\00__len\0050331726\000", metadata !1, metadata !2, metadata !10} ; [ DW_TAG_arg_variable ]
-!10 = metadata !{metadata !"0x16\00size_t\0080\000\000\000\000", metadata !27, metadata !3, metadata !11} ; [ DW_TAG_typedef ]
-!11 = metadata !{metadata !"0x16\00__darwin_size_t\0090\000\000\000\000", metadata !27, metadata !3, metadata !12} ; [ DW_TAG_typedef ]
-!12 = metadata !{metadata !"0x24\00long unsigned int\000\0064\0064\000\000\007", null, metadata !3} ; [ DW_TAG_base_type ]
-!16 = metadata !{i32 78, i32 28, metadata !1, null}
-!18 = metadata !{i32 78, i32 40, metadata !1, null}
-!20 = metadata !{i32 78, i32 54, metadata !1, null}
-!21 = metadata !{i32 80, i32 3, metadata !22, null}
-!22 = metadata !{metadata !"0xb\0080\003\007", metadata !27, metadata !23} ; [ DW_TAG_lexical_block ]
-!23 = metadata !{metadata !"0xb\0079\001\006", metadata !27, metadata !1} ; [ DW_TAG_lexical_block ]
-!24 = metadata !{metadata !1}
-!25 = metadata !{metadata !0, metadata !7, metadata !9}
-!26 = metadata !{metadata !"0x29", metadata !28} ; [ DW_TAG_file_type ]
-!27 = metadata !{metadata !"string.h", metadata !"Game"}
-!28 = metadata !{metadata !"bits.c", metadata !"Game"}
-!29 = metadata !{i32 0}
-!30 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x101\00__dest\0016777294\000", !1, !2, !6} ; [ DW_TAG_arg_variable ]
+!1 = !{!"0x2e\00foobar\00foobar\00\0079\001\001\000\006\00256\001\0079", !27, !2, !4, null, i8* (i8*, i32, i64)* @foobar, null, null, !25} ; [ DW_TAG_subprogram ] [line 79] [local] [def] [foobar]
+!2 = !{!"0x29", !27} ; [ DW_TAG_file_type ]
+!3 = !{!"0x11\0012\00clang version 3.0 (trunk 127710)\001\00\000\00\000", !28, !29, !29, !24, null, null} ; [ DW_TAG_compile_unit ]
+!4 = !{!"0x15\00\000\000\000\000\000\000", !27, !2, null, !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!5 = !{!6}
+!6 = !{!"0xf\00\000\0064\0064\000\000", null, !3, null} ; [ DW_TAG_pointer_type ]
+!7 = !{!"0x101\00__val\0033554510\000", !1, !2, !8} ; [ DW_TAG_arg_variable ]
+!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !3} ; [ DW_TAG_base_type ]
+!9 = !{!"0x101\00__len\0050331726\000", !1, !2, !10} ; [ DW_TAG_arg_variable ]
+!10 = !{!"0x16\00size_t\0080\000\000\000\000", !27, !3, !11} ; [ DW_TAG_typedef ]
+!11 = !{!"0x16\00__darwin_size_t\0090\000\000\000\000", !27, !3, !12} ; [ DW_TAG_typedef ]
+!12 = !{!"0x24\00long unsigned int\000\0064\0064\000\000\007", null, !3} ; [ DW_TAG_base_type ]
+!16 = !MDLocation(line: 78, column: 28, scope: !1)
+!18 = !MDLocation(line: 78, column: 40, scope: !1)
+!20 = !MDLocation(line: 78, column: 54, scope: !1)
+!21 = !MDLocation(line: 80, column: 3, scope: !22)
+!22 = !{!"0xb\0080\003\007", !27, !23} ; [ DW_TAG_lexical_block ]
+!23 = !{!"0xb\0079\001\006", !27, !1} ; [ DW_TAG_lexical_block ]
+!24 = !{!1}
+!25 = !{!0, !7, !9}
+!26 = !{!"0x29", !28} ; [ DW_TAG_file_type ]
+!27 = !{!"string.h", !"Game"}
+!28 = !{!"bits.c", !"Game"}
+!29 = !{i32 0}
+!30 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll
index 2841043..e0ff07b 100644
--- a/test/Transforms/InstCombine/div.ll
+++ b/test/Transforms/InstCombine/div.ll
@@ -217,7 +217,7 @@ define i32 @test25(i32 %a) {
%div = sdiv i32 %shl, 2
ret i32 %div
; CHECK-LABEL: @test25(
-; CHECK-NEXT: %div = shl i32 %a, 1
+; CHECK-NEXT: %div = shl nsw i32 %a, 1
; CHECK-NEXT: ret i32 %div
}
@@ -226,7 +226,7 @@ define i32 @test26(i32 %a) {
%div = sdiv i32 %mul, 3
ret i32 %div
; CHECK-LABEL: @test26(
-; CHECK-NEXT: %div = shl i32 %a, 2
+; CHECK-NEXT: %div = shl nsw i32 %a, 2
; CHECK-NEXT: ret i32 %div
}
@@ -286,3 +286,42 @@ define i32 @test32(i32 %a, i32 %b) {
; CHECK-NEXT: %[[div:.*]] = udiv i32 %a, %[[shr]]
; CHECK-NEXT: ret i32
}
+
+define <2 x i64> @test33(<2 x i64> %x) nounwind {
+ %shr = lshr exact <2 x i64> %x, <i64 5, i64 5>
+ %div = udiv exact <2 x i64> %shr, <i64 6, i64 6>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test33(
+; CHECK-NEXT: udiv exact <2 x i64> %x, <i64 192, i64 192>
+; CHECK-NEXT: ret <2 x i64>
+}
+
+define <2 x i64> @test34(<2 x i64> %x) nounwind {
+ %neg = sub nsw <2 x i64> zeroinitializer, %x
+ %div = sdiv exact <2 x i64> %neg, <i64 3, i64 4>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test34(
+; CHECK-NEXT: sdiv exact <2 x i64> %x, <i64 -3, i64 -4>
+; CHECK-NEXT: ret <2 x i64>
+}
+
+define i32 @test35(i32 %A) {
+ %and = and i32 %A, 2147483647
+ %mul = sdiv exact i32 %and, 2147483647
+ ret i32 %mul
+; CHECK-LABEL: @test35(
+; CHECK-NEXT: %[[and:.*]] = and i32 %A, 2147483647
+; CHECK-NEXT: %[[udiv:.*]] = udiv exact i32 %[[and]], 2147483647
+; CHECK-NEXT: ret i32 %[[udiv]]
+}
+
+define i32 @test36(i32 %A) {
+ %and = and i32 %A, 2147483647
+ %shl = shl nsw i32 1, %A
+ %mul = sdiv exact i32 %and, %shl
+ ret i32 %mul
+; CHECK-LABEL: @test36(
+; CHECK-NEXT: %[[and:.*]] = and i32 %A, 2147483647
+; CHECK-NEXT: %[[shr:.*]] = lshr exact i32 %[[and]], %A
+; CHECK-NEXT: ret i32 %[[shr]]
+}
diff --git a/test/Transforms/InstCombine/fast-math.ll b/test/Transforms/InstCombine/fast-math.ll
index b0ec895..c6081c3 100644
--- a/test/Transforms/InstCombine/fast-math.ll
+++ b/test/Transforms/InstCombine/fast-math.ll
@@ -93,7 +93,7 @@ define float @fold9(float %f1, float %f2) {
ret float %t3
; CHECK-LABEL: @fold9(
-; CHECK: fsub fast float 0.000000e+00, %f2
+; CHECK: fsub fast float -0.000000e+00, %f2
}
; Let C3 = C1 + C2. (f1 + C1) + (f2 + C2) => (f1 + f2) + C3 instead of
@@ -322,6 +322,14 @@ define float @fneg1(float %f1, float %f2) {
; CHECK: fmul float %f1, %f2
}
+define float @fneg2(float %x) {
+ %sub = fsub nsz float 0.0, %x
+ ret float %sub
+; CHECK-LABEL: @fneg2(
+; CHECK-NEXT: fsub nsz float -0.000000e+00, %x
+; CHECK-NEXT: ret float
+}
+
; =========================================================================
;
; Testing-cases about div
diff --git a/test/Transforms/InstCombine/fcmp.ll b/test/Transforms/InstCombine/fcmp.ll
index afc6782..ee39d10 100644
--- a/test/Transforms/InstCombine/fcmp.ll
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -1,5 +1,7 @@
; RUN: opt -S -instcombine < %s | FileCheck %s
+declare double @llvm.fabs.f64(double) nounwind readnone
+
define i1 @test1(float %x, float %y) nounwind {
%ext1 = fpext float %x to double
%ext2 = fpext float %y to double
@@ -81,6 +83,16 @@ define i32 @test9(double %a) nounwind {
; CHECK: ret i32 0
}
+define i32 @test9_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp olt double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test9_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: ret i32 0
+}
+
define i32 @test10(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp ole double %call, 0.000000e+00
@@ -91,6 +103,16 @@ define i32 @test10(double %a) nounwind {
; CHECK: fcmp oeq double %a, 0.000000e+00
}
+define i32 @test10_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp ole double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test10_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp oeq double %a, 0.000000e+00
+}
+
define i32 @test11(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp ogt double %call, 0.000000e+00
@@ -101,6 +123,16 @@ define i32 @test11(double %a) nounwind {
; CHECK: fcmp one double %a, 0.000000e+00
}
+define i32 @test11_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp ogt double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test11_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp one double %a, 0.000000e+00
+}
+
define i32 @test12(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp oge double %call, 0.000000e+00
@@ -111,6 +143,16 @@ define i32 @test12(double %a) nounwind {
; CHECK: fcmp ord double %a, 0.000000e+00
}
+define i32 @test12_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp oge double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test12_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp ord double %a, 0.000000e+00
+}
+
define i32 @test13(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp une double %call, 0.000000e+00
@@ -121,6 +163,16 @@ define i32 @test13(double %a) nounwind {
; CHECK: fcmp une double %a, 0.000000e+00
}
+define i32 @test13_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp une double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test13_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp une double %a, 0.000000e+00
+}
+
define i32 @test14(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp oeq double %call, 0.000000e+00
@@ -131,6 +183,16 @@ define i32 @test14(double %a) nounwind {
; CHECK: fcmp oeq double %a, 0.000000e+00
}
+define i32 @test14_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp oeq double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test14_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp oeq double %a, 0.000000e+00
+}
+
define i32 @test15(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp one double %call, 0.000000e+00
@@ -141,6 +203,16 @@ define i32 @test15(double %a) nounwind {
; CHECK: fcmp one double %a, 0.000000e+00
}
+define i32 @test15_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp one double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test15_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp one double %a, 0.000000e+00
+}
+
define i32 @test16(double %a) nounwind {
%call = tail call double @fabs(double %a) nounwind
%cmp = fcmp ueq double %call, 0.000000e+00
@@ -151,6 +223,16 @@ define i32 @test16(double %a) nounwind {
; CHECK: fcmp ueq double %a, 0.000000e+00
}
+define i32 @test16_intrinsic(double %a) nounwind {
+ %call = tail call double @llvm.fabs.f64(double %a) nounwind
+ %cmp = fcmp ueq double %call, 0.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+; CHECK-LABEL: @test16_intrinsic(
+; CHECK-NOT: fabs
+; CHECK: fcmp ueq double %a, 0.000000e+00
+}
+
; Don't crash.
define i32 @test17(double %a, double (double)* %p) nounwind {
%call = tail call double %p(double %a) nounwind
diff --git a/test/Transforms/InstCombine/float-shrink-compare.ll b/test/Transforms/InstCombine/float-shrink-compare.ll
index e500467..a08f953 100644
--- a/test/Transforms/InstCombine/float-shrink-compare.ll
+++ b/test/Transforms/InstCombine/float-shrink-compare.ll
@@ -222,8 +222,46 @@ define i32 @test18(float %x, float %y, float %z) nounwind uwtable {
; CHECK-NEXT: fcmp oeq float %fmaxf, %z
}
+define i32 @test19(float %x, float %y, float %z) nounwind uwtable {
+ %1 = fpext float %x to double
+ %2 = fpext float %y to double
+ %3 = call double @copysign(double %1, double %2) nounwind
+ %4 = fpext float %z to double
+ %5 = fcmp oeq double %3, %4
+ %6 = zext i1 %5 to i32
+ ret i32 %6
+; CHECK-LABEL: @test19(
+; CHECK-NEXT: %copysignf = call float @copysignf(float %x, float %y)
+; CHECK-NEXT: fcmp oeq float %copysignf, %z
+}
+
+define i32 @test20(float %x, float %y) nounwind uwtable {
+ %1 = fpext float %y to double
+ %2 = fpext float %x to double
+ %3 = call double @fmin(double 1.000000e+00, double %2) nounwind
+ %4 = fcmp oeq double %1, %3
+ %5 = zext i1 %4 to i32
+ ret i32 %5
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: %fminf = call float @fminf(float 1.000000e+00, float %x)
+; CHECK-NEXT: fcmp oeq float %fminf, %y
+}
+
+define i32 @test21(float %x, float %y) nounwind uwtable {
+ %1 = fpext float %y to double
+ %2 = fpext float %x to double
+ %3 = call double @fmin(double 1.300000e+00, double %2) nounwind
+ %4 = fcmp oeq double %1, %3
+ %5 = zext i1 %4 to i32
+ ret i32 %5
+; should not be changed to fminf as the constant would loose precision
+; CHECK-LABEL: @test21(
+; CHECK: %3 = call double @fmin(double 1.300000e+00, double %2)
+}
+
declare double @fabs(double) nounwind readnone
declare double @ceil(double) nounwind readnone
+declare double @copysign(double, double) nounwind readnone
declare double @floor(double) nounwind readnone
declare double @nearbyint(double) nounwind readnone
declare double @rint(double) nounwind readnone
diff --git a/test/Transforms/InstCombine/fpcast.ll b/test/Transforms/InstCombine/fpcast.ll
index ac03402..8319624 100644
--- a/test/Transforms/InstCombine/fpcast.ll
+++ b/test/Transforms/InstCombine/fpcast.ll
@@ -73,3 +73,15 @@ define float @test7(double %V) {
; CHECK-NEXT: %[[trunc:.*]] = fptrunc double %frem to float
; CHECK-NEXT: ret float %trunc
}
+
+define float @test8(float %V) {
+ %fext = fpext float %V to double
+ %frem = frem double %fext, 1.000000e-01
+ %trunc = fptrunc double %frem to float
+ ret float %trunc
+; CHECK-LABEL: @test8
+; CHECK-NEXT: %[[fext:.*]] = fpext float %V to double
+; CHECK-NEXT: %[[frem:.*]] = frem double %fext, 1.000000e-01
+; CHECK-NEXT: %[[trunc:.*]] = fptrunc double %frem to float
+; CHECK-NEXT: ret float %trunc
+}
diff --git a/test/Transforms/InstCombine/gc.relocate.ll b/test/Transforms/InstCombine/gc.relocate.ll
new file mode 100644
index 0000000..d10ef5f
--- /dev/null
+++ b/test/Transforms/InstCombine/gc.relocate.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -datalayout -instcombine -S | FileCheck %s
+
+; Uses InstCombine with DataLayout to propagate dereferenceable
+; attribute via gc.relocate: if the derived ptr is dereferenceable(N),
+; then the return attribute of gc.relocate is dereferenceable(N).
+
+declare zeroext i1 @return_i1()
+declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
+declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
+
+define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) {
+; Checks that a dereferenceabler pointer
+; CHECK-LABEL: @deref
+; CHECK: call dereferenceable(8)
+entry:
+ %load = load i32 addrspace(1)* %dparam
+ %tok = tail call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
+ %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 4, i32 4)
+ ret i32 addrspace(1)* %relocate
+} \ No newline at end of file
diff --git a/test/Transforms/InstCombine/gep-sext.ll b/test/Transforms/InstCombine/gep-sext.ll
new file mode 100644
index 0000000..3d23dab
--- /dev/null
+++ b/test/Transforms/InstCombine/gep-sext.ll
@@ -0,0 +1,61 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-win32"
+
+declare void @use(i32) readonly
+
+; We prefer to canonicalize the machine width gep indices early
+define void @test(i32* %p, i32 %index) {
+; CHECK-LABEL: @test
+; CHECK-NEXT: %1 = sext i32 %index to i64
+; CHECK-NEXT: %addr = getelementptr i32* %p, i64 %1
+ %addr = getelementptr i32* %p, i32 %index
+ %val = load i32* %addr
+ call void @use(i32 %val)
+ ret void
+}
+; If they've already been canonicalized via zext, that's fine
+define void @test2(i32* %p, i32 %index) {
+; CHECK-LABEL: @test2
+; CHECK-NEXT: %i = zext i32 %index to i64
+; CHECK-NEXT: %addr = getelementptr i32* %p, i64 %i
+ %i = zext i32 %index to i64
+ %addr = getelementptr i32* %p, i64 %i
+ %val = load i32* %addr
+ call void @use(i32 %val)
+ ret void
+}
+; If we can use a zext, we prefer that. This requires
+; knowing that the index is positive.
+define void @test3(i32* %p, i32 %index) {
+; CHECK-LABEL: @test3
+; CHECK: zext
+; CHECK-NOT: sext
+ %addr_begin = getelementptr i32* %p, i64 40
+ %addr_fixed = getelementptr i32* %addr_begin, i64 48
+ %val_fixed = load i32* %addr_fixed, !range !0
+ %addr = getelementptr i32* %addr_begin, i32 %val_fixed
+ %val = load i32* %addr
+ call void @use(i32 %val)
+ ret void
+}
+; Replace sext with zext where possible
+define void @test4(i32* %p, i32 %index) {
+; CHECK-LABEL: @test4
+; CHECK: zext
+; CHECK-NOT: sext
+ %addr_begin = getelementptr i32* %p, i64 40
+ %addr_fixed = getelementptr i32* %addr_begin, i64 48
+ %val_fixed = load i32* %addr_fixed, !range !0
+ %i = sext i32 %val_fixed to i64
+ %addr = getelementptr i32* %addr_begin, i64 %i
+ %val = load i32* %addr
+ call void @use(i32 %val)
+ ret void
+}
+
+;; !range !0
+!0 = !{i32 0, i32 2147483647}
+
+
+
diff --git a/test/Transforms/InstCombine/gepphigep.ll b/test/Transforms/InstCombine/gepphigep.ll
index 9aab609..86295e4 100644
--- a/test/Transforms/InstCombine/gepphigep.ll
+++ b/test/Transforms/InstCombine/gepphigep.ll
@@ -2,6 +2,8 @@
%struct1 = type { %struct2*, i32, i32, i32 }
%struct2 = type { i32, i32 }
+%struct3 = type { i32, %struct4, %struct4 }
+%struct4 = type { %struct2, %struct2 }
define i32 @test1(%struct1* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) {
bb:
@@ -54,3 +56,45 @@ bb:
; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp19, i32 0
; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 1
}
+
+; Check that instcombine doesn't insert GEPs before landingpad.
+
+define i32 @test3(%struct3* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19, i64 %tmp20, i64 %tmp21) {
+bb:
+ %tmp = getelementptr inbounds %struct3* %dm, i64 0
+ br i1 %tmp4, label %bb1, label %bb2
+
+bb1:
+ %tmp1 = getelementptr inbounds %struct3* %tmp, i64 %tmp19, i32 1
+ %tmp11 = getelementptr inbounds %struct4* %tmp1, i64 0, i32 0, i32 0
+ store i32 0, i32* %tmp11, align 4
+ br label %bb3
+
+bb2:
+ %tmp2 = getelementptr inbounds %struct3* %tmp, i64 %tmp20, i32 1
+ %tmp12 = getelementptr inbounds %struct4* %tmp2, i64 0, i32 0, i32 1
+ store i32 0, i32* %tmp12, align 4
+ br label %bb3
+
+bb3:
+ %phi = phi %struct4* [ %tmp1, %bb1 ], [ %tmp2, %bb2 ]
+ %tmp22 = invoke i32 @foo1(i32 11) to label %bb4 unwind label %bb5
+
+bb4:
+ ret i32 0
+
+bb5:
+ %tmp27 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) catch i8* bitcast (i8** @_ZTIi to i8*)
+ %tmp34 = getelementptr inbounds %struct4* %phi, i64 %tmp21, i32 1
+ %tmp35 = getelementptr inbounds %struct2* %tmp34, i64 0, i32 1
+ %tmp25 = load i32* %tmp35, align 4
+ ret i32 %tmp25
+
+; CHECK-LABEL: @test3(
+; CHECK: bb5:
+; CHECK-NEXT: {{.*}}landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+}
+
+@_ZTIi = external constant i8*
+declare i32 @__gxx_personality_v0(...)
+declare i32 @foo1(i32)
diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll
index bb46662..94cc180 100644
--- a/test/Transforms/InstCombine/getelementptr.ll
+++ b/test/Transforms/InstCombine/getelementptr.ll
@@ -602,8 +602,8 @@ entry:
%C = load i8** %B, align 8
ret i8* %C
; CHECK-LABEL: @test34(
-; CHECK: %V.c = inttoptr i64 %V to i8*
-; CHECK: ret i8* %V.c
+; CHECK: %[[C:.*]] = inttoptr i64 %V to i8*
+; CHECK: ret i8* %[[C]]
}
%t0 = type { i8*, [19 x i8] }
diff --git a/test/Transforms/InstCombine/icmp-range.ll b/test/Transforms/InstCombine/icmp-range.ll
index 97d231f..0911ab0 100644
--- a/test/Transforms/InstCombine/icmp-range.ll
+++ b/test/Transforms/InstCombine/icmp-range.ll
@@ -55,7 +55,7 @@ define i1 @test_nonzero6(i8* %argw) {
}
-!0 = metadata !{i32 1, i32 6}
-!1 = metadata !{i32 0, i32 6}
-!2 = metadata !{i8 0, i8 1}
-!3 = metadata !{i8 0, i8 6}
+!0 = !{i32 1, i32 6}
+!1 = !{i32 0, i32 6}
+!2 = !{i8 0, i8 1}
+!3 = !{i8 0, i8 6}
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 279d86d..64741c5 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -1522,3 +1522,54 @@ define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
%icmp = icmp eq i32 %xtrc, %old_val
ret i1 %icmp
}
+
+; CHECK-LABEL: @f1
+; CHECK-NEXT: %[[cmp:.*]] = icmp sge i64 %a, %b
+; CHECK-NEXT: ret i1 %[[cmp]]
+define i1 @f1(i64 %a, i64 %b) {
+ %t = sub nsw i64 %a, %b
+ %v = icmp sge i64 %t, 0
+ ret i1 %v
+}
+
+; CHECK-LABEL: @f2
+; CHECK-NEXT: %[[cmp:.*]] = icmp sgt i64 %a, %b
+; CHECK-NEXT: ret i1 %[[cmp]]
+define i1 @f2(i64 %a, i64 %b) {
+ %t = sub nsw i64 %a, %b
+ %v = icmp sgt i64 %t, 0
+ ret i1 %v
+}
+
+; CHECK-LABEL: @f3
+; CHECK-NEXT: %[[cmp:.*]] = icmp slt i64 %a, %b
+; CHECK-NEXT: ret i1 %[[cmp]]
+define i1 @f3(i64 %a, i64 %b) {
+ %t = sub nsw i64 %a, %b
+ %v = icmp slt i64 %t, 0
+ ret i1 %v
+}
+
+; CHECK-LABEL: @f4
+; CHECK-NEXT: %[[cmp:.*]] = icmp sle i64 %a, %b
+; CHECK-NEXT: ret i1 %[[cmp]]
+define i1 @f4(i64 %a, i64 %b) {
+ %t = sub nsw i64 %a, %b
+ %v = icmp sle i64 %t, 0
+ ret i1 %v
+}
+
+; CHECK-LABEL: @f5
+; CHECK: %[[cmp:.*]] = icmp slt i32 %[[sub:.*]], 0
+; CHECK: %[[neg:.*]] = sub nsw i32 0, %[[sub]]
+; CHECK: %[[sel:.*]] = select i1 %[[cmp]], i32 %[[neg]], i32 %[[sub]]
+; CHECK: ret i32 %[[sel]]
+define i32 @f5(i8 %a, i8 %b) {
+ %conv = zext i8 %a to i32
+ %conv3 = zext i8 %b to i32
+ %sub = sub nsw i32 %conv, %conv3
+ %cmp4 = icmp slt i32 %sub, 0
+ %sub7 = sub nsw i32 0, %sub
+ %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
+ ret i32 %sub7.sub
+}
diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll
index 9b58d93..2791adf 100644
--- a/test/Transforms/InstCombine/intrinsics.ll
+++ b/test/Transforms/InstCombine/intrinsics.ll
@@ -1,10 +1,17 @@
; RUN: opt -instcombine -S < %s | FileCheck %s
%overflow.result = type {i8, i1}
+%ov.result.32 = type { i32, i1 }
+
-declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8)
-declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
-declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8)
+declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone
+declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone
+declare %ov.result.32 @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
+declare %ov.result.32 @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
+declare %ov.result.32 @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
+declare %ov.result.32 @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
+declare %ov.result.32 @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
+declare %ov.result.32 @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
declare double @llvm.powi.f64(double, i32) nounwind readonly
declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
@@ -91,17 +98,92 @@ define i8 @uaddtest7(i8 %A, i8 %B) {
}
; PR20194
-define { i32, i1 } @saddtest1(i8 %a, i8 %b) {
+define %ov.result.32 @saddtest_nsw(i8 %a, i8 %b) {
%A = sext i8 %a to i32
%B = sext i8 %b to i32
- %x = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %A, i32 %B)
- ret { i32, i1 } %x
-; CHECK-LABEL: @saddtest1
+ %x = call %ov.result.32 @llvm.sadd.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @saddtest_nsw
; CHECK: %x = add nsw i32 %A, %B
-; CHECK-NEXT: %1 = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 %x, 0
-; CHECK-NEXT: ret { i32, i1 } %1
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
}
+define %ov.result.32 @uaddtest_nuw(i32 %a, i32 %b) {
+ %A = and i32 %a, 2147483647
+ %B = and i32 %b, 2147483647
+ %x = call %ov.result.32 @llvm.uadd.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @uaddtest_nuw
+; CHECK: %x = add nuw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
+}
+
+define %ov.result.32 @ssubtest_nsw(i8 %a, i8 %b) {
+ %A = sext i8 %a to i32
+ %B = sext i8 %b to i32
+ %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @ssubtest_nsw
+; CHECK: %x = sub nsw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
+}
+
+define %ov.result.32 @usubtest_nuw(i32 %a, i32 %b) {
+ %A = or i32 %a, 2147483648
+ %B = and i32 %b, 2147483647
+ %x = call %ov.result.32 @llvm.usub.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @usubtest_nuw
+; CHECK: %x = sub nuw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
+}
+
+define %ov.result.32 @smultest1_nsw(i32 %a, i32 %b) {
+ %A = and i32 %a, 4095 ; 0xfff
+ %B = and i32 %b, 524287; 0x7ffff
+ %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @smultest1_nsw
+; CHECK: %x = mul nuw nsw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
+}
+
+define %ov.result.32 @smultest2_nsw(i32 %a, i32 %b) {
+ %A = ashr i32 %a, 16
+ %B = ashr i32 %b, 16
+ %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @smultest2_nsw
+; CHECK: %x = mul nsw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
+}
+
+define %ov.result.32 @smultest3_sw(i32 %a, i32 %b) {
+ %A = ashr i32 %a, 16
+ %B = ashr i32 %b, 15
+ %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @smultest3_sw
+; CHECK: %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
+; CHECK-NEXT: ret %ov.result.32 %x
+}
+
+define %ov.result.32 @umultest_nuw(i32 %a, i32 %b) {
+ %A = and i32 %a, 65535 ; 0xffff
+ %B = and i32 %b, 65535 ; 0xffff
+ %x = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %A, i32 %B)
+ ret %ov.result.32 %x
+; CHECK-LABEL: @umultest_nuw
+; CHECK: %x = mul nuw i32 %A, %B
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT: ret %ov.result.32 %1
+}
define i8 @umultest1(i8 %A, i1* %overflowPtr) {
%x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)
@@ -125,9 +207,6 @@ define i8 @umultest2(i8 %A, i1* %overflowPtr) {
; CHECK-NEXT: ret i8 %A
}
-%ov.result.32 = type { i32, i1 }
-declare %ov.result.32 @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
-
define i32 @umultest3(i32 %n) nounwind {
%shr = lshr i32 %n, 2
%mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %shr, i32 3)
@@ -152,6 +231,19 @@ define i32 @umultest4(i32 %n) nounwind {
; CHECK: umul.with.overflow
}
+define %ov.result.32 @umultest5(i32 %x, i32 %y) nounwind {
+ %or_x = or i32 %x, 2147483648
+ %or_y = or i32 %y, 2147483648
+ %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %or_x, i32 %or_y)
+ ret %ov.result.32 %mul
+; CHECK-LABEL: @umultest5(
+; CHECK-NEXT: %[[or_x:.*]] = or i32 %x, -2147483648
+; CHECK-NEXT: %[[or_y:.*]] = or i32 %y, -2147483648
+; CHECK-NEXT: %[[mul:.*]] = mul i32 %[[or_x]], %[[or_y]]
+; CHECK-NEXT: %[[ret:.*]] = insertvalue %ov.result.32 { i32 undef, i1 true }, i32 %[[mul]], 0
+; CHECK-NEXT: ret %ov.result.32 %[[ret]]
+}
+
define void @powi(double %V, double *%P) {
entry:
%A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind
@@ -257,7 +349,8 @@ define i32 @ctlz_select(i32 %Value) nounwind {
ret i32 %s
; CHECK-LABEL: @ctlz_select(
-; CHECK: select i1 %tobool, i32 %ctlz, i32 32
+; CHECK-NEXT: call i32 @llvm.ctlz.i32(i32 %Value, i1 false)
+; CHECK-NEXT: ret i32
}
define i32 @cttz_select(i32 %Value) nounwind {
@@ -267,5 +360,6 @@ define i32 @cttz_select(i32 %Value) nounwind {
ret i32 %s
; CHECK-LABEL: @cttz_select(
-; CHECK: select i1 %tobool, i32 %cttz, i32 32
+; CHECK-NEXT: call i32 @llvm.cttz.i32(i32 %Value, i1 false)
+; CHECK-NEXT: ret i32
}
diff --git a/test/Transforms/InstCombine/load-cmp.ll b/test/Transforms/InstCombine/load-cmp.ll
index 9810026..40673a7 100644
--- a/test/Transforms/InstCombine/load-cmp.ll
+++ b/test/Transforms/InstCombine/load-cmp.ll
@@ -230,7 +230,7 @@ define i1 @test10_struct(i32 %x) {
; NODL: getelementptr inbounds %Foo* @GS, i32 %x, i32 0
; P32-LABEL: @test10_struct(
-; P32: getelementptr inbounds %Foo* @GS, i32 %x, i32 0
+; P32: ret i1 false
%p = getelementptr inbounds %Foo* @GS, i32 %x, i32 0
%q = load i32* %p
%r = icmp eq i32 %q, 9
@@ -256,8 +256,7 @@ define i1 @test10_struct_i16(i16 %x){
; NODL: getelementptr inbounds %Foo* @GS, i16 %x, i32 0
; P32-LABEL: @test10_struct_i16(
-; P32: %1 = sext i16 %x to i32
-; P32: getelementptr inbounds %Foo* @GS, i32 %1, i32 0
+; P32: ret i1 false
%p = getelementptr inbounds %Foo* @GS, i16 %x, i32 0
%q = load i32* %p
%r = icmp eq i32 %q, 0
@@ -271,8 +270,7 @@ define i1 @test10_struct_i64(i64 %x){
; NODL: getelementptr inbounds %Foo* @GS, i64 %x, i32 0
; P32-LABEL: @test10_struct_i64(
-; P32: %1 = trunc i64 %x to i32
-; P32: getelementptr inbounds %Foo* @GS, i32 %1, i32 0
+; P32: ret i1 false
%p = getelementptr inbounds %Foo* @GS, i64 %x, i32 0
%q = load i32* %p
%r = icmp eq i32 %q, 0
diff --git a/test/Transforms/InstCombine/load.ll b/test/Transforms/InstCombine/load.ll
index b4b7558..624083b 100644
--- a/test/Transforms/InstCombine/load.ll
+++ b/test/Transforms/InstCombine/load.ll
@@ -1,8 +1,9 @@
; RUN: opt -instcombine -S < %s | FileCheck %s
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
; This test makes sure that these instructions are properly eliminated.
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target datalayout = "e-m:e-p:64:64:64-i64:64-f80:128-n8:16:32:64-S128"
@X = constant i32 42 ; <i32*> [#uses=2]
@X2 = constant i32 47 ; <i32*> [#uses=1]
@@ -150,3 +151,53 @@ define i8 @test15(i8 %x, i32 %y) {
%r = load i8* %g.i8
ret i8 %r
}
+
+define void @test16(i8* %x, i8* %a, i8* %b, i8* %c) {
+; Check that we canonicalize loads which are only stored to use integer types
+; when there is a valid integer type.
+; CHECK-LABEL: @test16(
+; CHECK: %[[L1:.*]] = load i32*
+; CHECK-NOT: load
+; CHECK: store i32 %[[L1]], i32*
+; CHECK: store i32 %[[L1]], i32*
+; CHECK-NOT: store
+; CHECK: %[[L1:.*]] = load i32*
+; CHECK-NOT: load
+; CHECK: store i32 %[[L1]], i32*
+; CHECK: store i32 %[[L1]], i32*
+; CHECK-NOT: store
+; CHECK: ret
+
+entry:
+ %x.cast = bitcast i8* %x to float*
+ %a.cast = bitcast i8* %a to float*
+ %b.cast = bitcast i8* %b to float*
+ %c.cast = bitcast i8* %c to i32*
+
+ %x1 = load float* %x.cast
+ store float %x1, float* %a.cast
+ store float %x1, float* %b.cast
+
+ %x2 = load float* %x.cast
+ store float %x2, float* %b.cast
+ %x2.cast = bitcast float %x2 to i32
+ store i32 %x2.cast, i32* %c.cast
+
+ ret void
+}
+
+define void @test17(i8** %x, i8 %y) {
+; Check that in cases similar to @test16 we don't try to rewrite a load when
+; its only use is a store but it is used as the pointer to that store rather
+; than the value.
+;
+; CHECK-LABEL: @test17(
+; CHECK: %[[L:.*]] = load i8**
+; CHECK: store i8 %y, i8* %[[L]]
+
+entry:
+ %x.load = load i8** %x
+ store i8 %y, i8* %x.load
+
+ ret void
+}
diff --git a/test/Transforms/InstCombine/loadstore-metadata.ll b/test/Transforms/InstCombine/loadstore-metadata.ll
index 863edae..be55fa6 100644
--- a/test/Transforms/InstCombine/loadstore-metadata.ll
+++ b/test/Transforms/InstCombine/loadstore-metadata.ll
@@ -1,5 +1,7 @@
; RUN: opt -instcombine -S < %s | FileCheck %s
+target datalayout = "e-m:e-p:64:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
define i32 @test_load_cast_combine_tbaa(float* %ptr) {
; Ensure (cast (load (...))) -> (load (cast (...))) preserves TBAA.
; CHECK-LABEL: @test_load_cast_combine_tbaa(
@@ -78,9 +80,34 @@ exit:
ret void
}
-!0 = metadata !{ metadata !1, metadata !1, i64 0 }
-!1 = metadata !{ metadata !1 }
-!2 = metadata !{ metadata !2, metadata !1 }
-!3 = metadata !{ }
-!4 = metadata !{ i32 1 }
-!5 = metadata !{ i32 0, i32 42 }
+define void @test_load_cast_combine_nonnull(float** %ptr) {
+; We can't preserve nonnull metadata when converting a load of a pointer to
+; a load of an integer. Instead, we translate it to range metadata.
+; FIXME: We should also transform range metadata back into nonnull metadata.
+; FIXME: This test is very fragile. If any LABEL lines are added after
+; this point, the test will fail, because this test depends on a metadata tuple,
+; which is always emitted at the end of the file. At some point, we should
+; consider an option to the IR printer to emit MD tuples after the function
+; that first uses them--this will allow us to refer to them like this and not
+; have the tests break. For now, this function must always come last in this
+; file, and no LABEL lines are to be added after this point.
+;
+; CHECK-LABEL: @test_load_cast_combine_nonnull(
+; CHECK: %[[V:.*]] = load i64* %{{.*}}, !range ![[MD:[0-9]+]]
+; CHECK-NOT: !nonnull
+; CHECK: store i64 %[[V]], i64*
+entry:
+ %p = load float** %ptr, !nonnull !3
+ %gep = getelementptr float** %ptr, i32 42
+ store float* %p, float** %gep
+ ret void
+}
+
+; This is the metadata tuple that we reference above:
+; CHECK: ![[MD]] = !{i64 1, i64 0}
+!0 = !{ !1, !1, i64 0 }
+!1 = !{ !1 }
+!2 = !{ !2, !1 }
+!3 = !{ }
+!4 = !{ i32 1 }
+!5 = !{ i32 0, i32 42 }
diff --git a/test/Transforms/InstCombine/malloc-free-delete.ll b/test/Transforms/InstCombine/malloc-free-delete.ll
index ed25e4e..765c8c3 100644
--- a/test/Transforms/InstCombine/malloc-free-delete.ll
+++ b/test/Transforms/InstCombine/malloc-free-delete.ll
@@ -146,17 +146,36 @@ lpad.i: ; preds = %entry
}
declare i8* @_Znwm(i64) nobuiltin
-declare void @_ZdlPvm(i8*, i64) nobuiltin
declare i8* @_Znwj(i32) nobuiltin
-declare void @_ZdlPvj(i8*, i32) nobuiltin
declare i8* @_Znam(i64) nobuiltin
-declare void @_ZdaPvm(i8*, i64) nobuiltin
declare i8* @_Znaj(i32) nobuiltin
-declare void @_ZdaPvj(i8*, i32) nobuiltin
+declare void @_ZdlPv(i8*) nobuiltin
+declare void @_ZdaPv(i8*) nobuiltin
+
+define linkonce void @_ZdlPvm(i8* %p, i64) nobuiltin {
+ call void @_ZdlPv(i8* %p)
+ ret void
+}
+define linkonce void @_ZdlPvj(i8* %p, i32) nobuiltin {
+ call void @_ZdlPv(i8* %p)
+ ret void
+}
+define linkonce void @_ZdaPvm(i8* %p, i64) nobuiltin {
+ call void @_ZdaPv(i8* %p)
+ ret void
+}
+define linkonce void @_ZdaPvj(i8* %p, i32) nobuiltin {
+ call void @_ZdaPv(i8* %p)
+ ret void
+}
; CHECK-LABEL: @test8(
define void @test8() {
; CHECK-NOT: call
+ %nw = call i8* @_Znwm(i64 32) builtin
+ call void @_ZdlPv(i8* %nw) builtin
+ %na = call i8* @_Znam(i64 32) builtin
+ call void @_ZdaPv(i8* %na) builtin
%nwm = call i8* @_Znwm(i64 32) builtin
call void @_ZdlPvm(i8* %nwm, i64 32) builtin
%nwj = call i8* @_Znwj(i32 32) builtin
diff --git a/test/Transforms/InstCombine/max-of-nots.ll b/test/Transforms/InstCombine/max-of-nots.ll
new file mode 100644
index 0000000..41e3038
--- /dev/null
+++ b/test/Transforms/InstCombine/max-of-nots.ll
@@ -0,0 +1,68 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+define i32 @compute_min_2(i32 %x, i32 %y) {
+; CHECK-LABEL: compute_min_2
+ entry:
+ %not_x = sub i32 -1, %x
+ %not_y = sub i32 -1, %y
+ %cmp = icmp sgt i32 %not_x, %not_y
+ %not_min = select i1 %cmp, i32 %not_x, i32 %not_y
+ %min = sub i32 -1, %not_min
+ ret i32 %min
+
+; CHECK: %0 = icmp slt i32 %x, %y
+; CHECK-NEXT: %1 = select i1 %0, i32 %x, i32 %y
+; CHECK-NEXT: ret i32 %1
+}
+
+define i32 @compute_min_3(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: compute_min_3
+ entry:
+ %not_x = sub i32 -1, %x
+ %not_y = sub i32 -1, %y
+ %not_z = sub i32 -1, %z
+ %cmp_1 = icmp sgt i32 %not_x, %not_y
+ %not_min_1 = select i1 %cmp_1, i32 %not_x, i32 %not_y
+ %cmp_2 = icmp sgt i32 %not_min_1, %not_z
+ %not_min_2 = select i1 %cmp_2, i32 %not_min_1, i32 %not_z
+ %min = sub i32 -1, %not_min_2
+ ret i32 %min
+
+; CHECK: %0 = icmp slt i32 %x, %y
+; CHECK-NEXT: %1 = select i1 %0, i32 %x, i32 %y
+; CHECK-NEXT: %2 = icmp slt i32 %1, %z
+; CHECK-NEXT: %3 = select i1 %2, i32 %1, i32 %z
+; CHECK-NEXT: ret i32 %3
+}
+
+define i32 @compute_min_arithmetic(i32 %x, i32 %y) {
+; CHECK-LABEL: compute_min_arithmetic
+ entry:
+ %not_value = sub i32 3, %x
+ %not_y = sub i32 -1, %y
+ %cmp = icmp sgt i32 %not_value, %not_y
+ %not_min = select i1 %cmp, i32 %not_value, i32 %not_y
+ ret i32 %not_min
+
+; CHECK: %0 = add i32 %x, -4
+; CHECK-NEXT: %1 = icmp slt i32 %0, %y
+; CHECK-NEXT: %2 = select i1 %1, i32 %0, i32 %y
+; CHECK-NEXT: %3 = xor i32 %2, -1
+; CHECK-NEXT: ret i32 %3
+}
+
+declare void @fake_use(i32)
+
+define i32 @compute_min_pessimization(i32 %x, i32 %y) {
+; CHECK-LABEL: compute_min_pessimization
+ entry:
+ %not_value = sub i32 3, %x
+ call void @fake_use(i32 %not_value)
+ %not_y = sub i32 -1, %y
+ %cmp = icmp sgt i32 %not_value, %not_y
+; CHECK: %not_value = sub i32 3, %x
+; CHECK: %cmp = icmp sgt i32 %not_value, %not_y
+ %not_min = select i1 %cmp, i32 %not_value, i32 %not_y
+ %min = sub i32 -1, %not_min
+ ret i32 %min
+}
diff --git a/test/Transforms/InstCombine/mem-gep-zidx.ll b/test/Transforms/InstCombine/mem-gep-zidx.ll
new file mode 100644
index 0000000..9141d99
--- /dev/null
+++ b/test/Transforms/InstCombine/mem-gep-zidx.ll
@@ -0,0 +1,48 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+@f.a = private unnamed_addr constant [1 x i32] [i32 12], align 4
+@f.b = private unnamed_addr constant [1 x i32] [i32 55], align 4
+
+define signext i32 @test1(i32 signext %x) #0 {
+entry:
+ %idxprom = sext i32 %x to i64
+ %arrayidx = getelementptr inbounds [1 x i32]* @f.a, i64 0, i64 %idxprom
+ %0 = load i32* %arrayidx, align 4
+ ret i32 %0
+
+; CHECK-LABEL: @test1
+; CHECK: ret i32 12
+}
+
+declare void @foo(i64* %p)
+define void @test2(i32 signext %x, i64 %v) #0 {
+entry:
+ %p = alloca i64
+ %idxprom = sext i32 %x to i64
+ %arrayidx = getelementptr inbounds i64* %p, i64 %idxprom
+ store i64 %v, i64* %arrayidx
+ call void @foo(i64* %p)
+ ret void
+
+; CHECK-LABEL: @test2
+; CHECK: %p = alloca i64
+; CHECK: store i64 %v, i64* %p
+; CHECK: ret void
+}
+
+define signext i32 @test3(i32 signext %x, i1 %y) #0 {
+entry:
+ %idxprom = sext i32 %x to i64
+ %p = select i1 %y, [1 x i32]* @f.a, [1 x i32]* @f.b
+ %arrayidx = getelementptr inbounds [1 x i32]* %p, i64 0, i64 %idxprom
+ %0 = load i32* %arrayidx, align 4
+ ret i32 %0
+
+; CHECK-LABEL: @test3
+; CHECK: getelementptr inbounds [1 x i32]* %p, i64 0, i64 0
+}
+
+attributes #0 = { nounwind readnone }
+
diff --git a/test/Transforms/InstCombine/memcpy_chk-1.ll b/test/Transforms/InstCombine/memcpy_chk-1.ll
index 9216ae7..ddaaf82 100644
--- a/test/Transforms/InstCombine/memcpy_chk-1.ll
+++ b/test/Transforms/InstCombine/memcpy_chk-1.ll
@@ -15,46 +15,63 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; Check cases where dstlen >= len.
-define void @test_simplify1() {
+define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
%dst = bitcast %struct.T1* @t1 to i8*
%src = bitcast %struct.T2* @t2 to i8*
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
- call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
+ %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
+ ret i8* %ret
}
-define void @test_simplify2() {
+define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
%dst = bitcast %struct.T1* @t1 to i8*
%src = bitcast %struct.T3* @t3 to i8*
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
- call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T3* @t3 to i8*), i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
+ %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
+ ret i8* %ret
}
; Check cases where dstlen < len.
-define void @test_no_simplify1() {
+define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
%dst = bitcast %struct.T3* @t3 to i8*
%src = bitcast %struct.T1* @t1 to i8*
-; CHECK-NEXT: call i8* @__memcpy_chk
- call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
- ret void
+; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64 2848, i64 1824)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
+ ret i8* %ret
}
-define void @test_no_simplify2() {
+define i8* @test_no_simplify2() {
; CHECK-LABEL: @test_no_simplify2(
%dst = bitcast %struct.T1* @t1 to i8*
%src = bitcast %struct.T2* @t2 to i8*
-; CHECK-NEXT: call i8* @__memcpy_chk
- call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0)
- ret void
+; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1024, i64 0)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0)
+ ret i8* %ret
+}
+
+define i8* @test_simplify_return_indcall(i8* ()* %alloc) {
+; CHECK-LABEL: @test_simplify_return_indcall(
+ %src = bitcast %struct.T2* @t2 to i8*
+
+; CHECK-NEXT: %dst = call i8* %alloc()
+ %dst = call i8* %alloc()
+
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
+ %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
+; CHECK-NEXT: ret i8* %dst
+ ret i8* %ret
}
declare i8* @__memcpy_chk(i8*, i8*, i64, i64)
diff --git a/test/Transforms/InstCombine/memmove_chk-1.ll b/test/Transforms/InstCombine/memmove_chk-1.ll
index 6d93bbb..e4e1f6e 100644
--- a/test/Transforms/InstCombine/memmove_chk-1.ll
+++ b/test/Transforms/InstCombine/memmove_chk-1.ll
@@ -15,46 +15,50 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; Check cases where dstlen >= len.
-define void @test_simplify1() {
+define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
%dst = bitcast %struct.T1* @t1 to i8*
%src = bitcast %struct.T2* @t2 to i8*
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64
- call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
- ret void
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
+ %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
+ ret i8* %ret
}
-define void @test_simplify2() {
+define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
%dst = bitcast %struct.T1* @t1 to i8*
%src = bitcast %struct.T3* @t3 to i8*
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64
- call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
- ret void
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T3* @t3 to i8*), i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
+ %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
+ ret i8* %ret
}
; Check cases where dstlen < len.
-define void @test_no_simplify1() {
+define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
%dst = bitcast %struct.T3* @t3 to i8*
%src = bitcast %struct.T1* @t1 to i8*
-; CHECK-NEXT: call i8* @__memmove_chk
- call i8* @__memmove_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
- ret void
+; CHECK-NEXT: %ret = call i8* @__memmove_chk(i8* bitcast (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64 2848, i64 1824)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
+ ret i8* %ret
}
-define void @test_no_simplify2() {
+define i8* @test_no_simplify2() {
; CHECK-LABEL: @test_no_simplify2(
%dst = bitcast %struct.T1* @t1 to i8*
%src = bitcast %struct.T2* @t2 to i8*
-; CHECK-NEXT: call i8* @__memmove_chk
- call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1024, i64 0)
- ret void
+; CHECK-NEXT: %ret = call i8* @__memmove_chk(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1024, i64 0)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1024, i64 0)
+ ret i8* %ret
}
declare i8* @__memmove_chk(i8*, i8*, i64, i64)
diff --git a/test/Transforms/InstCombine/memset_chk-1.ll b/test/Transforms/InstCombine/memset_chk-1.ll
index 47cc7db..27f7293 100644
--- a/test/Transforms/InstCombine/memset_chk-1.ll
+++ b/test/Transforms/InstCombine/memset_chk-1.ll
@@ -11,51 +11,56 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; Check cases where dstlen >= len.
-define void @test_simplify1() {
+define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
%dst = bitcast %struct.T* @t to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64
- call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
- ret void
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
+ %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
+ ret i8* %ret
}
-define void @test_simplify2() {
+define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
%dst = bitcast %struct.T* @t to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64
- call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648)
- ret void
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
+ %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648)
+ ret i8* %ret
}
-define void @test_simplify3() {
+define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
%dst = bitcast %struct.T* @t to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64
- call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1)
- ret void
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i32 4, i1 false)
+; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
+ %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1)
+ ret i8* %ret
}
; Check cases where dstlen < len.
-define void @test_no_simplify1() {
+define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
%dst = bitcast %struct.T* @t to i8*
-; CHECK-NEXT: call i8* @__memset_chk
- call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 400)
- ret void
+; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast (%struct.T* @t to i8*), i32 0, i64 1824, i64 400)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 400)
+ ret i8* %ret
}
-define void @test_no_simplify2() {
+define i8* @test_no_simplify2() {
; CHECK-LABEL: @test_no_simplify2(
%dst = bitcast %struct.T* @t to i8*
-; CHECK-NEXT: call i8* @__memset_chk
- call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 0)
- ret void
+; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast (%struct.T* @t to i8*), i32 0, i64 1824, i64 0)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 0)
+ ret i8* %ret
}
declare i8* @__memset_chk(i8*, i32, i64, i64)
diff --git a/test/Transforms/InstCombine/minnum.ll b/test/Transforms/InstCombine/minnum.ll
index 57d6e16..f7494e7 100644
--- a/test/Transforms/InstCombine/minnum.ll
+++ b/test/Transforms/InstCombine/minnum.ll
@@ -7,7 +7,7 @@ declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>) #0
declare double @llvm.minnum.f64(double, double) #0
declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>) #0
-declare float @llvm.fmax.f32(float, float) #0
+declare float @llvm.maxnum.f32(float, float) #0
; CHECK-LABEL: @constant_fold_minnum_f32
; CHECK-NEXT: ret float 1.000000e+00
@@ -206,23 +206,23 @@ define float @minnum4(float %x, float %y, float %z, float %w) #0 {
ret float %c
}
-; CHECK-LABEL: @minnum_x_fmax_x_y
-; CHECK-NEXT: call float @llvm.fmax.f32
+; CHECK-LABEL: @minnum_x_maxnum_x_y
+; CHECK-NEXT: call float @llvm.maxnum.f32
; CHECK-NEXT: call float @llvm.minnum.f32
; CHECK-NEXT: ret float
-define float @minnum_x_fmax_x_y(float %x, float %y) #0 {
- %a = call float @llvm.fmax.f32(float %x, float %y) #0
+define float @minnum_x_maxnum_x_y(float %x, float %y) #0 {
+ %a = call float @llvm.maxnum.f32(float %x, float %y) #0
%b = call float @llvm.minnum.f32(float %x, float %a) #0
ret float %b
}
-; CHECK-LABEL: @fmax_x_minnum_x_y
+; CHECK-LABEL: @maxnum_x_minnum_x_y
; CHECK-NEXT: call float @llvm.minnum.f32
-; CHECK-NEXT: call float @llvm.fmax.f32
+; CHECK-NEXT: call float @llvm.maxnum.f32
; CHECK-NEXT: ret float
-define float @fmax_x_minnum_x_y(float %x, float %y) #0 {
+define float @maxnum_x_minnum_x_y(float %x, float %y) #0 {
%a = call float @llvm.minnum.f32(float %x, float %y) #0
- %b = call float @llvm.fmax.f32(float %x, float %a) #0
+ %b = call float @llvm.maxnum.f32(float %x, float %a) #0
ret float %b
}
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index d19bedc..4d1e6c7 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -197,3 +197,94 @@ define <2 x i1> @test21(<2 x i1> %A, <2 x i1> %B) {
ret <2 x i1> %C
; CHECK: %C = and <2 x i1> %A, %B
}
+
+define i32 @test22(i32 %A) {
+; CHECK-LABEL: @test22(
+ %B = mul nsw i32 %A, -1
+ ret i32 %B
+; CHECK: sub nsw i32 0, %A
+}
+
+define i32 @test23(i32 %A) {
+; CHECK-LABEL: @test23(
+ %B = shl nuw i32 %A, 1
+ %C = mul nuw i32 %B, 3
+ ret i32 %C
+; CHECK: mul nuw i32 %A, 6
+}
+
+define i32 @test24(i32 %A) {
+; CHECK-LABEL: @test24(
+ %B = shl nsw i32 %A, 1
+ %C = mul nsw i32 %B, 3
+ ret i32 %C
+; CHECK: mul nsw i32 %A, 6
+}
+
+define i32 @test25(i32 %A, i32 %B) {
+; CHECK-LABEL: @test25(
+ %C = sub nsw i32 0, %A
+ %D = sub nsw i32 0, %B
+ %E = mul nsw i32 %C, %D
+ ret i32 %E
+; CHECK: mul nsw i32 %A, %B
+}
+
+define i32 @test26(i32 %A, i32 %B) {
+; CHECK-LABEL: @test26(
+ %C = shl nsw i32 1, %B
+ %D = mul nsw i32 %A, %C
+ ret i32 %D
+; CHECK: shl nsw i32 %A, %B
+}
+
+define i32 @test27(i32 %A, i32 %B) {
+; CHECK-LABEL: @test27(
+ %C = shl i32 1, %B
+ %D = mul nuw i32 %A, %C
+ ret i32 %D
+; CHECK: shl nuw i32 %A, %B
+}
+
+define i32 @test28(i32 %A) {
+; CHECK-LABEL: @test28(
+ %B = shl i32 1, %A
+ %C = mul nsw i32 %B, %B
+ ret i32 %C
+; CHECK: %[[shl1:.*]] = shl i32 1, %A
+; CHECK-NEXT: %[[shl2:.*]] = shl i32 %[[shl1]], %A
+; CHECK-NEXT: ret i32 %[[shl2]]
+}
+
+define i64 @test29(i31 %A, i31 %B) {
+; CHECK-LABEL: @test29(
+ %C = sext i31 %A to i64
+ %D = sext i31 %B to i64
+ %E = mul i64 %C, %D
+ ret i64 %E
+; CHECK: %[[sext1:.*]] = sext i31 %A to i64
+; CHECK-NEXT: %[[sext2:.*]] = sext i31 %B to i64
+; CHECK-NEXT: %[[mul:.*]] = mul nsw i64 %[[sext1]], %[[sext2]]
+; CHECK-NEXT: ret i64 %[[mul]]
+}
+
+define i64 @test30(i32 %A, i32 %B) {
+; CHECK-LABEL: @test30(
+ %C = zext i32 %A to i64
+ %D = zext i32 %B to i64
+ %E = mul i64 %C, %D
+ ret i64 %E
+; CHECK: %[[zext1:.*]] = zext i32 %A to i64
+; CHECK-NEXT: %[[zext2:.*]] = zext i32 %B to i64
+; CHECK-NEXT: %[[mul:.*]] = mul nuw i64 %[[zext1]], %[[zext2]]
+; CHECK-NEXT: ret i64 %[[mul]]
+}
+
+@PR22087 = external global i32
+define i32 @test31(i32 %V) {
+; CHECK-LABEL: @test31
+ %mul = mul i32 %V, shl (i32 1, i32 zext (i1 icmp ne (i32* inttoptr (i64 1 to i32*), i32* @PR22087) to i32))
+ ret i32 %mul
+; CHECK: %[[mul:.*]] = shl i32 %V, zext (i1 icmp ne (i32* inttoptr (i64 1 to i32*), i32* @PR22087) to i32)
+; CHECK-NEXT: ret i32 %[[mul]]
+}
diff --git a/test/Transforms/InstCombine/narrow-switch.ll b/test/Transforms/InstCombine/narrow-switch.ll
index 7646189..f3f19ba 100644
--- a/test/Transforms/InstCombine/narrow-switch.ll
+++ b/test/Transforms/InstCombine/narrow-switch.ll
@@ -91,3 +91,33 @@ return:
%retval.0 = phi i32 [ 24, %sw.default ], [ 123, %sw.bb2 ], [ 213, %sw.bb1 ], [ 231, %entry ]
ret i32 %retval.0
}
+
+; Make sure to avoid assertion crashes and use the type before
+; truncation to generate the sub constant expressions that leads
+; to the recomputed condition.
+;
+; CHECK-LABEL: @trunc64to59
+; CHECK: switch i59
+; CHECK: i59 0, label
+; CHECK: i59 18717182647723699, label
+
+define void @trunc64to59(i64 %a) {
+entry:
+ %tmp0 = and i64 %a, 15
+ %tmp1 = mul i64 %tmp0, -6425668444178048401
+ %tmp2 = add i64 %tmp1, 5170979678563097242
+ %tmp3 = mul i64 %tmp2, 1627972535142754813
+ switch i64 %tmp3, label %sw.default [
+ i64 847514119312061490, label %sw.bb1
+ i64 866231301959785189, label %sw.bb2
+ ]
+
+sw.bb1:
+ br label %sw.default
+
+sw.bb2:
+ br label %sw.default
+
+sw.default:
+ ret void
+}
diff --git a/test/Transforms/InstCombine/not-fcmp.ll b/test/Transforms/InstCombine/not-fcmp.ll
index ad01a6b..9718e0b 100644
--- a/test/Transforms/InstCombine/not-fcmp.ll
+++ b/test/Transforms/InstCombine/not-fcmp.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | grep "fcmp uge"
+; RUN: opt < %s -instcombine -S | FileCheck %s
; PR1570
define i1 @f(float %X, float %Y) {
@@ -6,5 +6,8 @@ entry:
%tmp3 = fcmp olt float %X, %Y ; <i1> [#uses=1]
%toBoolnot5 = xor i1 %tmp3, true ; <i1> [#uses=1]
ret i1 %toBoolnot5
+; CHECK-LABEL: @f(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %toBoolnot5 = fcmp uge float %X, %Y
+; CHECK-NEXT: ret i1 %toBoolnot5
}
-
diff --git a/test/Transforms/InstCombine/not.ll b/test/Transforms/InstCombine/not.ll
index 4a8825b..9d59edd 100644
--- a/test/Transforms/InstCombine/not.ll
+++ b/test/Transforms/InstCombine/not.ll
@@ -1,7 +1,8 @@
; This test makes sure that these instructions are properly eliminated.
;
-; RUN: opt < %s -instcombine -S | not grep xor
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; CHECK-NOT: xor
define i32 @test1(i32 %A) {
%B = xor i32 %A, -1 ; <i32> [#uses=1]
@@ -52,3 +53,8 @@ entry:
ret i8 %retval67
}
+define <2 x i1> @test7(<2 x i32> %A, <2 x i32> %B) {
+ %cond = icmp sle <2 x i32> %A, %B
+ %Ret = xor <2 x i1> %cond, <i1 true, i1 true>
+ ret <2 x i1> %Ret
+}
diff --git a/test/Transforms/InstCombine/or-xor.ll b/test/Transforms/InstCombine/or-xor.ll
index 670e3e0..546b777 100644
--- a/test/Transforms/InstCombine/or-xor.ll
+++ b/test/Transforms/InstCombine/or-xor.ll
@@ -103,81 +103,75 @@ define i32 @test10(i32 %A, i32 %B) {
; CHECK-NEXT: ret i32 -1
}
-define i32 @test11(i32 %A, i32 %B) {
- %xor1 = xor i32 %B, %A
- %not = xor i32 %A, -1
- %xor2 = xor i32 %not, %B
- %or = or i32 %xor1, %xor2
- ret i32 %or
-; CHECK-LABEL: @test11(
-; CHECK-NEXT: ret i32 -1
-}
-
; (x | y) & ((~x) ^ y) -> (x & y)
-define i32 @test12(i32 %x, i32 %y) {
+define i32 @test11(i32 %x, i32 %y) {
%or = or i32 %x, %y
%neg = xor i32 %x, -1
%xor = xor i32 %neg, %y
%and = and i32 %or, %xor
ret i32 %and
-; CHECK-LABEL: @test12(
+; CHECK-LABEL: @test11(
; CHECK-NEXT: %and = and i32 %x, %y
; CHECK-NEXT: ret i32 %and
}
; ((~x) ^ y) & (x | y) -> (x & y)
-define i32 @test13(i32 %x, i32 %y) {
+define i32 @test12(i32 %x, i32 %y) {
%neg = xor i32 %x, -1
%xor = xor i32 %neg, %y
%or = or i32 %x, %y
%and = and i32 %xor, %or
ret i32 %and
-; CHECK-LABEL: @test13(
+; CHECK-LABEL: @test12(
; CHECK-NEXT: %and = and i32 %x, %y
; CHECK-NEXT: ret i32 %and
}
; ((x | y) ^ (x ^ y)) -> (x & y)
-define i32 @test15(i32 %x, i32 %y) {
+define i32 @test13(i32 %x, i32 %y) {
%1 = xor i32 %y, %x
%2 = or i32 %y, %x
%3 = xor i32 %2, %1
ret i32 %3
-; CHECK-LABEL: @test15(
+; CHECK-LABEL: @test13(
; CHECK-NEXT: %1 = and i32 %y, %x
; CHECK-NEXT: ret i32 %1
}
; ((x | ~y) ^ (~x | y)) -> x ^ y
-define i32 @test16(i32 %x, i32 %y) {
+define i32 @test14(i32 %x, i32 %y) {
%noty = xor i32 %y, -1
%notx = xor i32 %x, -1
%or1 = or i32 %x, %noty
%or2 = or i32 %notx, %y
%xor = xor i32 %or1, %or2
ret i32 %xor
-; CHECK-LABEL: @test16(
+; CHECK-LABEL: @test14(
; CHECK-NEXT: %xor = xor i32 %x, %y
; CHECK-NEXT: ret i32 %xor
}
; ((x & ~y) ^ (~x & y)) -> x ^ y
-define i32 @test17(i32 %x, i32 %y) {
+define i32 @test15(i32 %x, i32 %y) {
%noty = xor i32 %y, -1
%notx = xor i32 %x, -1
%and1 = and i32 %x, %noty
%and2 = and i32 %notx, %y
%xor = xor i32 %and1, %and2
ret i32 %xor
-; CHECK-LABEL: @test17(
+; CHECK-LABEL: @test15(
; CHECK-NEXT: %xor = xor i32 %x, %y
; CHECK-NEXT: ret i32 %xor
}
-define i32 @test18(i32 %a, i32 %b) {
+define i32 @test16(i32 %a, i32 %b) {
%or = xor i32 %a, %b
%and1 = and i32 %or, 1
%and2 = and i32 %b, -2
%xor = or i32 %and1, %and2
ret i32 %xor
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: %1 = and i32 %a, 1
+; CHECK-NEXT: %xor = xor i32 %1, %b
+; CHECK-NEXT: ret i32 %xor
}
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index 23dad21..f604baf 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -506,3 +506,13 @@ define i1 @test47(i8 signext %c) {
; CHECK-NEXT: add i8 %1, -65
; CHECK-NEXT: icmp ult i8 %2, 27
}
+
+define i1 @test48(i64 %x, i1 %b) {
+ %1 = icmp ult i64 %x, 2305843009213693952
+ %2 = icmp ugt i64 %x, 2305843009213693951
+ %.b = or i1 %2, %b
+ %3 = or i1 %1, %.b
+ ret i1 %3
+; CHECK-LABEL: @test48(
+; CHECK-NEXT: ret i1 true
+}
diff --git a/test/Transforms/InstCombine/pr12251.ll b/test/Transforms/InstCombine/pr12251.ll
index 74a41eb..8c382bb 100644
--- a/test/Transforms/InstCombine/pr12251.ll
+++ b/test/Transforms/InstCombine/pr12251.ll
@@ -12,4 +12,4 @@ entry:
; CHECK-NEXT: %tobool = icmp ne i8 %a, 0
; CHECK-NEXT: ret i1 %tobool
-!0 = metadata !{i8 0, i8 2}
+!0 = !{i8 0, i8 2}
diff --git a/test/Transforms/InstCombine/pr12338.ll b/test/Transforms/InstCombine/pr12338.ll
index 614387a..7e0bf59 100644
--- a/test/Transforms/InstCombine/pr12338.ll
+++ b/test/Transforms/InstCombine/pr12338.ll
@@ -4,6 +4,7 @@ define void @entry() nounwind {
entry:
br label %for.cond
+; CHECK: br label %for.cond
for.cond:
%local = phi <1 x i32> [ <i32 0>, %entry ], [ %phi2, %cond.end47 ]
%phi3 = sub <1 x i32> zeroinitializer, %local
@@ -18,7 +19,6 @@ cond.end:
cond.end47:
%sum = add <1 x i32> %cond, <i32 92>
-; CHECK: sub <1 x i32> <i32 -92>, %cond
%phi2 = sub <1 x i32> zeroinitializer, %sum
br label %for.cond
}
diff --git a/test/Transforms/InstCombine/pr21199.ll b/test/Transforms/InstCombine/pr21199.ll
new file mode 100644
index 0000000..e6599fb
--- /dev/null
+++ b/test/Transforms/InstCombine/pr21199.ll
@@ -0,0 +1,25 @@
+; do not replace a 'select' with 'or' in 'select - cmp - br' sequence
+; RUN: opt -instcombine -S < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @f(i32)
+
+define void @test(i32 %len) {
+entry:
+ %cmp = icmp ult i32 %len, 8
+ %cond = select i1 %cmp, i32 %len, i32 8
+ %cmp11 = icmp ult i32 0, %cond
+ br i1 %cmp11, label %for.body, label %for.end
+
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ tail call void @f(i32 %cond)
+ %inc = add i32 %i.02, 1
+ %cmp1 = icmp ult i32 %inc, %cond
+ br i1 %cmp1, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ ret void
+; CHECK: select
+}
diff --git a/test/Transforms/InstCombine/pr21210.ll b/test/Transforms/InstCombine/pr21210.ll
new file mode 100644
index 0000000..1db8794
--- /dev/null
+++ b/test/Transforms/InstCombine/pr21210.ll
@@ -0,0 +1,50 @@
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -instcombine -S | FileCheck %s
+; Checks that the select-icmp optimization is safe in two cases
+declare void @foo(i32)
+declare i32 @bar(i32)
+
+; don't replace 'cond' by 'len' in the home block ('bb') that
+; contains the select
+define void @test1(i32 %len) {
+entry:
+ br label %bb
+
+bb:
+ %cmp = icmp ult i32 %len, 8
+ %cond = select i1 %cmp, i32 %len, i32 8
+ call void @foo(i32 %cond)
+ %cmp11 = icmp eq i32 %cond, 8
+ br i1 %cmp11, label %for.end, label %bb
+
+for.end:
+ ret void
+; CHECK: select
+; CHECK: icmp eq i32 %cond, 8
+}
+
+; don't replace 'cond' by 'len' in a block ('b1') that dominates all uses
+; of the select outside the home block ('bb'), but can be reached from the home
+; block on another path ('bb -> b0 -> b1')
+define void @test2(i32 %len) {
+entry:
+ %0 = call i32 @bar(i32 %len);
+ %cmp = icmp ult i32 %len, 4
+ br i1 %cmp, label %bb, label %b1
+bb:
+ %cond = select i1 %cmp, i32 %len, i32 8
+ %cmp11 = icmp eq i32 %cond, 8
+ br i1 %cmp11, label %b0, label %b1
+
+b0:
+ call void @foo(i32 %len)
+ br label %b1
+
+b1:
+; CHECK: phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ]
+ %1 = phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ]
+ br label %ret
+
+ret:
+ call void @foo(i32 %1)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/pr21651.ll b/test/Transforms/InstCombine/pr21651.ll
new file mode 100644
index 0000000..914785f
--- /dev/null
+++ b/test/Transforms/InstCombine/pr21651.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define void @PR21651() {
+ switch i2 0, label %out [
+ i2 0, label %out
+ i2 1, label %out
+ ]
+
+out:
+ ret void
+}
+
+; CHECK-LABEL: define void @PR21651(
+; CHECK: switch i2 0, label %out [
+; CHECK: i2 0, label %out
+; CHECK: i2 1, label %out
+; CHECK: ]
+; CHECK: out: ; preds = %0, %0, %0
+; CHECK: ret void
+; CHECK: }
diff --git a/test/Transforms/InstCombine/pr21891.ll b/test/Transforms/InstCombine/pr21891.ll
new file mode 100644
index 0000000..8194976
--- /dev/null
+++ b/test/Transforms/InstCombine/pr21891.ll
@@ -0,0 +1,18 @@
+; RUN: opt %s -instcombine
+
+define i32 @f(i32 %theNumber) {
+entry:
+ %cmp = icmp sgt i32 %theNumber, -1
+ call void @llvm.assume(i1 %cmp)
+ br i1 true, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %shl = shl nuw i32 %theNumber, 1
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %phi = phi i32 [ %shl, %if.then ], [ undef, %entry ]
+ ret i32 %phi
+}
+
+declare void @llvm.assume(i1)
diff --git a/test/Transforms/InstCombine/range-check.ll b/test/Transforms/InstCombine/range-check.ll
new file mode 100644
index 0000000..35f11dd
--- /dev/null
+++ b/test/Transforms/InstCombine/range-check.ll
@@ -0,0 +1,159 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; Check simplification of
+; (icmp sgt x, -1) & (icmp sgt/sge n, x) --> icmp ugt/uge n, x
+
+; CHECK-LABEL: define i1 @test_and1
+; CHECK: [[R:%[0-9]+]] = icmp ugt i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_and1(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp sge i32 %x, 0
+ %b = icmp slt i32 %x, %nn
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_and2
+; CHECK: [[R:%[0-9]+]] = icmp uge i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_and2(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp sgt i32 %x, -1
+ %b = icmp sle i32 %x, %nn
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_and3
+; CHECK: [[R:%[0-9]+]] = icmp ugt i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_and3(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp sgt i32 %nn, %x
+ %b = icmp sge i32 %x, 0
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_and4
+; CHECK: [[R:%[0-9]+]] = icmp uge i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_and4(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp sge i32 %nn, %x
+ %b = icmp sge i32 %x, 0
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_or1
+; CHECK: [[R:%[0-9]+]] = icmp ule i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_or1(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp slt i32 %x, 0
+ %b = icmp sge i32 %x, %nn
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_or2
+; CHECK: [[R:%[0-9]+]] = icmp ult i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_or2(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp sle i32 %x, -1
+ %b = icmp sgt i32 %x, %nn
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_or3
+; CHECK: [[R:%[0-9]+]] = icmp ule i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_or3(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp sle i32 %nn, %x
+ %b = icmp slt i32 %x, 0
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @test_or4
+; CHECK: [[R:%[0-9]+]] = icmp ult i32 %nn, %x
+; CHECK: ret i1 [[R]]
+define i1 @test_or4(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp slt i32 %nn, %x
+ %b = icmp slt i32 %x, 0
+ %c = or i1 %a, %b
+ ret i1 %c
+}
+
+; Negative tests
+
+; CHECK-LABEL: define i1 @negative1
+; CHECK: %a = icmp
+; CHECK: %b = icmp
+; CHECK: %c = and i1 %a, %b
+; CHECK: ret i1 %c
+define i1 @negative1(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp slt i32 %x, %nn
+ %b = icmp sgt i32 %x, 0 ; should be: icmp sge
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @negative2
+; CHECK: %a = icmp
+; CHECK: %b = icmp
+; CHECK: %c = and i1 %a, %b
+; CHECK: ret i1 %c
+define i1 @negative2(i32 %x, i32 %n) {
+ %a = icmp slt i32 %x, %n ; n can be negative
+ %b = icmp sge i32 %x, 0
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @negative3
+; CHECK: %a = icmp
+; CHECK: %b = icmp
+; CHECK: %c = and i1 %a, %b
+; CHECK: ret i1 %c
+define i1 @negative3(i32 %x, i32 %y, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp slt i32 %x, %nn
+ %b = icmp sge i32 %y, 0 ; should compare %x and not %y
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @negative4
+; CHECK: %a = icmp
+; CHECK: %b = icmp
+; CHECK: %c = and i1 %a, %b
+; CHECK: ret i1 %c
+define i1 @negative4(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp ne i32 %x, %nn ; should be: icmp slt/sle
+ %b = icmp sge i32 %x, 0
+ %c = and i1 %a, %b
+ ret i1 %c
+}
+
+; CHECK-LABEL: define i1 @negative5
+; CHECK: %a = icmp
+; CHECK: %b = icmp
+; CHECK: %c = or i1 %a, %b
+; CHECK: ret i1 %c
+define i1 @negative5(i32 %x, i32 %n) {
+ %nn = and i32 %n, 2147483647
+ %a = icmp slt i32 %x, %nn
+ %b = icmp sge i32 %x, 0
+ %c = or i1 %a, %b ; should be: and
+ ret i1 %c
+}
+
diff --git a/test/Transforms/InstCombine/select-cmp-br.ll b/test/Transforms/InstCombine/select-cmp-br.ll
new file mode 100644
index 0000000..f10d587
--- /dev/null
+++ b/test/Transforms/InstCombine/select-cmp-br.ll
@@ -0,0 +1,155 @@
+; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+%C = type <{ %struct.S }>
+%struct.S = type { i64*, i32, i32 }
+
+declare void @bar(%struct.S *) #1
+declare void @foobar()
+
+define void @test1(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* %0, %C* null
+ %8 = icmp eq %C* %7, null
+ br i1 %8, label %12, label %10
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test1(
+; CHECK-NOT: select
+; CHECK: or
+; CHECK-NOT: select
+}
+
+define void @test2(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* null, %C* %0
+ %8 = icmp eq %C* %7, null
+ br i1 %8, label %12, label %10
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test2(
+; CHECK-NOT: select
+; CHECK: or
+; CHECK-NOT: select
+}
+
+define void @test3(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* %0, %C* null
+ %8 = icmp ne %C* %7, null
+ br i1 %8, label %10, label %12
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test3(
+; CHECK-NOT: select
+; CHECK: or
+; CHECK-NOT: select
+}
+
+define void @test4(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* null, %C* %0
+ %8 = icmp ne %C* %7, null
+ br i1 %8, label %10, label %12
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test4(
+; CHECK-NOT: select
+; CHECK: or
+; CHECK-NOT: select
+}
+
+define void @test5(%C*, i1) {
+entry:
+ %2 = select i1 %1, %C* null, %C* %0
+ %3 = icmp ne %C* %2, null
+ br i1 %3, label %5, label %7
+
+; <label>:4 ; preds = %10, %12
+ ret void
+
+; <label>:5 ; preds = %entry
+ %6 = getelementptr inbounds %C* %2, i64 0, i32 0
+ tail call void @bar(%struct.S* %6)
+ br label %4
+
+; <label>:7 ; preds = %entry
+ tail call void @foobar()
+ br label %4
+; CHECK-LABEL: @test5(
+; CHECK-NOT: select
+; CHECK: or
+; CHECK-NOT: select
+}
diff --git a/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll b/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll
new file mode 100644
index 0000000..894bf6d
--- /dev/null
+++ b/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll
@@ -0,0 +1,327 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+; This test is to verify that the instruction combiner is able to fold
+; a cttz/ctlz followed by a icmp + select into a single cttz/ctlz with
+; the 'is_zero_undef' flag cleared.
+
+define i16 @test1(i16 %x) {
+; CHECK-LABEL: @test1(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
+; CHECK-NEXT: ret i16 [[VAR]]
+entry:
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
+ %tobool = icmp ne i16 %x, 0
+ %cond = select i1 %tobool, i16 %0, i16 16
+ ret i16 %cond
+}
+
+define i32 @test2(i32 %x) {
+; CHECK-LABEL: @test2(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+; CHECK-NEXT: ret i32 [[VAR]]
+entry:
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i32 %0, i32 32
+ ret i32 %cond
+}
+
+define i64 @test3(i64 %x) {
+; CHECK-LABEL: @test3(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
+; CHECK-NEXT: ret i64 [[VAR]]
+entry:
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %tobool = icmp ne i64 %x, 0
+ %cond = select i1 %tobool, i64 %0, i64 64
+ ret i64 %cond
+}
+
+define i16 @test4(i16 %x) {
+; CHECK-LABEL: @test4(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
+; CHECK-NEXT: ret i16 [[VAR]]
+entry:
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
+ %tobool = icmp eq i16 %x, 0
+ %cond = select i1 %tobool, i16 16, i16 %0
+ ret i16 %cond
+}
+
+define i32 @test5(i32 %x) {
+; CHECK-LABEL: @test5(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+; CHECK-NEXT: ret i32 [[VAR]]
+entry:
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %tobool = icmp eq i32 %x, 0
+ %cond = select i1 %tobool, i32 32, i32 %0
+ ret i32 %cond
+}
+
+define i64 @test6(i64 %x) {
+; CHECK-LABEL: @test6(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
+; CHECK-NEXT: ret i64 [[VAR]]
+entry:
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %tobool = icmp eq i64 %x, 0
+ %cond = select i1 %tobool, i64 64, i64 %0
+ ret i64 %cond
+}
+
+define i16 @test1b(i16 %x) {
+; CHECK-LABEL: @test1b(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
+; CHECK-NEXT: ret i16 [[VAR]]
+entry:
+ %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
+ %tobool = icmp ne i16 %x, 0
+ %cond = select i1 %tobool, i16 %0, i16 16
+ ret i16 %cond
+}
+
+define i32 @test2b(i32 %x) {
+; CHECK-LABEL: @test2b(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+; CHECK-NEXT: ret i32 [[VAR]]
+entry:
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i32 %0, i32 32
+ ret i32 %cond
+}
+
+define i64 @test3b(i64 %x) {
+; CHECK-LABEL: @test3b(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
+; CHECK-NEXT: ret i64 [[VAR]]
+entry:
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %tobool = icmp ne i64 %x, 0
+ %cond = select i1 %tobool, i64 %0, i64 64
+ ret i64 %cond
+}
+
+define i16 @test4b(i16 %x) {
+; CHECK-LABEL: @test4b(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
+; CHECK-NEXT: ret i16 [[VAR]]
+entry:
+ %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
+ %tobool = icmp eq i16 %x, 0
+ %cond = select i1 %tobool, i16 16, i16 %0
+ ret i16 %cond
+}
+
+define i32 @test5b(i32 %x) {
+; CHECK-LABEL: @test5b(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+; CHECK-NEXT: ret i32 [[VAR]]
+entry:
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %tobool = icmp eq i32 %x, 0
+ %cond = select i1 %tobool, i32 32, i32 %0
+ ret i32 %cond
+}
+
+define i64 @test6b(i64 %x) {
+; CHECK-LABEL: @test6b(
+; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
+; CHECK-NEXT: ret i64 [[VAR]]
+entry:
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %tobool = icmp eq i64 %x, 0
+ %cond = select i1 %tobool, i64 64, i64 %0
+ ret i64 %cond
+}
+
+define i32 @test1c(i16 %x) {
+; CHECK-LABEL: @test1c(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i32
+; CHECK-NEXT: ret i32 [[VAR2]]
+entry:
+ %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
+ %cast2 = zext i16 %0 to i32
+ %tobool = icmp ne i16 %x, 0
+ %cond = select i1 %tobool, i32 %cast2, i32 16
+ ret i32 %cond
+}
+
+define i64 @test2c(i16 %x) {
+; CHECK-LABEL: @test2c(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i64
+; CHECK-NEXT: ret i64 [[VAR2]]
+entry:
+ %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
+ %conv = zext i16 %0 to i64
+ %tobool = icmp ne i16 %x, 0
+ %cond = select i1 %tobool, i64 %conv, i64 16
+ ret i64 %cond
+}
+
+define i64 @test3c(i32 %x) {
+; CHECK-LABEL: @test3c(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
+; CHECK-NEXT: ret i64 [[VAR2]]
+entry:
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %conv = zext i32 %0 to i64
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i64 %conv, i64 32
+ ret i64 %cond
+}
+
+define i32 @test4c(i16 %x) {
+; CHECK-LABEL: @test4c(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i32
+; CHECK-NEXT: ret i32 [[VAR2]]
+entry:
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
+ %cast = zext i16 %0 to i32
+ %tobool = icmp ne i16 %x, 0
+ %cond = select i1 %tobool, i32 %cast, i32 16
+ ret i32 %cond
+}
+
+define i64 @test5c(i16 %x) {
+; CHECK-LABEL: @test5c(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i64
+; CHECK-NEXT: ret i64 [[VAR2]]
+entry:
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
+ %cast = zext i16 %0 to i64
+ %tobool = icmp ne i16 %x, 0
+ %cond = select i1 %tobool, i64 %cast, i64 16
+ ret i64 %cond
+}
+
+define i64 @test6c(i32 %x) {
+; CHECK-LABEL: @test6c(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
+; CHECK-NEXT: ret i64 [[VAR2]]
+entry:
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %cast = zext i32 %0 to i64
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i64 %cast, i64 32
+ ret i64 %cond
+}
+
+define i16 @test1d(i64 %x) {
+; CHECK-LABEL: @test1d(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i16
+; CHECK-NEXT: ret i16 [[VAR2]]
+entry:
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %conv = trunc i64 %0 to i16
+ %tobool = icmp ne i64 %x, 0
+ %cond = select i1 %tobool, i16 %conv, i16 64
+ ret i16 %cond
+}
+
+define i32 @test2d(i64 %x) {
+; CHECK-LABEL: @test2d(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i32
+; CHECK-NEXT: ret i32 [[VAR2]]
+entry:
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i32
+ %tobool = icmp ne i64 %x, 0
+ %cond = select i1 %tobool, i32 %cast, i32 64
+ ret i32 %cond
+}
+
+define i16 @test3d(i32 %x) {
+; CHECK-LABEL: @test3d(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
+; CHECK-NEXT: ret i16 [[VAR2]]
+entry:
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %cast = trunc i32 %0 to i16
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i16 %cast, i16 32
+ ret i16 %cond
+}
+
+define i16 @test4d(i64 %x) {
+; CHECK-LABEL: @test4d(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i16
+; CHECK-NEXT: ret i16 [[VAR2]]
+entry:
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i16
+ %tobool = icmp ne i64 %x, 0
+ %cond = select i1 %tobool, i16 %cast, i16 64
+ ret i16 %cond
+}
+
+define i32 @test5d(i64 %x) {
+; CHECK-LABEL: @test5d(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i32
+; CHECK-NEXT: ret i32 [[VAR2]]
+entry:
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i32
+ %tobool = icmp ne i64 %x, 0
+ %cond = select i1 %tobool, i32 %cast, i32 64
+ ret i32 %cond
+}
+
+define i16 @test6d(i32 %x) {
+; CHECK-LABEL: @test6d(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
+; CHECK-NEXT: ret i16 [[VAR2]]
+entry:
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %cast = trunc i32 %0 to i16
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i16 %cast, i16 32
+ ret i16 %cond
+}
+
+define i64 @select_bug1(i32 %x) {
+; CHECK-LABEL: @select_bug1(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
+; CHECK-NEXT: ret i64 [[VAR2]]
+entry:
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+ %conv = zext i32 %0 to i64
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i64 %conv, i64 32
+ ret i64 %cond
+}
+
+define i16 @select_bug2(i32 %x) {
+; CHECK-LABEL: @select_bug2(
+; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
+; CHECK-NEXT: ret i16 [[VAR2]]
+entry:
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
+ %conv = trunc i32 %0 to i16
+ %tobool = icmp ne i32 %x, 0
+ %cond = select i1 %tobool, i16 %conv, i16 32
+ ret i16 %cond
+}
+
+
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 6cf9f0f..a6a7aa9 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -308,6 +308,26 @@ define i32 @test16(i1 %C, i32* %P) {
; CHECK: ret i32 %V
}
+;; It may be legal to load from a null address in a non-zero address space
+define i32 @test16_neg(i1 %C, i32 addrspace(1)* %P) {
+ %P2 = select i1 %C, i32 addrspace(1)* %P, i32 addrspace(1)* null
+ %V = load i32 addrspace(1)* %P2
+ ret i32 %V
+; CHECK-LABEL: @test16_neg
+; CHECK-NEXT: %P2 = select i1 %C, i32 addrspace(1)* %P, i32 addrspace(1)* null
+; CHECK-NEXT: %V = load i32 addrspace(1)* %P2
+; CHECK: ret i32 %V
+}
+define i32 @test16_neg2(i1 %C, i32 addrspace(1)* %P) {
+ %P2 = select i1 %C, i32 addrspace(1)* null, i32 addrspace(1)* %P
+ %V = load i32 addrspace(1)* %P2
+ ret i32 %V
+; CHECK-LABEL: @test16_neg2
+; CHECK-NEXT: %P2 = select i1 %C, i32 addrspace(1)* null, i32 addrspace(1)* %P
+; CHECK-NEXT: %V = load i32 addrspace(1)* %P2
+; CHECK: ret i32 %V
+}
+
define i1 @test17(i32* %X, i1 %C) {
%R = select i1 %C, i32* %X, i32* null
%RV = icmp eq i32* %R, null
@@ -997,17 +1017,6 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_vector_of_2s(i32 %x, <2 x i32> %y) {
ret <2 x i32> %select
}
-; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
-; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8
-; CHECK-NEXT: ret i32 [[OR]]
-define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %or = or i32 %x, 8
- %or.x = select i1 %cmp, i32 %or, i32 %x
- ret i32 %or.x
-}
-
; CHECK-LABEL: @select_icmp_and_8_ne_0_xor_8(
; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
; CHECK-NEXT: ret i32 [[AND]]
@@ -1030,27 +1039,6 @@ define i32 @select_icmp_and_8_eq_0_xor_8(i32 %x) {
ret i32 %xor.x
}
-; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
-; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
-; CHECK-NEXT: ret i32 [[AND]]
-define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i32 %x, -9
- %x.and1 = select i1 %cmp, i32 %x, i32 %and1
- ret i32 %x.and1
-}
-
-; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
-; CHECK-NEXT: ret i32 %x
-define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i32 %x, -9
- %and1.x = select i1 %cmp, i32 %and1, i32 %x
- ret i32 %and1.x
-}
-
; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_xor_8(
; CHECK: select i1 %cmp, i64 %y, i64 %xor
define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
@@ -1061,16 +1049,6 @@ define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
ret i64 %y.xor
}
-; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
-; CHECK: select i1 %cmp, i64 %y, i64 %and1
-define i64 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i64 %y) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i64 %y, -9
- %y.and1 = select i1 %cmp, i64 %y, i64 %and1
- ret i64 %y.and1
-}
-
; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_xor_8(
; CHECK: select i1 %cmp, i64 %xor, i64 %y
define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) {
@@ -1081,16 +1059,6 @@ define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) {
ret i64 %xor.y
}
-; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_and_not_8(
-; CHECK: select i1 %cmp, i64 %and1, i64 %y
-define i64 @select_icmp_x_and_8_ne_0_y_and_not_8(i32 %x, i64 %y) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i64 %y, -9
- %and1.y = select i1 %cmp, i64 %and1, i64 %y
- ret i64 %and1.y
-}
-
; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_or_8(
; CHECK: xor i64 %1, 8
; CHECK: or i64 %2, %y
@@ -1102,6 +1070,39 @@ define i64 @select_icmp_x_and_8_ne_0_y_or_8(i32 %x, i64 %y) {
ret i64 %or.y
}
+; CHECK-LABEL: @select_icmp_and_2147483648_ne_0_xor_2147483648(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 2147483647
+; CHECK-NEXT: ret i32 [[AND]]
+define i32 @select_icmp_and_2147483648_ne_0_xor_2147483648(i32 %x) {
+ %and = and i32 %x, 2147483648
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i32 %x, 2147483648
+ %x.xor = select i1 %cmp, i32 %x, i32 %xor
+ ret i32 %x.xor
+}
+
+; CHECK-LABEL: @select_icmp_and_2147483648_eq_0_xor_2147483648(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, -2147483648
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_and_2147483648_eq_0_xor_2147483648(i32 %x) {
+ %and = and i32 %x, 2147483648
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i32 %x, 2147483648
+ %xor.x = select i1 %cmp, i32 %xor, i32 %x
+ ret i32 %xor.x
+}
+
+; CHECK-LABEL: @select_icmp_x_and_2147483648_ne_0_or_2147483648(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, -2147483648
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_x_and_2147483648_ne_0_or_2147483648(i32 %x) {
+ %and = and i32 %x, 2147483648
+ %cmp = icmp eq i32 %and, 0
+ %or = or i32 %x, 2147483648
+ %or.x = select i1 %cmp, i32 %or, i32 %x
+ ret i32 %or.x
+}
+
define i32 @test65(i64 %x) {
%1 = and i64 %x, 16
%2 = icmp ne i64 %1, 0
@@ -1256,7 +1257,7 @@ define i32 @test76(i1 %flag, i32* %x) {
ret i32 %v
}
-declare void @scribble_on_memory(i32*)
+declare void @scribble_on_i32(i32*)
define i32 @test77(i1 %flag, i32* %x) {
; The load here must not be speculated around the select. One side of the
@@ -1264,13 +1265,13 @@ define i32 @test77(i1 %flag, i32* %x) {
; load does.
; CHECK-LABEL: @test77(
; CHECK: %[[A:.*]] = alloca i32, align 1
-; CHECK: call void @scribble_on_memory(i32* %[[A]])
+; CHECK: call void @scribble_on_i32(i32* %[[A]])
; CHECK: store i32 0, i32* %x
; CHECK: %[[P:.*]] = select i1 %flag, i32* %[[A]], i32* %x
; CHECK: load i32* %[[P]]
%under_aligned = alloca i32, align 1
- call void @scribble_on_memory(i32* %under_aligned)
+ call void @scribble_on_i32(i32* %under_aligned)
store i32 0, i32* %x
%p = select i1 %flag, i32* %under_aligned, i32* %x
%v = load i32* %p
@@ -1327,8 +1328,8 @@ define i32 @test80(i1 %flag) {
entry:
%x = alloca i32
%y = alloca i32
- call void @scribble_on_memory(i32* %x)
- call void @scribble_on_memory(i32* %y)
+ call void @scribble_on_i32(i32* %x)
+ call void @scribble_on_i32(i32* %y)
%tmp = load i32* %x
store i32 %tmp, i32* %y
%p = select i1 %flag, i32* %x, i32* %y
@@ -1351,8 +1352,8 @@ entry:
%y = alloca i32
%x1 = bitcast float* %x to i32*
%y1 = bitcast i32* %y to float*
- call void @scribble_on_memory(i32* %x1)
- call void @scribble_on_memory(i32* %y)
+ call void @scribble_on_i32(i32* %x1)
+ call void @scribble_on_i32(i32* %y)
%tmp = load i32* %x1
store i32 %tmp, i32* %y
%p = select i1 %flag, float* %x, float* %y1
@@ -1377,11 +1378,145 @@ entry:
%y = alloca i32
%x1 = bitcast float* %x to i32*
%y1 = bitcast i32* %y to float*
- call void @scribble_on_memory(i32* %x1)
- call void @scribble_on_memory(i32* %y)
+ call void @scribble_on_i32(i32* %x1)
+ call void @scribble_on_i32(i32* %y)
%tmp = load float* %x
store float %tmp, float* %y1
%p = select i1 %flag, i32* %x1, i32* %y
%v = load i32* %p
ret i32 %v
}
+
+declare void @scribble_on_i64(i64*)
+declare void @scribble_on_i128(i128*)
+
+define i8* @test83(i1 %flag) {
+; Test that we can speculate the load around the select even though they use
+; differently typed pointers and requires inttoptr casts.
+; CHECK-LABEL: @test83(
+; CHECK: %[[X:.*]] = alloca i8*
+; CHECK-NEXT: %[[Y:.*]] = alloca i8*
+; CHECK-DAG: %[[X2:.*]] = bitcast i8** %[[X]] to i64*
+; CHECK-DAG: %[[Y2:.*]] = bitcast i8** %[[Y]] to i64*
+; CHECK: %[[V:.*]] = load i64* %[[X2]]
+; CHECK-NEXT: store i64 %[[V]], i64* %[[Y2]]
+; CHECK-NEXT: %[[C:.*]] = inttoptr i64 %[[V]] to i8*
+; CHECK-NEXT: ret i8* %[[S]]
+entry:
+ %x = alloca i8*
+ %y = alloca i64
+ %x1 = bitcast i8** %x to i64*
+ %y1 = bitcast i64* %y to i8**
+ call void @scribble_on_i64(i64* %x1)
+ call void @scribble_on_i64(i64* %y)
+ %tmp = load i64* %x1
+ store i64 %tmp, i64* %y
+ %p = select i1 %flag, i8** %x, i8** %y1
+ %v = load i8** %p
+ ret i8* %v
+}
+
+define i64 @test84(i1 %flag) {
+; Test that we can speculate the load around the select even though they use
+; differently typed pointers and requires a ptrtoint cast.
+; CHECK-LABEL: @test84(
+; CHECK: %[[X:.*]] = alloca i8*
+; CHECK-NEXT: %[[Y:.*]] = alloca i8*
+; CHECK: %[[V:.*]] = load i8** %[[X]]
+; CHECK-NEXT: store i8* %[[V]], i8** %[[Y]]
+; CHECK-NEXT: %[[C:.*]] = ptrtoint i8* %[[V]] to i64
+; CHECK-NEXT: ret i64 %[[C]]
+entry:
+ %x = alloca i8*
+ %y = alloca i64
+ %x1 = bitcast i8** %x to i64*
+ %y1 = bitcast i64* %y to i8**
+ call void @scribble_on_i64(i64* %x1)
+ call void @scribble_on_i64(i64* %y)
+ %tmp = load i8** %x
+ store i8* %tmp, i8** %y1
+ %p = select i1 %flag, i64* %x1, i64* %y
+ %v = load i64* %p
+ ret i64 %v
+}
+
+define i8* @test85(i1 %flag) {
+; Test that we can't speculate the load around the select. The load of the
+; pointer doesn't load all of the stored integer bits. We could fix this, but it
+; would require endianness checks and other nastiness.
+; CHECK-LABEL: @test85(
+; CHECK: %[[T:.*]] = load i128*
+; CHECK-NEXT: store i128 %[[T]], i128*
+; CHECK-NEXT: %[[X:.*]] = load i8**
+; CHECK-NEXT: %[[Y:.*]] = load i8**
+; CHECK-NEXT: %[[V:.*]] = select i1 %flag, i8* %[[X]], i8* %[[Y]]
+; CHECK-NEXT: ret i8* %[[V]]
+entry:
+ %x = alloca [2 x i8*]
+ %y = alloca i128
+ %x1 = bitcast [2 x i8*]* %x to i8**
+ %x2 = bitcast i8** %x1 to i128*
+ %y1 = bitcast i128* %y to i8**
+ call void @scribble_on_i128(i128* %x2)
+ call void @scribble_on_i128(i128* %y)
+ %tmp = load i128* %x2
+ store i128 %tmp, i128* %y
+ %p = select i1 %flag, i8** %x1, i8** %y1
+ %v = load i8** %p
+ ret i8* %v
+}
+
+define i128 @test86(i1 %flag) {
+; Test that we can't speculate the load around the select when the integer size
+; is larger than the pointer size. The store of the pointer doesn't store to all
+; the bits of the integer.
+;
+; CHECK-LABEL: @test86(
+; CHECK: %[[T:.*]] = load i8**
+; CHECK-NEXT: store i8* %[[T]], i8**
+; CHECK-NEXT: %[[X:.*]] = load i128*
+; CHECK-NEXT: %[[Y:.*]] = load i128*
+; CHECK-NEXT: %[[V:.*]] = select i1 %flag, i128 %[[X]], i128 %[[Y]]
+; CHECK-NEXT: ret i128 %[[V]]
+entry:
+ %x = alloca [2 x i8*]
+ %y = alloca i128
+ %x1 = bitcast [2 x i8*]* %x to i8**
+ %x2 = bitcast i8** %x1 to i128*
+ %y1 = bitcast i128* %y to i8**
+ call void @scribble_on_i128(i128* %x2)
+ call void @scribble_on_i128(i128* %y)
+ %tmp = load i8** %x1
+ store i8* %tmp, i8** %y1
+ %p = select i1 %flag, i128* %x2, i128* %y
+ %v = load i128* %p
+ ret i128 %v
+}
+
+define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
+ ; CHECK-LABEL: @test_select_select0(
+ ; CHECK: %[[C0:.*]] = icmp sge i32 %a, %v1
+ ; CHECK-NEXT: %[[C1:.*]] = icmp slt i32 %a, %v2
+ ; CHECK-NEXT: %[[C:.*]] = and i1 %[[C1]], %[[C0]]
+ ; CHECK-NEXT: %[[SEL:.*]] = select i1 %[[C]], i32 %r0, i32 %r1
+ ; CHECK-NEXT: ret i32 %[[SEL]]
+ %c0 = icmp sge i32 %a, %v1
+ %s0 = select i1 %c0, i32 %r0, i32 %r1
+ %c1 = icmp slt i32 %a, %v2
+ %s1 = select i1 %c1, i32 %s0, i32 %r1
+ ret i32 %s1
+}
+
+define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
+ ; CHECK-LABEL: @test_select_select1(
+ ; CHECK: %[[C0:.*]] = icmp sge i32 %a, %v1
+ ; CHECK-NEXT: %[[C1:.*]] = icmp slt i32 %a, %v2
+ ; CHECK-NEXT: %[[C:.*]] = or i1 %[[C1]], %[[C0]]
+ ; CHECK-NEXT: %[[SEL:.*]] = select i1 %[[C]], i32 %r0, i32 %r1
+ ; CHECK-NEXT: ret i32 %[[SEL]]
+ %c0 = icmp sge i32 %a, %v1
+ %s0 = select i1 %c0, i32 %r0, i32 %r1
+ %c1 = icmp slt i32 %a, %v2
+ %s1 = select i1 %c1, i32 %r0, i32 %s0
+ ret i32 %s1
+}
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll
index 5586bb6..0b5b5de 100644
--- a/test/Transforms/InstCombine/shift.ll
+++ b/test/Transforms/InstCombine/shift.ll
@@ -57,7 +57,7 @@ define <4 x i32> @test5_zero_vector(<4 x i32> %A) {
define <4 x i32> @test5_non_splat_vector(<4 x i32> %A) {
; CHECK-LABEL: @test5_non_splat_vector(
; CHECK-NOT: ret <4 x i32> undef
- %B = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
+ %B = lshr <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
ret <4 x i32> %B
}
@@ -84,14 +84,14 @@ define <4 x i32> @test5a_non_splat_vector(<4 x i32> %A) {
define i32 @test5b() {
; CHECK-LABEL: @test5b(
-; CHECK: ret i32 -1
+; CHECK: ret i32 0
%B = ashr i32 undef, 2 ;; top two bits must be equal, so not undef
ret i32 %B
}
define i32 @test5b2(i32 %A) {
; CHECK-LABEL: @test5b2(
-; CHECK: ret i32 -1
+; CHECK: ret i32 0
%B = ashr i32 undef, %A ;; top %A bits must be equal, so not undef
ret i32 %B
}
@@ -738,67 +738,49 @@ define i32 @test56(i32 %x) {
define i32 @test57(i32 %x) {
- %shr = lshr i32 %x, 1
- %shl = shl i32 %shr, 4
- %and = and i32 %shl, 16
- ret i32 %and
-; CHECK-LABEL: @test57(
-; CHECK: shl i32 %x, 3
-}
-
-define i32 @test58(i32 %x) {
- %shr = lshr i32 %x, 1
- %shl = shl i32 %shr, 4
- %or = or i32 %shl, 8
- ret i32 %or
-; CHECK-LABEL: @test58(
-; CHECK: shl i32 %x, 3
-}
-
-define i32 @test59(i32 %x) {
%shr = ashr i32 %x, 1
%shl = shl i32 %shr, 4
%or = or i32 %shl, 7
ret i32 %or
-; CHECK-LABEL: @test59(
+; CHECK-LABEL: @test57(
; CHECK: %shl = shl i32 %shr1, 4
}
-define i32 @test60(i32 %x) {
+define i32 @test58(i32 %x) {
%shr = ashr i32 %x, 4
%shl = shl i32 %shr, 1
%or = or i32 %shl, 1
ret i32 %or
-; CHECK-LABEL: @test60(
+; CHECK-LABEL: @test58(
; CHECK: ashr i32 %x, 3
}
-define i32 @test61(i32 %x) {
+define i32 @test59(i32 %x) {
%shr = ashr i32 %x, 4
%shl = shl i32 %shr, 1
%or = or i32 %shl, 2
ret i32 %or
-; CHECK-LABEL: @test61(
+; CHECK-LABEL: @test59(
; CHECK: ashr i32 %x, 4
}
; propagate "exact" trait
-define i32 @test62(i32 %x) {
+define i32 @test60(i32 %x) {
%shr = ashr exact i32 %x, 4
%shl = shl i32 %shr, 1
%or = or i32 %shl, 1
ret i32 %or
-; CHECK-LABEL: @test62(
+; CHECK-LABEL: @test60(
; CHECK: ashr exact i32 %x, 3
}
; PR17026
-; CHECK-LABEL: @test63(
+; CHECK-LABEL: @test61(
; CHECK-NOT: sh
; CHECK: ret
-define void @test63(i128 %arg) {
+define void @test61(i128 %arg) {
bb:
br i1 undef, label %bb1, label %bb12
@@ -830,29 +812,29 @@ bb12: ; preds = %bb11, %bb8, %bb
ret void
}
-define i32 @test64(i32 %a) {
-; CHECK-LABEL: @test64(
+define i32 @test62(i32 %a) {
+; CHECK-LABEL: @test62(
; CHECK-NEXT: ret i32 undef
%b = ashr i32 %a, 32 ; shift all bits out
ret i32 %b
}
-define <4 x i32> @test64_splat_vector(<4 x i32> %a) {
-; CHECK-LABEL: @test64_splat_vector
+define <4 x i32> @test62_splat_vector(<4 x i32> %a) {
+; CHECK-LABEL: @test62_splat_vector
; CHECK-NEXT: ret <4 x i32> undef
%b = ashr <4 x i32> %a, <i32 32, i32 32, i32 32, i32 32> ; shift all bits out
ret <4 x i32> %b
}
-define <4 x i32> @test64_non_splat_vector(<4 x i32> %a) {
-; CHECK-LABEL: @test64_non_splat_vector
+define <4 x i32> @test62_non_splat_vector(<4 x i32> %a) {
+; CHECK-LABEL: @test62_non_splat_vector
; CHECK-NOT: ret <4 x i32> undef
%b = ashr <4 x i32> %a, <i32 32, i32 0, i32 1, i32 2> ; shift all bits out
ret <4 x i32> %b
}
-define <2 x i65> @test_65(<2 x i64> %t) {
-; CHECK-LABEL: @test_65
+define <2 x i65> @test_63(<2 x i64> %t) {
+; CHECK-LABEL: @test_63
%a = zext <2 x i64> %t to <2 x i65>
%sext = shl <2 x i65> %a, <i65 33, i65 33>
%b = ashr <2 x i65> %sext, <i65 33, i65 33>
diff --git a/test/Transforms/InstCombine/signext.ll b/test/Transforms/InstCombine/signext.ll
index d700497..3a714d7 100644
--- a/test/Transforms/InstCombine/signext.ll
+++ b/test/Transforms/InstCombine/signext.ll
@@ -34,54 +34,45 @@ define i32 @test3(i16 %P) {
; CHECK: ret i32 %tmp.5
}
-define i32 @test4(i16 %P) {
- %tmp.1 = zext i16 %P to i32 ; <i32> [#uses=1]
- %tmp.4 = xor i32 %tmp.1, 32768 ; <i32> [#uses=1]
- %tmp.5 = add i32 %tmp.4, -32768 ; <i32> [#uses=1]
- ret i32 %tmp.5
-; CHECK-LABEL: @test4(
-; CHECK: %tmp.5 = sext i16 %P to i32
-; CHECK: ret i32 %tmp.5
-}
-
-define i32 @test5(i32 %x) {
+define i32 @test4(i32 %x) {
%tmp.1 = and i32 %x, 255 ; <i32> [#uses=1]
%tmp.2 = xor i32 %tmp.1, 128 ; <i32> [#uses=1]
%tmp.3 = add i32 %tmp.2, -128 ; <i32> [#uses=1]
ret i32 %tmp.3
-; CHECK-LABEL: @test5(
+; CHECK-LABEL: @test4(
; CHECK: %sext = shl i32 %x, 24
; CHECK: %tmp.3 = ashr exact i32 %sext, 24
; CHECK: ret i32 %tmp.3
}
-define i32 @test6(i32 %x) {
+define i32 @test5(i32 %x) {
%tmp.2 = shl i32 %x, 16 ; <i32> [#uses=1]
%tmp.4 = ashr i32 %tmp.2, 16 ; <i32> [#uses=1]
ret i32 %tmp.4
-; CHECK-LABEL: @test6(
+; CHECK-LABEL: @test5(
; CHECK: %tmp.2 = shl i32 %x, 16
; CHECK: %tmp.4 = ashr exact i32 %tmp.2, 16
; CHECK: ret i32 %tmp.4
}
-define i32 @test7(i16 %P) {
+define i32 @test6(i16 %P) {
%tmp.1 = zext i16 %P to i32 ; <i32> [#uses=1]
%sext1 = shl i32 %tmp.1, 16 ; <i32> [#uses=1]
%tmp.5 = ashr i32 %sext1, 16 ; <i32> [#uses=1]
ret i32 %tmp.5
-; CHECK-LABEL: @test7(
+; CHECK-LABEL: @test6(
; CHECK: %tmp.5 = sext i16 %P to i32
; CHECK: ret i32 %tmp.5
}
-define i32 @test8(i32 %x) nounwind readnone {
+define i32 @test7(i32 %x) nounwind readnone {
entry:
%shr = lshr i32 %x, 5 ; <i32> [#uses=1]
%xor = xor i32 %shr, 67108864 ; <i32> [#uses=1]
%sub = add i32 %xor, -67108864 ; <i32> [#uses=1]
ret i32 %sub
-; CHECK-LABEL: @test8(
+; CHECK-LABEL: @test7(
; CHECK: %sub = ashr i32 %x, 5
; CHECK: ret i32 %sub
}
+
diff --git a/test/Transforms/InstCombine/sitofp.ll b/test/Transforms/InstCombine/sitofp.ll
index bd31b89..8209778 100644
--- a/test/Transforms/InstCombine/sitofp.ll
+++ b/test/Transforms/InstCombine/sitofp.ll
@@ -1,28 +1,40 @@
-; RUN: opt < %s -instcombine -S | not grep itofp
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; CHECK-LABEL: test1
+; CHECK: ret i1 true
define i1 @test1(i8 %A) {
%B = sitofp i8 %A to double
%C = fcmp ult double %B, 128.0
- ret i1 %C ; True!
+ ret i1 %C
}
+
+; CHECK-LABEL: test2
+; CHECK: ret i1 true
define i1 @test2(i8 %A) {
%B = sitofp i8 %A to double
%C = fcmp ugt double %B, -128.1
- ret i1 %C ; True!
+ ret i1 %C
}
+; CHECK-LABEL: test3
+; CHECK: ret i1 true
define i1 @test3(i8 %A) {
%B = sitofp i8 %A to double
%C = fcmp ule double %B, 127.0
- ret i1 %C ; true!
+ ret i1 %C
}
+; CHECK-LABEL: test4
+; CHECK: icmp ne i8 %A, 127
+; CHECK-NEXT: ret i1
define i1 @test4(i8 %A) {
%B = sitofp i8 %A to double
%C = fcmp ult double %B, 127.0
- ret i1 %C ; A != 127
+ ret i1 %C
}
+; CHECK-LABEL: test5
+; CHECK: ret i32
define i32 @test5(i32 %A) {
%B = sitofp i32 %A to double
%C = fptosi double %B to i32
@@ -31,25 +43,142 @@ define i32 @test5(i32 %A) {
ret i32 %E
}
+; CHECK-LABEL: test6
+; CHECK: and i32 %A, 39
+; CHECK-NEXT: ret i32
define i32 @test6(i32 %A) {
- %B = and i32 %A, 7 ; <i32> [#uses=1]
- %C = and i32 %A, 32 ; <i32> [#uses=1]
- %D = sitofp i32 %B to double ; <double> [#uses=1]
- %E = sitofp i32 %C to double ; <double> [#uses=1]
- %F = fadd double %D, %E ; <double> [#uses=1]
- %G = fptosi double %F to i32 ; <i32> [#uses=1]
- ret i32 %G
+ %B = and i32 %A, 7
+ %C = and i32 %A, 32
+ %D = sitofp i32 %B to double
+ %E = sitofp i32 %C to double
+ %F = fadd double %D, %E
+ %G = fptosi double %F to i32
+ ret i32 %G
+}
+
+; CHECK-LABEL: test7
+; CHECK: ret i32
+define i32 @test7(i32 %A) nounwind {
+ %B = sitofp i32 %A to double
+ %C = fptoui double %B to i32
+ ret i32 %C
+}
+
+; CHECK-LABEL: test8
+; CHECK: ret i32
+define i32 @test8(i32 %A) nounwind {
+ %B = uitofp i32 %A to double
+ %C = fptosi double %B to i32
+ ret i32 %C
+}
+
+; CHECK-LABEL: test9
+; CHECK: zext i8
+; CHECK-NEXT: ret i32
+define i32 @test9(i8 %A) nounwind {
+ %B = sitofp i8 %A to float
+ %C = fptoui float %B to i32
+ ret i32 %C
+}
+
+; CHECK-LABEL: test10
+; CHECK: sext i8
+; CHECK-NEXT: ret i32
+define i32 @test10(i8 %A) nounwind {
+ %B = sitofp i8 %A to float
+ %C = fptosi float %B to i32
+ ret i32 %C
+}
+
+; If the input value is outside of the range of the output cast, it's
+; undefined behavior, so we can assume it fits.
+; CHECK-LABEL: test11
+; CHECK: trunc
+; CHECK-NEXT: ret i8
+define i8 @test11(i32 %A) nounwind {
+ %B = sitofp i32 %A to float
+ %C = fptosi float %B to i8
+ ret i8 %C
+}
+
+; If the input value is negative, it'll be outside the range of the
+; output cast, and thus undefined behavior.
+; CHECK-LABEL: test12
+; CHECK: zext i8
+; CHECK-NEXT: ret i32
+define i32 @test12(i8 %A) nounwind {
+ %B = sitofp i8 %A to float
+ %C = fptoui float %B to i32
+ ret i32 %C
+}
+
+; This can't fold because the 25-bit input doesn't fit in the mantissa.
+; CHECK-LABEL: test13
+; CHECK: uitofp
+; CHECK-NEXT: fptoui
+define i32 @test13(i25 %A) nounwind {
+ %B = uitofp i25 %A to float
+ %C = fptoui float %B to i32
+ ret i32 %C
+}
+
+; But this one can.
+; CHECK-LABEL: test14
+; CHECK: zext i24
+; CHECK-NEXT: ret i32
+define i32 @test14(i24 %A) nounwind {
+ %B = uitofp i24 %A to float
+ %C = fptoui float %B to i32
+ ret i32 %C
+}
+
+; And this one can too.
+; CHECK-LABEL: test15
+; CHECK: trunc i32
+; CHECK-NEXT: ret i24
+define i24 @test15(i32 %A) nounwind {
+ %B = uitofp i32 %A to float
+ %C = fptoui float %B to i24
+ ret i24 %C
+}
+
+; This can fold because the 25-bit input is signed and we disard the sign bit.
+; CHECK-LABEL: test16
+; CHECK: zext
+define i32 @test16(i25 %A) nounwind {
+ %B = sitofp i25 %A to float
+ %C = fptoui float %B to i32
+ ret i32 %C
+}
+
+; This can't fold because the 26-bit input won't fit the mantissa
+; even after disarding the signed bit.
+; CHECK-LABEL: test17
+; CHECK: sitofp
+; CHECK-NEXT: fptoui
+define i32 @test17(i26 %A) nounwind {
+ %B = sitofp i26 %A to float
+ %C = fptoui float %B to i32
+ ret i32 %C
}
-define i32 @test7(i32 %a) nounwind {
- %b = sitofp i32 %a to double ; <double> [#uses=1]
- %c = fptoui double %b to i32 ; <i32> [#uses=1]
- ret i32 %c
+; This can fold because the 54-bit output is signed and we disard the sign bit.
+; CHECK-LABEL: test18
+; CHECK: trunc
+define i54 @test18(i64 %A) nounwind {
+ %B = sitofp i64 %A to double
+ %C = fptosi double %B to i54
+ ret i54 %C
}
-define i32 @test8(i32 %a) nounwind {
- %b = uitofp i32 %a to double ; <double> [#uses=1]
- %c = fptosi double %b to i32 ; <i32> [#uses=1]
- ret i32 %c
+; This can't fold because the 55-bit output won't fit the mantissa
+; even after disarding the sign bit.
+; CHECK-LABEL: test19
+; CHECK: sitofp
+; CHECK-NEXT: fptosi
+define i55 @test19(i64 %A) nounwind {
+ %B = sitofp i64 %A to double
+ %C = fptosi double %B to i55
+ ret i55 %C
}
diff --git a/test/Transforms/InstCombine/statepoint.ll b/test/Transforms/InstCombine/statepoint.ll
new file mode 100644
index 0000000..bee219d
--- /dev/null
+++ b/test/Transforms/InstCombine/statepoint.ll
@@ -0,0 +1,52 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; These tests check the optimizations specific to
+; pointers being relocated at a statepoint.
+
+
+declare void @func()
+
+define i1 @test_negative(i32 addrspace(1)* %p) {
+entry:
+ %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
+ %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4)
+ %cmp = icmp eq i32 addrspace(1)* %pnew, null
+ ret i1 %cmp
+; CHECK-LABEL: test_negative
+; CHECK: %pnew = call i32 addrspace(1)*
+; CHECK: ret i1 %cmp
+}
+
+define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) {
+entry:
+ %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* %p)
+ %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4)
+ %cmp = icmp eq i32 addrspace(1)* %pnew, null
+ ret i1 %cmp
+; CHECK-LABEL: test_nonnull
+; CHECK: ret i1 false
+}
+
+define i1 @test_null() {
+entry:
+ %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* null)
+ %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4)
+ %cmp = icmp eq i32 addrspace(1)* %pnew, null
+ ret i1 %cmp
+; CHECK-LABEL: test_null
+; CHECK-NOT: %pnew
+; CHECK: ret i1 true
+}
+
+define i1 @test_undef() {
+entry:
+ %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* undef)
+ %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4)
+ %cmp = icmp eq i32 addrspace(1)* %pnew, null
+ ret i1 %cmp
+; CHECK-LABEL: test_undef
+; CHECK-NOT: %pnew
+; CHECK: ret i1 undef
+}
+
+declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
+declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
diff --git a/test/Transforms/InstCombine/store.ll b/test/Transforms/InstCombine/store.ll
index b64c800..0bb1759 100644
--- a/test/Transforms/InstCombine/store.ll
+++ b/test/Transforms/InstCombine/store.ll
@@ -113,8 +113,8 @@ for.end: ; preds = %for.cond
; CHECK-NEXT: store i32 %storemerge, i32* %gi, align 4, !tbaa !0
}
-!0 = metadata !{metadata !4, metadata !4, i64 0}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA"}
-!3 = metadata !{metadata !"float", metadata !1}
-!4 = metadata !{metadata !"int", metadata !1}
+!0 = !{!4, !4, i64 0}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"float", !1}
+!4 = !{!"int", !1}
diff --git a/test/Transforms/InstCombine/stpcpy_chk-1.ll b/test/Transforms/InstCombine/stpcpy_chk-1.ll
index 8a02529..393c5d9 100644
--- a/test/Transforms/InstCombine/stpcpy_chk-1.ll
+++ b/test/Transforms/InstCombine/stpcpy_chk-1.ll
@@ -11,46 +11,50 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
; Check cases where slen >= strlen (src).
-define void @test_simplify1() {
+define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11)
+ %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
+ ret i8* %ret
}
-define void @test_simplify2() {
+define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11)
+ %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
+ ret i8* %ret
}
-define void @test_simplify3() {
+define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11)
+ %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
+ ret i8* %ret
}
; Check cases where there are no string constants.
-define void @test_simplify4() {
+define i8* @test_simplify4() {
; CHECK-LABEL: @test_simplify4(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
-; CHECK-NEXT: call i8* @stpcpy
- call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
- ret void
+; CHECK-NEXT: %stpcpy = call i8* @stpcpy(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0, i32 0))
+; CHECK-NEXT: ret i8* %stpcpy
+ %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
+ ret i8* %ret
}
; Check case where the string length is not constant.
@@ -60,10 +64,11 @@ define i8* @test_simplify5() {
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK: @__memcpy_chk
+; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 %len)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11)
%len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
-; CHECK: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11)
ret i8* %ret
}
@@ -73,8 +78,9 @@ define i8* @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
-; CHECK: [[LEN:%[a-z]+]] = call i32 @strlen
-; CHECK-NEXT: getelementptr inbounds [60 x i8]* @a, i32 0, i32 [[LEN]]
+; CHECK-NEXT: %strlen = call i32 @strlen(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0))
+; CHECK-NEXT: %1 = getelementptr inbounds [60 x i8]* @a, i32 0, i32 %strlen
+; CHECK-NEXT: ret i8* %1
%len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
ret i8* %ret
@@ -82,14 +88,15 @@ define i8* @test_simplify6() {
; Check case where slen < strlen (src).
-define void @test_no_simplify1() {
+define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
-; CHECK-NEXT: call i8* @__stpcpy_chk
- call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
- ret void
+; CHECK-NEXT: %ret = call i8* @__stpcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0, i32 0), i32 8)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
+ ret i8* %ret
}
declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
diff --git a/test/Transforms/InstCombine/strcpy_chk-1.ll b/test/Transforms/InstCombine/strcpy_chk-1.ll
index 8e7fec7..e3f163f 100644
--- a/test/Transforms/InstCombine/strcpy_chk-1.ll
+++ b/test/Transforms/InstCombine/strcpy_chk-1.ll
@@ -11,59 +11,65 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
; Check cases where slen >= strlen (src).
-define void @test_simplify1() {
+define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
+ %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60)
+ ret i8* %ret
}
-define void @test_simplify2() {
+define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
+ %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12)
+ ret i8* %ret
}
-define void @test_simplify3() {
+define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
+ %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
+ ret i8* %ret
}
; Check cases where there are no string constants.
-define void @test_simplify4() {
+define i8* @test_simplify4() {
; CHECK-LABEL: @test_simplify4(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
-; CHECK-NEXT: call i8* @strcpy
- call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
- ret void
+; CHECK-NEXT: %strcpy = call i8* @strcpy(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0, i32 0))
+; CHECK-NEXT: ret i8* %strcpy
+ %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
+ ret i8* %ret
}
; Check case where the string length is not constant.
-define void @test_simplify5() {
+define i8* @test_simplify5() {
; CHECK-LABEL: @test_simplify5(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK: @__memcpy_chk
+; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 %len)
+; CHECK-NEXT: ret i8* %1
%len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
- call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
- ret void
+ %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
+ ret i8* %ret
}
; Check case where the source and destination are the same.
@@ -72,7 +78,9 @@ define i8* @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
-; CHECK: getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
+; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i32 %len)
+; CHECK-NEXT: ret i8* %ret
%len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
%ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len)
ret i8* %ret
@@ -80,14 +88,15 @@ define i8* @test_simplify6() {
; Check case where slen < strlen (src).
-define void @test_no_simplify1() {
+define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
-; CHECK-NEXT: call i8* @__strcpy_chk
- call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 8)
- ret void
+; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0, i32 0), i32 8)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 8)
+ ret i8* %ret
}
declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
diff --git a/test/Transforms/InstCombine/strncpy_chk-1.ll b/test/Transforms/InstCombine/strncpy_chk-1.ll
index 90b4173..9242a8a 100644
--- a/test/Transforms/InstCombine/strncpy_chk-1.ll
+++ b/test/Transforms/InstCombine/strncpy_chk-1.ll
@@ -11,56 +11,61 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
; Check cases where dstlen >= len
-define void @test_simplify1() {
+define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
+ %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
+ ret i8* %ret
}
-define void @test_simplify2() {
+define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
- call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12)
- ret void
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
+; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
+ %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12)
+ ret i8* %ret
}
-define void @test_simplify3() {
+define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
-; CHECK-NEXT: call i8* @strncpy
- call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
- ret void
+; CHECK-NEXT: %strncpy = call i8* @strncpy(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0, i32 0), i32 12)
+; CHECK-NEXT: ret i8* %strncpy
+ %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
+ ret i8* %ret
}
; Check cases where dstlen < len
-define void @test_no_simplify1() {
+define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
-; CHECK-NEXT: call i8* @__strncpy_chk
- call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4)
- ret void
+; CHECK-NEXT: %ret = call i8* @__strncpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 8, i32 4)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4)
+ ret i8* %ret
}
-define void @test_no_simplify2() {
+define i8* @test_no_simplify2() {
; CHECK-LABEL: @test_no_simplify2(
%dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
-; CHECK-NEXT: call i8* @__strncpy_chk
- call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0)
- ret void
+; CHECK-NEXT: %ret = call i8* @__strncpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0, i32 0), i32 8, i32 0)
+; CHECK-NEXT: ret i8* %ret
+ %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0)
+ ret i8* %ret
}
declare i8* @__strncpy_chk(i8*, i8*, i32, i32)
diff --git a/test/Transforms/InstCombine/struct-assign-tbaa.ll b/test/Transforms/InstCombine/struct-assign-tbaa.ll
index c80e31a..e949640 100644
--- a/test/Transforms/InstCombine/struct-assign-tbaa.ll
+++ b/test/Transforms/InstCombine/struct-assign-tbaa.ll
@@ -10,8 +10,8 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32,
%struct.test1 = type { float }
; CHECK: @test
-; CHECK: %2 = load float* %0, align 4, !tbaa !0
-; CHECK: store float %2, float* %1, align 4, !tbaa !0
+; CHECK: %[[LOAD:.*]] = load i32* %{{.*}}, align 4, !tbaa !0
+; CHECK: store i32 %[[LOAD:.*]], i32* %{{.*}}, align 4, !tbaa !0
; CHECK: ret
define void @test1(%struct.test1* nocapture %a, %struct.test1* nocapture %b) {
entry:
@@ -35,12 +35,12 @@ define i32 (i8*, i32*, double*)*** @test2() {
ret i32 (i8*, i32*, double*)*** %tmp2
}
-; CHECK: !0 = metadata !{metadata !1, metadata !1, i64 0}
-; CHECK: !1 = metadata !{metadata !"float", metadata !2}
+; CHECK: !0 = !{!1, !1, i64 0}
+; CHECK: !1 = !{!"float", !2}
-!0 = metadata !{metadata !"Simple C/C++ TBAA"}
-!1 = metadata !{metadata !"omnipotent char", metadata !0}
-!2 = metadata !{metadata !5, metadata !5, i64 0}
-!3 = metadata !{i64 0, i64 4, metadata !2}
-!4 = metadata !{i64 0, i64 8, null}
-!5 = metadata !{metadata !"float", metadata !0}
+!0 = !{!"Simple C/C++ TBAA"}
+!1 = !{!"omnipotent char", !0}
+!2 = !{!5, !5, i64 0}
+!3 = !{i64 0, i64 4, !2}
+!4 = !{i64 0, i64 8, null}
+!5 = !{!"float", !0}
diff --git a/test/Transforms/InstCombine/type_pun.ll b/test/Transforms/InstCombine/type_pun.ll
new file mode 100644
index 0000000..33143ef
--- /dev/null
+++ b/test/Transforms/InstCombine/type_pun.ll
@@ -0,0 +1,137 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; Ensure that type punning using a union of vector and same-sized array
+; generates an extract instead of a shuffle with an uncommon vector size:
+;
+; typedef uint32_t v4i32 __attribute__((vector_size(16)));
+; union { v4i32 v; uint32_t a[4]; };
+;
+; This cleans up behind SROA, which inserts the uncommon vector size when
+; cleaning up the alloca/store/GEP/load.
+
+
+; Extracting the zeroth element in an i32 array.
+define i32 @type_pun_zeroth(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_zeroth(
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
+; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 0
+; CHECK-NEXT: ret i32 %[[EXT]]
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %1 = bitcast <4 x i8> %sroa to i32
+ ret i32 %1
+}
+
+; Extracting the first element in an i32 array.
+define i32 @type_pun_first(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_first(
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
+; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 1
+; CHECK-NEXT: ret i32 %[[EXT]]
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+ %1 = bitcast <4 x i8> %sroa to i32
+ ret i32 %1
+}
+
+; Extracting an i32 that isn't aligned to any natural boundary.
+define i32 @type_pun_misaligned(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_misaligned(
+; CHECK-NEXT: %[[SHUF:.*]] = shufflevector <16 x i8> %in, <16 x i8> undef, <16 x i32> <i32 6, i32 7, i32 8, i32 9, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %[[SHUF]] to <4 x i32>
+; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 0
+; CHECK-NEXT: ret i32 %[[EXT]]
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 6, i32 7, i32 8, i32 9>
+ %1 = bitcast <4 x i8> %sroa to i32
+ ret i32 %1
+}
+
+; Type punning to an array of pointers.
+define i32* @type_pun_pointer(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_pointer(
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
+; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x i32> %[[BC]], i32 0
+; CHECK-NEXT: %[[I2P:.*]] = inttoptr i32 %[[EXT]] to i32*
+; CHECK-NEXT: ret i32* %[[I2P]]
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %1 = bitcast <4 x i8> %sroa to i32
+ %2 = inttoptr i32 %1 to i32*
+ ret i32* %2
+}
+
+; Type punning to an array of 32-bit floating-point values.
+define float @type_pun_float(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_float(
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x float>
+; CHECK-NEXT: %[[EXT:.*]] = extractelement <4 x float> %[[BC]], i32 0
+; CHECK-NEXT: ret float %[[EXT]]
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %1 = bitcast <4 x i8> %sroa to float
+ ret float %1
+}
+
+; Type punning to an array of 64-bit floating-point values.
+define double @type_pun_double(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_double(
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <2 x double>
+; CHECK-NEXT: %[[EXT:.*]] = extractelement <2 x double> %[[BC]], i32 0
+; CHECK-NEXT: ret double %[[EXT]]
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+ %1 = bitcast <8 x i8> %sroa to double
+ ret double %1
+}
+
+; Type punning to same-size floating-point and integer values.
+; Verify that multiple uses with different bitcast types are properly handled.
+define { float, i32 } @type_pun_float_i32(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_float_i32(
+; CHECK-NEXT: %[[BCI:.*]] = bitcast <16 x i8> %in to <4 x i32>
+; CHECK-NEXT: %[[EXTI:.*]] = extractelement <4 x i32> %[[BCI]], i32 0
+; CHECK-NEXT: %[[BCF:.*]] = bitcast <16 x i8> %in to <4 x float>
+; CHECK-NEXT: %[[EXTF:.*]] = extractelement <4 x float> %[[BCF]], i32 0
+; CHECK-NEXT: %1 = insertvalue { float, i32 } undef, float %[[EXTF]], 0
+; CHECK-NEXT: %2 = insertvalue { float, i32 } %1, i32 %[[EXTI]], 1
+; CHECK-NEXT: ret { float, i32 } %2
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %f = bitcast <4 x i8> %sroa to float
+ %i = bitcast <4 x i8> %sroa to i32
+ %1 = insertvalue { float, i32 } undef, float %f, 0
+ %2 = insertvalue { float, i32 } %1, i32 %i, 1
+ ret { float, i32 } %2
+}
+
+; Type punning two i32 values, with control flow.
+; Verify that the bitcast is shared and dominates usage.
+define i32 @type_pun_i32_ctrl(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_i32_ctrl(
+entry: ; CHECK-NEXT: entry:
+; CHECK-NEXT: %[[BC:.*]] = bitcast <16 x i8> %in to <4 x i32>
+; CHECK-NEXT: br
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ br i1 undef, label %left, label %right
+left: ; CHECK: left:
+; CHECK-NEXT: %[[EXTL:.*]] = extractelement <4 x i32> %[[BC]], i32 0
+; CHECK-NEXT: br
+ %lhs = bitcast <4 x i8> %sroa to i32
+ br label %tail
+right: ; CHECK: right:
+; CHECK-NEXT: %[[EXTR:.*]] = extractelement <4 x i32> %[[BC]], i32 0
+; CHECK-NEXT: br
+ %rhs = bitcast <4 x i8> %sroa to i32
+ br label %tail
+tail: ; CHECK: tail:
+; CHECK-NEXT: %i = phi i32 [ %[[EXTL]], %left ], [ %[[EXTR]], %right ]
+; CHECK-NEXT: ret i32 %i
+ %i = phi i32 [ %lhs, %left ], [ %rhs, %right ]
+ ret i32 %i
+}
+
+; Extracting a type that won't fit in a vector isn't handled. The function
+; should stay the same.
+define i40 @type_pun_unhandled(<16 x i8> %in) {
+; CHECK-LABEL: @type_pun_unhandled(
+; CHECK-NEXT: %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <5 x i32> <i32 4, i32 5, i32 6, i32 7, i32 8>
+; CHECK-NEXT: %1 = bitcast <5 x i8> %sroa to i40
+; CHECK-NEXT: ret i40 %1
+ %sroa = shufflevector <16 x i8> %in, <16 x i8> undef, <5 x i32> <i32 4, i32 5, i32 6, i32 7, i32 8>
+ %1 = bitcast <5 x i8> %sroa to i40
+ ret i40 %1
+}
diff --git a/test/Transforms/InstCombine/unordered-fcmp-select.ll b/test/Transforms/InstCombine/unordered-fcmp-select.ll
new file mode 100644
index 0000000..0eb7290
--- /dev/null
+++ b/test/Transforms/InstCombine/unordered-fcmp-select.ll
@@ -0,0 +1,125 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; CHECK-LABEL: @select_max_ugt(
+; CHECK: %cmp.inv = fcmp ole float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %b, float %a
+; CHECK-NEXT: ret float %sel
+define float @select_max_ugt(float %a, float %b) {
+ %cmp = fcmp ugt float %a, %b
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_max_uge(
+; CHECK: %cmp.inv = fcmp olt float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %b, float %a
+; CHECK-NEXT: ret float %sel
+define float @select_max_uge(float %a, float %b) {
+ %cmp = fcmp uge float %a, %b
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_min_ugt(
+; CHECK: %cmp.inv = fcmp ole float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %a, float %b
+; CHECK-NEXT: ret float %sel
+define float @select_min_ugt(float %a, float %b) {
+ %cmp = fcmp ugt float %a, %b
+ %sel = select i1 %cmp, float %b, float %a
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_min_uge(
+; CHECK: %cmp.inv = fcmp olt float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %a, float %b
+; CHECK-NEXT: ret float %sel
+define float @select_min_uge(float %a, float %b) {
+ %cmp = fcmp uge float %a, %b
+ %sel = select i1 %cmp, float %b, float %a
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_max_ult(
+; CHECK: %cmp.inv = fcmp oge float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %a, float %b
+; CHECK-NEXT: ret float %sel
+define float @select_max_ult(float %a, float %b) {
+ %cmp = fcmp ult float %a, %b
+ %sel = select i1 %cmp, float %b, float %a
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_max_ule(
+; CHECK: %cmp.inv = fcmp ogt float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %a, float %b
+; CHECK: ret float %sel
+define float @select_max_ule(float %a, float %b) {
+ %cmp = fcmp ule float %a, %b
+ %sel = select i1 %cmp, float %b, float %a
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_min_ult(
+; CHECK: %cmp.inv = fcmp oge float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %b, float %a
+; CHECK-NEXT: ret float %sel
+define float @select_min_ult(float %a, float %b) {
+ %cmp = fcmp ult float %a, %b
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_min_ule(
+; CHECK: %cmp.inv = fcmp ogt float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %b, float %a
+; CHECK-NEXT: ret float %sel
+define float @select_min_ule(float %a, float %b) {
+ %cmp = fcmp ule float %a, %b
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_fcmp_une(
+; CHECK: %cmp.inv = fcmp oeq float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %b, float %a
+; CHECK-NEXT: ret float %sel
+define float @select_fcmp_une(float %a, float %b) {
+ %cmp = fcmp une float %a, %b
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_fcmp_ueq
+; CHECK: %cmp.inv = fcmp one float %a, %b
+; CHECK-NEXT: %sel = select i1 %cmp.inv, float %b, float %a
+; CHECK-NEXT: ret float %sel
+define float @select_fcmp_ueq(float %a, float %b) {
+ %cmp = fcmp ueq float %a, %b
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+declare void @foo(i1)
+
+; CHECK-LABEL: @select_max_ugt_2_use_cmp(
+; CHECK: fcmp ugt
+; CHECK-NOT: fcmp
+; CHECK: ret
+define float @select_max_ugt_2_use_cmp(float %a, float %b) {
+ %cmp = fcmp ugt float %a, %b
+ call void @foo(i1 %cmp)
+ %sel = select i1 %cmp, float %a, float %b
+ ret float %sel
+}
+
+; CHECK-LABEL: @select_min_uge_2_use_cmp(
+; CHECK: fcmp uge
+; CHECK-NOT: fcmp
+; CHECK: ret
+define float @select_min_uge_2_use_cmp(float %a, float %b) {
+ %cmp = fcmp uge float %a, %b
+ call void @foo(i1 %cmp)
+ %sel = select i1 %cmp, float %b, float %a
+ ret float %sel
+}
diff --git a/test/Transforms/InstCombine/vec_demanded_elts.ll b/test/Transforms/InstCombine/vec_demanded_elts.ll
index 41d2b29..00a029a 100644
--- a/test/Transforms/InstCombine/vec_demanded_elts.ll
+++ b/test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -303,6 +303,33 @@ define <2 x i64> @testInsertDisjointRange_2(<2 x i64> %v, <2 x i64> %i) {
ret <2 x i64> %2
}
+; CHECK: define <2 x i64> @testZeroLength(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testZeroLength(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: ret <2 x i64> %i
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 0, i8 0)
+ ret <2 x i64> %1
+}
+
+; CHECK: define <2 x i64> @testUndefinedInsertq_1(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testUndefinedInsertq_1(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: ret <2 x i64> undef
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 0, i8 16)
+ ret <2 x i64> %1
+}
+
+; CHECK: define <2 x i64> @testUndefinedInsertq_2(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testUndefinedInsertq_2(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: ret <2 x i64> undef
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 32)
+ ret <2 x i64> %1
+}
+
+; CHECK: define <2 x i64> @testUndefinedInsertq_3(<2 x i64> %v, <2 x i64> %i)
+define <2 x i64> @testUndefinedInsertq_3(<2 x i64> %v, <2 x i64> %i) {
+; CHECK: ret <2 x i64> undef
+ %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 64, i8 16)
+ ret <2 x i64> %1
+}
; CHECK: declare <2 x i64> @llvm.x86.sse4a.insertqi
declare <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64>, <2 x i64>, i8, i8) nounwind
diff --git a/test/Transforms/InstCombine/xor.ll b/test/Transforms/InstCombine/xor.ll
index 3722697..c8debcb 100644
--- a/test/Transforms/InstCombine/xor.ll
+++ b/test/Transforms/InstCombine/xor.ll
@@ -1,50 +1,70 @@
; This test makes sure that these instructions are properly eliminated.
;
; RUN: opt < %s -instcombine -S | \
-; RUN: not grep "xor "
+; RUN: FileCheck %s
; END.
@G1 = global i32 0 ; <i32*> [#uses=1]
@G2 = global i32 0 ; <i32*> [#uses=1]
define i1 @test0(i1 %A) {
+; CHECK-LABEL: @test0(
+; CHECK-NEXT: ret i1 %A
%B = xor i1 %A, false ; <i1> [#uses=1]
ret i1 %B
}
define i32 @test1(i32 %A) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: ret i32 %A
%B = xor i32 %A, 0 ; <i32> [#uses=1]
ret i32 %B
}
define i1 @test2(i1 %A) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: ret i1 false
%B = xor i1 %A, %A ; <i1> [#uses=1]
ret i1 %B
}
define i32 @test3(i32 %A) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: ret i32 0
%B = xor i32 %A, %A ; <i32> [#uses=1]
ret i32 %B
}
define i32 @test4(i32 %A) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: ret i32 -1
%NotA = xor i32 -1, %A ; <i32> [#uses=1]
%B = xor i32 %A, %NotA ; <i32> [#uses=1]
ret i32 %B
}
define i32 @test5(i32 %A) {
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: %1 = and i32 %A, -124
+; CHECK-NEXT: ret i32 %1
%t1 = or i32 %A, 123 ; <i32> [#uses=1]
%r = xor i32 %t1, 123 ; <i32> [#uses=1]
ret i32 %r
}
define i8 @test6(i8 %A) {
+; CHECK-LABEL: @test6(
+; CHECK-NEXT: ret i8 %A
%B = xor i8 %A, 17 ; <i8> [#uses=1]
%C = xor i8 %B, 17 ; <i8> [#uses=1]
ret i8 %C
}
define i32 @test7(i32 %A, i32 %B) {
+; CHECK-LABEL: @test7(
+; CHECK-NEXT: %A1 = and i32 %A, 7
+; CHECK-NEXT: %B1 = and i32 %B, 128
+; CHECK-NEXT: %C11 = or i32 %A1, %B1
+; CHECK-NEXT: ret i32 %C11
%A1 = and i32 %A, 7 ; <i32> [#uses=1]
%B1 = and i32 %B, 128 ; <i32> [#uses=1]
%C1 = xor i32 %A1, %B1 ; <i32> [#uses=1]
@@ -52,6 +72,8 @@ define i32 @test7(i32 %A, i32 %B) {
}
define i8 @test8(i1 %c) {
+; CHECK-LABEL: @test8(
+; CHECK: br i1 %c, label %False, label %True
%d = xor i1 %c, true ; <i1> [#uses=1]
br i1 %d, label %True, label %False
@@ -63,30 +85,47 @@ False: ; preds = %0
}
define i1 @test9(i8 %A) {
+; CHECK-LABEL: @test9(
+; CHECK-NEXT: %C = icmp eq i8 %A, 89
+; CHECK-NEXT: ret i1 %C
%B = xor i8 %A, 123 ; <i8> [#uses=1]
%C = icmp eq i8 %B, 34 ; <i1> [#uses=1]
ret i1 %C
}
define i8 @test10(i8 %A) {
+; CHECK-LABEL: @test10(
+; CHECK-NEXT: %B = and i8 %A, 3
+; CHECK-NEXT: %C1 = or i8 %B, 4
+; CHECK-NEXT: ret i8 %C1
%B = and i8 %A, 3 ; <i8> [#uses=1]
%C = xor i8 %B, 4 ; <i8> [#uses=1]
ret i8 %C
}
define i8 @test11(i8 %A) {
+; CHECK-LABEL: @test11(
+; CHECK-NEXT: %B = and i8 %A, -13
+; CHECK-NEXT: %1 = or i8 %B, 8
+; CHECK-NEXT: ret i8 %1
%B = or i8 %A, 12 ; <i8> [#uses=1]
%C = xor i8 %B, 4 ; <i8> [#uses=1]
ret i8 %C
}
define i1 @test12(i8 %A) {
+; CHECK-LABEL: @test12(
+; CHECK-NEXT: %c = icmp ne i8 %A, 4
+; CHECK-NEXT: ret i1 %c
%B = xor i8 %A, 4 ; <i8> [#uses=1]
%c = icmp ne i8 %B, 0 ; <i1> [#uses=1]
ret i1 %c
}
define i1 @test13(i8 %A, i8 %B) {
+; CHECK-LABEL: @test13(
+; CHECK-NEXT: %1 = icmp ne i8 %A, %B
+; CHECK-NEXT: ret i1 %1
%C = icmp ult i8 %A, %B ; <i1> [#uses=1]
%D = icmp ugt i8 %A, %B ; <i1> [#uses=1]
%E = xor i1 %C, %D ; <i1> [#uses=1]
@@ -94,6 +133,8 @@ define i1 @test13(i8 %A, i8 %B) {
}
define i1 @test14(i8 %A, i8 %B) {
+; CHECK-LABEL: @test14(
+; CHECK-NEXT: ret i1 true
%C = icmp eq i8 %A, %B ; <i1> [#uses=1]
%D = icmp ne i8 %B, %A ; <i1> [#uses=1]
%E = xor i1 %C, %D ; <i1> [#uses=1]
@@ -101,36 +142,54 @@ define i1 @test14(i8 %A, i8 %B) {
}
define i32 @test15(i32 %A) {
+; CHECK-LABEL: @test15(
+; CHECK-NEXT: %C = sub i32 0, %A
+; CHECK-NEXT: ret i32 %C
%B = add i32 %A, -1 ; <i32> [#uses=1]
%C = xor i32 %B, -1 ; <i32> [#uses=1]
ret i32 %C
}
define i32 @test16(i32 %A) {
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: %C = sub i32 -124, %A
+; CHECK-NEXT: ret i32 %C
%B = add i32 %A, 123 ; <i32> [#uses=1]
%C = xor i32 %B, -1 ; <i32> [#uses=1]
ret i32 %C
}
define i32 @test17(i32 %A) {
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: %C = add i32 %A, -124
+; CHECK-NEXT: ret i32 %C
%B = sub i32 123, %A ; <i32> [#uses=1]
%C = xor i32 %B, -1 ; <i32> [#uses=1]
ret i32 %C
}
define i32 @test18(i32 %A) {
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: %C = add i32 %A, 124
+; CHECK-NEXT: ret i32 %C
%B = xor i32 %A, -1 ; <i32> [#uses=1]
%C = sub i32 123, %B ; <i32> [#uses=1]
ret i32 %C
}
define i32 @test19(i32 %A, i32 %B) {
+; CHECK-LABEL: @test19(
+; CHECK-NEXT: ret i32 %B
%C = xor i32 %A, %B ; <i32> [#uses=1]
%D = xor i32 %C, %A ; <i32> [#uses=1]
ret i32 %D
}
define void @test20(i32 %A, i32 %B) {
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: store i32 %B, i32* @G1
+; CHECK-NEXT: store i32 %A, i32* @G2
+; CHECK-NEXT: ret void
%tmp.2 = xor i32 %B, %A ; <i32> [#uses=2]
%tmp.5 = xor i32 %tmp.2, %B ; <i32> [#uses=2]
%tmp.8 = xor i32 %tmp.5, %tmp.2 ; <i32> [#uses=1]
@@ -140,12 +199,18 @@ define void @test20(i32 %A, i32 %B) {
}
define i32 @test21(i1 %C, i32 %A, i32 %B) {
+; CHECK-LABEL: @test21(
+; CHECK-NEXT: %D = select i1 %C, i32 %B, i32 %A
+; CHECK-NEXT: ret i32 %D
%C2 = xor i1 %C, true ; <i1> [#uses=1]
%D = select i1 %C2, i32 %A, i32 %B ; <i32> [#uses=1]
ret i32 %D
}
define i32 @test22(i1 %X) {
+; CHECK-LABEL: @test22(
+; CHECK-NEXT: %1 = zext i1 %X to i32
+; CHECK-NEXT: ret i32 %1
%Y = xor i1 %X, true ; <i1> [#uses=1]
%Z = zext i1 %Y to i32 ; <i32> [#uses=1]
%Q = xor i32 %Z, 1 ; <i32> [#uses=1]
@@ -153,18 +218,27 @@ define i32 @test22(i1 %X) {
}
define i1 @test23(i32 %a, i32 %b) {
+; CHECK-LABEL: @test23(
+; CHECK-NEXT: %tmp.4 = icmp eq i32 %b, 0
+; CHECK-NEXT: ret i1 %tmp.4
%tmp.2 = xor i32 %b, %a ; <i32> [#uses=1]
%tmp.4 = icmp eq i32 %tmp.2, %a ; <i1> [#uses=1]
ret i1 %tmp.4
}
define i1 @test24(i32 %c, i32 %d) {
+; CHECK-LABEL: @test24(
+; CHECK-NEXT: %tmp.4 = icmp ne i32 %d, 0
+; CHECK-NEXT: ret i1 %tmp.4
%tmp.2 = xor i32 %d, %c ; <i32> [#uses=1]
%tmp.4 = icmp ne i32 %tmp.2, %c ; <i1> [#uses=1]
ret i1 %tmp.4
}
define i32 @test25(i32 %g, i32 %h) {
+; CHECK-LABEL: @test25(
+; CHECK-NEXT: %tmp4 = and i32 %h, %g
+; CHECK-NEXT: ret i32 %tmp4
%h2 = xor i32 %h, -1 ; <i32> [#uses=1]
%tmp2 = and i32 %h2, %g ; <i32> [#uses=1]
%tmp4 = xor i32 %tmp2, %g ; <i32> [#uses=1]
@@ -172,6 +246,9 @@ define i32 @test25(i32 %g, i32 %h) {
}
define i32 @test26(i32 %a, i32 %b) {
+; CHECK-LABEL: @test26(
+; CHECK-NEXT: %tmp4 = and i32 %a, %b
+; CHECK-NEXT: ret i32 %tmp4
%b2 = xor i32 %b, -1 ; <i32> [#uses=1]
%tmp2 = xor i32 %a, %b2 ; <i32> [#uses=1]
%tmp4 = and i32 %tmp2, %a ; <i32> [#uses=1]
@@ -179,6 +256,10 @@ define i32 @test26(i32 %a, i32 %b) {
}
define i32 @test27(i32 %b, i32 %c, i32 %d) {
+; CHECK-LABEL: @test27(
+; CHECK-NEXT: %tmp = icmp eq i32 %b, %c
+; CHECK-NEXT: %tmp6 = zext i1 %tmp to i32
+; CHECK-NEXT: ret i32 %tmp6
%tmp2 = xor i32 %d, %b ; <i32> [#uses=1]
%tmp5 = xor i32 %d, %c ; <i32> [#uses=1]
%tmp = icmp eq i32 %tmp2, %tmp5 ; <i1> [#uses=1]
@@ -187,6 +268,9 @@ define i32 @test27(i32 %b, i32 %c, i32 %d) {
}
define i32 @test28(i32 %indvar) {
+; CHECK-LABEL: @test28(
+; CHECK-NEXT: %tmp214 = add i32 %indvar, 1
+; CHECK-NEXT: ret i32 %tmp214
%tmp7 = add i32 %indvar, -2147483647 ; <i32> [#uses=1]
%tmp214 = xor i32 %tmp7, -2147483648 ; <i32> [#uses=1]
ret i32 %tmp214
diff --git a/test/Transforms/InstMerge/st_sink_barrier_call.ll b/test/Transforms/InstMerge/st_sink_barrier_call.ll
new file mode 100644
index 0000000..c158b00
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_barrier_call.ll
@@ -0,0 +1,43 @@
+; Test to make sure that a function call that needs to be a barrier to sinking stores is indeed a barrier.
+; Stores sunks into the footer.
+; RUN: opt -basicaa -memdep -mldst-motion -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+%struct.node = type { i32, %struct.node*, %struct.node*, %struct.node*, i32, i32, i32, i32 }
+
+declare i32 @foo(i32 %x)
+
+; Function Attrs: nounwind uwtable
+define void @sink_store(%struct.node* nocapture %r, i32 %index) {
+entry:
+ %node.0.in16 = getelementptr inbounds %struct.node* %r, i64 0, i32 2
+ %node.017 = load %struct.node** %node.0.in16, align 8
+ %index.addr = alloca i32, align 4
+ store i32 %index, i32* %index.addr, align 4
+ %0 = load i32* %index.addr, align 4
+ %cmp = icmp slt i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+; CHECK: if.then
+if.then: ; preds = %entry
+ %1 = load i32* %index.addr, align 4
+ %p1 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK: store i32
+ store i32 %1, i32* %p1, align 4
+ br label %if.end
+
+; CHECK: if.else
+if.else: ; preds = %entry
+ %2 = load i32* %index.addr, align 4
+ %add = add nsw i32 %2, 1
+ %p3 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK: store i32
+ store i32 %add, i32* %p3, align 4
+ call i32 @foo(i32 5) ;barrier
+ br label %if.end
+
+; CHECK: if.end
+if.end: ; preds = %if.else, %if.then
+; CHECK-NOT: store
+ ret void
+}
diff --git a/test/Transforms/InstMerge/st_sink_bugfix_22613.ll b/test/Transforms/InstMerge/st_sink_bugfix_22613.ll
new file mode 100644
index 0000000..34e3fdb
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_bugfix_22613.ll
@@ -0,0 +1,106 @@
+; ModuleID = 'bug.c'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; RUN: opt -O2 -S < %s | FileCheck %s
+
+; CHECK_LABEL: main
+; CHECK: if.end
+; CHECK: store
+; CHECK: memset
+; CHECK: if.then
+; CHECK: store
+; CHECK: memset
+
+@d = common global i32 0, align 4
+@b = common global i32 0, align 4
+@f = common global [1 x [3 x i8]] zeroinitializer, align 1
+@e = common global i32 0, align 4
+@c = common global i32 0, align 4
+@a = common global i32 0, align 4
+
+; Function Attrs: nounwind uwtable
+define void @fn1() {
+entry:
+ store i32 0, i32* @d, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc8, %entry
+ %0 = load i32* @d, align 4
+ %cmp = icmp slt i32 %0, 2
+ br i1 %cmp, label %for.body, label %for.end10
+
+for.body: ; preds = %for.cond
+ %1 = load i32* @d, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32* @b, align 4
+ %idxprom1 = sext i32 %2 to i64
+ %arrayidx = getelementptr inbounds [1 x [3 x i8]]* @f, i32 0, i64 %idxprom1
+ %arrayidx2 = getelementptr inbounds [3 x i8]* %arrayidx, i32 0, i64 %idxprom
+ store i8 0, i8* %arrayidx2, align 1
+ store i32 0, i32* @e, align 4
+ br label %for.cond3
+
+for.cond3: ; preds = %for.inc, %for.body
+ %3 = load i32* @e, align 4
+ %cmp4 = icmp slt i32 %3, 3
+ br i1 %cmp4, label %for.body5, label %for.end
+
+for.body5: ; preds = %for.cond3
+ %4 = load i32* @c, align 4
+ %tobool = icmp ne i32 %4, 0
+ br i1 %tobool, label %if.then, label %if.end
+
+if.then: ; preds = %for.body5
+ %5 = load i32* @a, align 4
+ %dec = add nsw i32 %5, -1
+ store i32 %dec, i32* @a, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body5
+ %6 = load i32* @e, align 4
+ %idxprom6 = sext i32 %6 to i64
+ %arrayidx7 = getelementptr inbounds [3 x i8]* getelementptr inbounds ([1 x [3 x i8]]* @f, i32 0, i64 0), i32 0, i64 %idxprom6
+ store i8 1, i8* %arrayidx7, align 1
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %7 = load i32* @e, align 4
+ %inc = add nsw i32 %7, 1
+ store i32 %inc, i32* @e, align 4
+ br label %for.cond3
+
+for.end: ; preds = %for.cond3
+ br label %for.inc8
+
+for.inc8: ; preds = %for.end
+ %8 = load i32* @d, align 4
+ %inc9 = add nsw i32 %8, 1
+ store i32 %inc9, i32* @d, align 4
+ br label %for.cond
+
+for.end10: ; preds = %for.cond
+ ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, i32* %retval
+ call void @fn1()
+ %0 = load i8* getelementptr inbounds ([1 x [3 x i8]]* @f, i32 0, i64 0, i64 1), align 1
+ %conv = sext i8 %0 to i32
+ %cmp = icmp ne i32 %conv, 1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ call void @abort()
+ unreachable
+
+if.end: ; preds = %entry
+ ret i32 0
+}
+
+; Function Attrs: noreturn nounwind
+declare void @abort()
diff --git a/test/Transforms/InstMerge/st_sink_no_barrier_call.ll b/test/Transforms/InstMerge/st_sink_no_barrier_call.ll
new file mode 100644
index 0000000..72f1fdf
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_no_barrier_call.ll
@@ -0,0 +1,45 @@
+; Test to make sure that stores in a diamond get merged with a non barrier function call after the store instruction
+; Stores sunks into the footer.
+; RUN: opt -basicaa -memdep -mldst-motion -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+%struct.node = type { i32, %struct.node*, %struct.node*, %struct.node*, i32, i32, i32, i32 }
+
+declare i32 @foo(i32 %x) #0
+
+; Function Attrs: nounwind uwtable
+define void @sink_store(%struct.node* nocapture %r, i32 %index) {
+entry:
+ %node.0.in16 = getelementptr inbounds %struct.node* %r, i64 0, i32 2
+ %node.017 = load %struct.node** %node.0.in16, align 8
+ %index.addr = alloca i32, align 4
+ store i32 %index, i32* %index.addr, align 4
+ %0 = load i32* %index.addr, align 4
+ %cmp = icmp slt i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+; CHECK: if.then
+if.then: ; preds = %entry
+ %1 = load i32* %index.addr, align 4
+ %p1 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %1, i32* %p1, align 4
+ br label %if.end
+
+; CHECK: if.else
+if.else: ; preds = %entry
+ %2 = load i32* %index.addr, align 4
+ %add = add nsw i32 %2, 1
+ %p3 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %add, i32* %p3, align 4
+ call i32 @foo(i32 5) ;not a barrier
+ br label %if.end
+
+; CHECK: if.end
+if.end: ; preds = %if.else, %if.then
+; CHECK: store
+ ret void
+}
+
+attributes #0 = { readnone }
diff --git a/test/Transforms/InstMerge/st_sink_no_barrier_load.ll b/test/Transforms/InstMerge/st_sink_no_barrier_load.ll
new file mode 100644
index 0000000..5be0c25
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_no_barrier_load.ll
@@ -0,0 +1,43 @@
+; Test to make sure that stores in a diamond get merged with a non barrier load after the store instruction
+; Stores sunks into the footer.
+; RUN: opt -basicaa -memdep -mldst-motion -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+%struct.node = type { i32, %struct.node*, %struct.node*, %struct.node*, i32, i32, i32, i32 }
+
+; Function Attrs: nounwind uwtable
+define void @sink_store(%struct.node* nocapture %r, i32 %index) {
+entry:
+ %node.0.in16 = getelementptr inbounds %struct.node* %r, i64 0, i32 2
+ %node.017 = load %struct.node** %node.0.in16, align 8
+ %index.addr = alloca i32, align 4
+ store i32 %index, i32* %index.addr, align 4
+ %0 = load i32* %index.addr, align 4
+ %cmp = icmp slt i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+; CHECK: if.then
+if.then: ; preds = %entry
+ %1 = load i32* %index.addr, align 4
+ %p1 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %1, i32* %p1, align 4
+ %p2 = getelementptr inbounds %struct.node* %node.017, i32 5, i32 6
+ ; CHECK: load i32*
+ %not_barrier = load i32 * %p2, align 4
+ br label %if.end
+
+; CHECK: if.else
+if.else: ; preds = %entry
+ %2 = load i32* %index.addr, align 4
+ %add = add nsw i32 %2, 1
+ %p3 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %add, i32* %p3, align 4
+ br label %if.end
+
+; CHECK: if.end
+if.end: ; preds = %if.else, %if.then
+; CHECK: store
+ ret void
+}
diff --git a/test/Transforms/InstMerge/st_sink_no_barrier_store.ll b/test/Transforms/InstMerge/st_sink_no_barrier_store.ll
new file mode 100644
index 0000000..06e2b63
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_no_barrier_store.ll
@@ -0,0 +1,42 @@
+; Test to make sure that stores in a diamond get merged with a non barrier store after the store instruction to be sunk
+; Stores sunks into the footer.
+; RUN: opt -basicaa -memdep -mldst-motion -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+%struct.node = type { i32, %struct.node*, %struct.node*, %struct.node*, i32, i32, i32, i32 }
+
+; Function Attrs: nounwind uwtable
+define void @sink_store(%struct.node* nocapture %r, i32 %index) {
+entry:
+ %node.0.in16 = getelementptr inbounds %struct.node* %r, i64 0, i32 2
+ %node.017 = load %struct.node** %node.0.in16, align 8
+ %index.addr = alloca i32, align 4
+ store i32 %index, i32* %index.addr, align 4
+ %0 = load i32* %index.addr, align 4
+ %cmp = icmp slt i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+; CHECK: if.then
+if.then: ; preds = %entry
+ %1 = load i32* %index.addr, align 4
+ %p1 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %1, i32* %p1, align 4
+ br label %if.end
+
+; CHECK: if.else
+if.else: ; preds = %entry
+ %2 = load i32* %index.addr, align 4
+ %add = add nsw i32 %2, 1
+ %p2 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ store i32 %add, i32* %p2, align 4
+ %p3 = getelementptr inbounds %struct.node* %node.017, i32 5, i32 6
+ ; CHECK: store i32
+ store i32 %add, i32* %p3, align 4 ; This is not a barrier
+ br label %if.end
+
+; CHECK: if.end
+if.end: ; preds = %if.else, %if.then
+; CHECK: store
+ ret void
+}
diff --git a/test/Transforms/InstMerge/st_sink_two_stores.ll b/test/Transforms/InstMerge/st_sink_two_stores.ll
new file mode 100644
index 0000000..1f7c6aa
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_two_stores.ll
@@ -0,0 +1,47 @@
+; Test to make sure that stores in a diamond get merged
+; Stores sunks into the footer.
+; RUN: opt -basicaa -memdep -mldst-motion -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+%struct.node = type { i32, %struct.node*, %struct.node*, %struct.node*, i32, i32, i32, i32 }
+
+; Function Attrs: nounwind uwtable
+define void @sink_store(%struct.node* nocapture %r, i32 %index) {
+entry:
+ %node.0.in16 = getelementptr inbounds %struct.node* %r, i64 0, i32 2
+ %node.017 = load %struct.node** %node.0.in16, align 8
+ %index.addr = alloca i32, align 4
+ store i32 %index, i32* %index.addr, align 4
+ %0 = load i32* %index.addr, align 4
+ %cmp = icmp slt i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+; CHECK: if.then
+if.then: ; preds = %entry
+ %1 = load i32* %index.addr, align 4
+ %p1 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %1, i32* %p1, align 4
+ %p2 = getelementptr inbounds %struct.node* %node.017, i32 4, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %1, i32* %p2, align 4
+ br label %if.end
+
+; CHECK: if.else
+if.else: ; preds = %entry
+ %2 = load i32* %index.addr, align 4
+ %add = add nsw i32 %2, 1
+ %p3 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %add, i32* %p3, align 4
+ %p4 = getelementptr inbounds %struct.node* %node.017, i32 4, i32 6
+ ; CHECK-NOT: store i32
+ store i32 %2, i32* %p4, align 4
+ br label %if.end
+
+; CHECK: if.end
+if.end: ; preds = %if.else, %if.then
+; CHECK: store
+; CHECK: store
+ ret void
+}
diff --git a/test/Transforms/InstMerge/st_sink_with_barrier.ll b/test/Transforms/InstMerge/st_sink_with_barrier.ll
new file mode 100644
index 0000000..d4efaa7
--- /dev/null
+++ b/test/Transforms/InstMerge/st_sink_with_barrier.ll
@@ -0,0 +1,42 @@
+; Test to make sure that load from the same address as a store and appears after the store prevents the store from being sunk
+; RUN: opt -basicaa -memdep -mldst-motion -S < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+%struct.node = type { i32, %struct.node*, %struct.node*, %struct.node*, i32, i32, i32, i32 }
+
+; Function Attrs: nounwind uwtable
+define void @sink_store(%struct.node* nocapture %r, i32 %index) {
+entry:
+ %node.0.in16 = getelementptr inbounds %struct.node* %r, i64 0, i32 2
+ %node.017 = load %struct.node** %node.0.in16, align 8
+ %index.addr = alloca i32, align 4
+ store i32 %index, i32* %index.addr, align 4
+ %0 = load i32* %index.addr, align 4
+ %cmp = icmp slt i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+; CHECK: if.then
+if.then: ; preds = %entry
+ %1 = load i32* %index.addr, align 4
+ %p1 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK: store i32
+ store i32 %1, i32* %p1, align 4
+ %p2 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK: load i32*
+ %barrier = load i32 * %p2, align 4
+ br label %if.end
+
+; CHECK: if.else
+if.else: ; preds = %entry
+ %2 = load i32* %index.addr, align 4
+ %add = add nsw i32 %2, 1
+ %p3 = getelementptr inbounds %struct.node* %node.017, i32 0, i32 6
+ ; CHECK: store i32
+ store i32 %add, i32* %p3, align 4
+ br label %if.end
+
+; CHECK: if.end
+if.end: ; preds = %if.else, %if.then
+; CHECK-NOT: store
+ ret void
+}
diff --git a/test/Transforms/InstSimplify/AndOrXor.ll b/test/Transforms/InstSimplify/AndOrXor.ll
index 8ed06e8..ce3c2aa 100644
--- a/test/Transforms/InstSimplify/AndOrXor.ll
+++ b/test/Transforms/InstSimplify/AndOrXor.ll
@@ -148,3 +148,58 @@ define i1 @or_of_icmps5(i32 %b) {
ret i1 %cmp
; CHECK: ret i1 true
}
+
+define i32 @neg_nuw(i32 %x) {
+; CHECK-LABEL: @neg_nuw(
+ %neg = sub nuw i32 0, %x
+ ret i32 %neg
+; CHECK: ret i32 0
+}
+
+define i1 @and_icmp1(i32 %x, i32 %y) {
+ %1 = icmp ult i32 %x, %y
+ %2 = icmp ne i32 %y, 0
+ %3 = and i1 %1, %2
+ ret i1 %3
+}
+; CHECK-LABEL: @and_icmp1(
+; CHECK: %[[cmp:.*]] = icmp ult i32 %x, %y
+; CHECK: ret i1 %[[cmp]]
+
+define i1 @and_icmp2(i32 %x, i32 %y) {
+ %1 = icmp ult i32 %x, %y
+ %2 = icmp eq i32 %y, 0
+ %3 = and i1 %1, %2
+ ret i1 %3
+}
+; CHECK-LABEL: @and_icmp2(
+; CHECK: ret i1 false
+
+define i1 @or_icmp1(i32 %x, i32 %y) {
+ %1 = icmp ult i32 %x, %y
+ %2 = icmp ne i32 %y, 0
+ %3 = or i1 %1, %2
+ ret i1 %3
+}
+; CHECK-LABEL: @or_icmp1(
+; CHECK: %[[cmp:.*]] = icmp ne i32 %y, 0
+; CHECK: ret i1 %[[cmp]]
+
+define i1 @or_icmp2(i32 %x, i32 %y) {
+ %1 = icmp uge i32 %x, %y
+ %2 = icmp ne i32 %y, 0
+ %3 = or i1 %1, %2
+ ret i1 %3
+}
+; CHECK-LABEL: @or_icmp2(
+; CHECK: ret i1 true
+
+define i1 @or_icmp3(i32 %x, i32 %y) {
+ %1 = icmp uge i32 %x, %y
+ %2 = icmp eq i32 %y, 0
+ %3 = or i1 %1, %2
+ ret i1 %3
+}
+; CHECK-LABEL: @or_icmp3(
+; CHECK: %[[cmp:.*]] = icmp uge i32 %x, %y
+; CHECK: ret i1 %[[cmp]]
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index 38fd747..10c7ca6 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -1100,3 +1100,67 @@ define i1 @icmp_shl_1_V_ne_31(i32 %V) {
; CHECK-LABEL: @icmp_shl_1_V_ne_31(
; CHECK-NEXT: ret i1 true
}
+
+define i1 @tautological1(i32 %A, i32 %B) {
+ %C = and i32 %A, %B
+ %D = icmp ugt i32 %C, %A
+ ret i1 %D
+; CHECK-LABEL: @tautological1(
+; CHECK: ret i1 false
+}
+
+define i1 @tautological2(i32 %A, i32 %B) {
+ %C = and i32 %A, %B
+ %D = icmp ule i32 %C, %A
+ ret i1 %D
+; CHECK-LABEL: @tautological2(
+; CHECK: ret i1 true
+}
+
+define i1 @tautological3(i32 %A, i32 %B) {
+ %C = or i32 %A, %B
+ %D = icmp ule i32 %A, %C
+ ret i1 %D
+; CHECK-LABEL: @tautological3(
+; CHECK: ret i1 true
+}
+
+define i1 @tautological4(i32 %A, i32 %B) {
+ %C = or i32 %A, %B
+ %D = icmp ugt i32 %A, %C
+ ret i1 %D
+; CHECK-LABEL: @tautological4(
+; CHECK: ret i1 false
+}
+
+define i1 @tautological5(i32 %A, i32 %B) {
+ %C = or i32 %A, %B
+ %D = icmp ult i32 %C, %A
+ ret i1 %D
+; CHECK-LABEL: @tautological5(
+; CHECK: ret i1 false
+}
+
+define i1 @tautological6(i32 %A, i32 %B) {
+ %C = or i32 %A, %B
+ %D = icmp uge i32 %C, %A
+ ret i1 %D
+; CHECK-LABEL: @tautological6(
+; CHECK: ret i1 true
+}
+
+define i1 @tautological7(i32 %A, i32 %B) {
+ %C = and i32 %A, %B
+ %D = icmp uge i32 %A, %C
+ ret i1 %D
+; CHECK-LABEL: @tautological7(
+; CHECK: ret i1 true
+}
+
+define i1 @tautological8(i32 %A, i32 %B) {
+ %C = and i32 %A, %B
+ %D = icmp ult i32 %A, %C
+ ret i1 %D
+; CHECK-LABEL: @tautological8(
+; CHECK: ret i1 false
+}
diff --git a/test/Transforms/InstSimplify/fast-math.ll b/test/Transforms/InstSimplify/fast-math.ll
index 71d1ed8..e7fb14d 100644
--- a/test/Transforms/InstSimplify/fast-math.ll
+++ b/test/Transforms/InstSimplify/fast-math.ll
@@ -105,3 +105,12 @@ define float @nofold_fadd_x_0(float %a) {
; CHECK: ret float %no_zero
ret float %no_zero
}
+
+; fdiv nsz nnan 0, X ==> 0
+define double @fdiv_zero_by_x(double %X) {
+; CHECK-LABEL: @fdiv_zero_by_x(
+; 0 / X -> 0
+ %r = fdiv nnan nsz double 0.0, %X
+ ret double %r
+; CHECK: ret double 0
+}
diff --git a/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/test/Transforms/InstSimplify/floating-point-arithmetic.ll
index 8177440..b0957a8 100644
--- a/test/Transforms/InstSimplify/floating-point-arithmetic.ll
+++ b/test/Transforms/InstSimplify/floating-point-arithmetic.ll
@@ -33,3 +33,29 @@ define double @fmul_X_1(double %a) {
; CHECK: ret double %a
ret double %b
}
+
+; We can't optimize away the fadd in this test because the input
+; value to the function and subsequently to the fadd may be -0.0.
+; In that one special case, the result of the fadd should be +0.0
+; rather than the first parameter of the fadd.
+
+; Fragile test warning: We need 6 sqrt calls to trigger the bug
+; because the internal logic has a magic recursion limit of 6.
+; This is presented without any explanation or ability to customize.
+
+declare float @sqrtf(float)
+
+define float @PR22688(float %x) {
+ %1 = call float @sqrtf(float %x)
+ %2 = call float @sqrtf(float %1)
+ %3 = call float @sqrtf(float %2)
+ %4 = call float @sqrtf(float %3)
+ %5 = call float @sqrtf(float %4)
+ %6 = call float @sqrtf(float %5)
+ %7 = fadd float %6, 0.0
+ ret float %7
+
+; CHECK-LABEL: @PR22688(
+; CHECK: fadd float %6, 0.0
+}
+
diff --git a/test/Transforms/InstSimplify/floating-point-compare.ll b/test/Transforms/InstSimplify/floating-point-compare.ll
new file mode 100644
index 0000000..af48d06
--- /dev/null
+++ b/test/Transforms/InstSimplify/floating-point-compare.ll
@@ -0,0 +1,60 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+; These tests choose arbitrarily between float and double,
+; and between uge and olt, to give reasonble coverage
+; without combinatorial explosion.
+
+declare float @llvm.fabs.f32(float)
+declare float @llvm.sqrt.f32(float)
+declare double @llvm.powi.f64(double,i32)
+declare float @llvm.exp.f32(float)
+declare double @llvm.exp2.f64(double)
+declare float @llvm.fma.f32(float,float,float)
+
+declare void @expect_equal(i1,i1)
+
+; CHECK-LABEL: @orderedLessZeroTree(
+define i1 @orderedLessZeroTree(float,float,float,float) {
+ %square = fmul float %0, %0
+ %abs = call float @llvm.fabs.f32(float %1)
+ %sqrt = call float @llvm.sqrt.f32(float %2)
+ %fma = call float @llvm.fma.f32(float %3, float %3, float %sqrt)
+ %div = fdiv float %square, %abs
+ %rem = frem float %sqrt, %fma
+ %add = fadd float %div, %rem
+ %uge = fcmp uge float %add, 0.000000e+00
+; CHECK: ret i1 true
+ ret i1 %uge
+}
+
+; CHECK-LABEL: @orderedLessZeroExpExt(
+define i1 @orderedLessZeroExpExt(float) {
+ %a = call float @llvm.exp.f32(float %0)
+ %b = fpext float %a to double
+ %uge = fcmp uge double %b, 0.000000e+00
+; CHECK: ret i1 true
+ ret i1 %uge
+}
+
+; CHECK-LABEL: @orderedLessZeroExp2Trunc(
+define i1 @orderedLessZeroExp2Trunc(double) {
+ %a = call double @llvm.exp2.f64(double %0)
+ %b = fptrunc double %a to float
+ %olt = fcmp olt float %b, 0.000000e+00
+; CHECK: ret i1 false
+ ret i1 %olt
+}
+
+; CHECK-LABEL: @orderedLessZeroPowi(
+define i1 @orderedLessZeroPowi(double,double) {
+ ; Even constant exponent
+ %a = call double @llvm.powi.f64(double %0, i32 2)
+ %square = fmul double %1, %1
+ ; Odd constant exponent with provably non-negative base
+ %b = call double @llvm.powi.f64(double %square, i32 3)
+ %c = fadd double %a, %b
+ %olt = fcmp olt double %b, 0.000000e+00
+; CHECK: ret i1 false
+ ret i1 %olt
+}
+
diff --git a/test/Transforms/InstSimplify/load.ll b/test/Transforms/InstSimplify/load.ll
new file mode 100644
index 0000000..92953cd
--- /dev/null
+++ b/test/Transforms/InstSimplify/load.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+@zeroinit = constant {} zeroinitializer
+@undef = constant {} undef
+
+define i32 @crash_on_zeroinit() {
+; CHECK-LABEL: @crash_on_zeroinit
+; CHECK: ret i32 0
+ %load = load i32* bitcast ({}* @zeroinit to i32*)
+ ret i32 %load
+}
+
+define i32 @crash_on_undef() {
+; CHECK-LABEL: @crash_on_undef
+; CHECK: ret i32 undef
+ %load = load i32* bitcast ({}* @undef to i32*)
+ ret i32 %load
+}
+
diff --git a/test/Transforms/InstSimplify/noalias-ptr.ll b/test/Transforms/InstSimplify/noalias-ptr.ll
new file mode 100644
index 0000000..7693e55
--- /dev/null
+++ b/test/Transforms/InstSimplify/noalias-ptr.ll
@@ -0,0 +1,259 @@
+; RUN: opt -instsimplify -S < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@g1 = global i32 0, align 4
+@g2 = internal global i32 0, align 4
+@g3 = unnamed_addr global i32 0, align 4
+@g4 = hidden global i32 0, align 4
+@g5 = protected global i32 0, align 4
+@g6 = thread_local unnamed_addr global i32 0, align 4
+
+; Make sure we can simplify away a pointer comparison between
+; dynamically-allocated memory and a local stack allocation.
+; void p()
+; {
+; int *mData;
+; int mStackData[10];
+; mData = new int[12];
+; if (mData != mStackData) {
+; delete[] mData;
+; }
+; }
+
+define void @_Z2p1v() #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = tail call noalias i8* @_Znam(i64 48) #4
+ %3 = bitcast i8* %2 to i32*
+ %4 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %5 = icmp eq i32* %3, %4
+ br i1 %5, label %7, label %6
+
+; CHECK-LABEL: @_Z2p1v
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:6 ; preds = %0
+ call void @_ZdaPv(i8* %2) #5
+ br label %7
+
+; <label>:7 ; preds = %0, %6
+ ret void
+}
+
+; Also check a more-complicated case with multiple underlying objects.
+
+define void @_Z2p2bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g2
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p2bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p4bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g3
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p4bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p5bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g4
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p5bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p6bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g5
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p6bb
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+; Here's another case involving multiple underlying objects, but this time we
+; must keep the comparison (it might involve a regular pointer-typed function
+; argument).
+
+define void @_Z4nopebbPi(i1 zeroext %b1, i1 zeroext %b2, i32* readnone %q) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* %q
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z4nopebbPi
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p3bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g1
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p3bb
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p7bb(i1 zeroext %b1, i1 zeroext %b2) #0 {
+ %mStackData = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %3 = select i1 %b1, i32* %2, i32* @g6
+ %4 = tail call noalias i8* @_Znam(i64 48) #4
+ %5 = tail call noalias i8* @_Znam(i64 48) #4
+ %.v = select i1 %b2, i8* %4, i8* %5
+ %6 = bitcast i8* %.v to i32*
+ %7 = icmp eq i32* %6, %3
+ br i1 %7, label %9, label %8
+
+; CHECK-LABEL: @_Z2p7bb
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:8 ; preds = %0
+ call void @_ZdaPv(i8* %4) #5
+ call void @_ZdaPv(i8* %5) #5
+ br label %9
+
+; <label>:9 ; preds = %0, %8
+ ret void
+}
+
+define void @_Z2p2v(i32 %c) #0 {
+ %mStackData = alloca [10 x i32], i32 %c, align 16
+ %1 = bitcast [10 x i32]* %mStackData to i8*
+ %2 = tail call noalias i8* @_Znam(i64 48) #4
+ %3 = bitcast i8* %2 to i32*
+ %4 = getelementptr inbounds [10 x i32]* %mStackData, i64 0, i64 0
+ %5 = icmp eq i32* %3, %4
+ br i1 %5, label %7, label %6
+
+; CHECK-LABEL: @_Z2p2v
+; CHECK: icmp
+; CHECK: ret void
+
+; <label>:6 ; preds = %0
+ call void @_ZdaPv(i8* %2) #5
+ br label %7
+
+; <label>:7 ; preds = %0, %6
+ ret void
+}
+
+; Function Attrs: nobuiltin
+declare noalias i8* @_Znam(i64) #2
+
+; Function Attrs: nobuiltin nounwind
+declare void @_ZdaPv(i8*) #3
+
+attributes #0 = { uwtable }
+attributes #1 = { nounwind }
+attributes #2 = { nobuiltin }
+attributes #3 = { nobuiltin nounwind }
+attributes #4 = { builtin }
+attributes #5 = { builtin nounwind }
+
diff --git a/test/Transforms/InstSimplify/select.ll b/test/Transforms/InstSimplify/select.ll
new file mode 100644
index 0000000..1d45e57
--- /dev/null
+++ b/test/Transforms/InstSimplify/select.ll
@@ -0,0 +1,161 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+define i32 @test1(i32 %x) {
+ %and = and i32 %x, 1
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i32 %x, -2
+ %and1.x = select i1 %cmp, i32 %and1, i32 %x
+ ret i32 %and1.x
+; CHECK-LABEL: @test1(
+; CHECK: ret i32 %x
+}
+
+define i32 @test2(i32 %x) {
+ %and = and i32 %x, 1
+ %cmp = icmp ne i32 %and, 0
+ %and1 = and i32 %x, -2
+ %and1.x = select i1 %cmp, i32 %x, i32 %and1
+ ret i32 %and1.x
+; CHECK-LABEL: @test2(
+; CHECK: ret i32 %x
+}
+
+define i32 @test3(i32 %x) {
+ %and = and i32 %x, 1
+ %cmp = icmp ne i32 %and, 0
+ %and1 = and i32 %x, -2
+ %and1.x = select i1 %cmp, i32 %and1, i32 %x
+ ret i32 %and1.x
+; CHECK-LABEL: @test3(
+; CHECK: %[[and:.*]] = and i32 %x, -2
+; CHECK: ret i32 %[[and]]
+}
+
+define i32 @test4(i32 %X) {
+ %cmp = icmp slt i32 %X, 0
+ %or = or i32 %X, -2147483648
+ %cond = select i1 %cmp, i32 %X, i32 %or
+ ret i32 %cond
+; CHECK-LABEL: @test4
+; CHECK: %[[or:.*]] = or i32 %X, -2147483648
+; CHECK: ret i32 %[[or]]
+}
+
+define i32 @test5(i32 %X) {
+ %cmp = icmp slt i32 %X, 0
+ %or = or i32 %X, -2147483648
+ %cond = select i1 %cmp, i32 %or, i32 %X
+ ret i32 %cond
+; CHECK-LABEL: @test5
+; CHECK: ret i32 %X
+}
+
+define i32 @test6(i32 %X) {
+ %cmp = icmp slt i32 %X, 0
+ %and = and i32 %X, 2147483647
+ %cond = select i1 %cmp, i32 %and, i32 %X
+ ret i32 %cond
+; CHECK-LABEL: @test6
+; CHECK: %[[and:.*]] = and i32 %X, 2147483647
+; CHECK: ret i32 %[[and]]
+}
+
+define i32 @test7(i32 %X) {
+ %cmp = icmp slt i32 %X, 0
+ %and = and i32 %X, 2147483647
+ %cond = select i1 %cmp, i32 %X, i32 %and
+ ret i32 %cond
+; CHECK-LABEL: @test7
+; CHECK: ret i32 %X
+}
+
+define i32 @test8(i32 %X) {
+ %cmp = icmp sgt i32 %X, -1
+ %or = or i32 %X, -2147483648
+ %cond = select i1 %cmp, i32 %X, i32 %or
+ ret i32 %cond
+; CHECK-LABEL: @test8
+; CHECK: ret i32 %X
+}
+
+define i32 @test9(i32 %X) {
+ %cmp = icmp sgt i32 %X, -1
+ %or = or i32 %X, -2147483648
+ %cond = select i1 %cmp, i32 %or, i32 %X
+ ret i32 %cond
+; CHECK-LABEL: @test9
+; CHECK: %[[or:.*]] = or i32 %X, -2147483648
+; CHECK: ret i32 %[[or]]
+}
+
+define i32 @test10(i32 %X) {
+ %cmp = icmp sgt i32 %X, -1
+ %and = and i32 %X, 2147483647
+ %cond = select i1 %cmp, i32 %and, i32 %X
+ ret i32 %cond
+; CHECK-LABEL: @test10
+; CHECK: ret i32 %X
+}
+
+define i32 @test11(i32 %X) {
+ %cmp = icmp sgt i32 %X, -1
+ %and = and i32 %X, 2147483647
+ %cond = select i1 %cmp, i32 %X, i32 %and
+ ret i32 %cond
+; CHECK-LABEL: @test11
+; CHECK: %[[and:.*]] = and i32 %X, 2147483647
+; CHECK: ret i32 %[[and]]
+}
+
+; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %or = or i32 %x, 8
+ %or.x = select i1 %cmp, i32 %or, i32 %x
+ ret i32 %or.x
+}
+
+; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
+; CHECK-NEXT: ret i32 [[AND]]
+define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i32 %x, -9
+ %x.and1 = select i1 %cmp, i32 %x, i32 %and1
+ ret i32 %x.and1
+}
+
+; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
+; CHECK-NEXT: ret i32 %x
+define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i32 %x, -9
+ %and1.x = select i1 %cmp, i32 %and1, i32 %x
+ ret i32 %and1.x
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
+; CHECK: select i1 %cmp, i64 %y, i64 %and1
+define i64 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i64 %y, -9
+ %y.and1 = select i1 %cmp, i64 %y, i64 %and1
+ ret i64 %y.and1
+}
+
+; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_and_not_8(
+; CHECK: select i1 %cmp, i64 %and1, i64 %y
+define i64 @select_icmp_x_and_8_ne_0_y_and_not_8(i32 %x, i64 %y) {
+ %and = and i32 %x, 8
+ %cmp = icmp eq i32 %and, 0
+ %and1 = and i64 %y, -9
+ %and1.y = select i1 %cmp, i64 %and1, i64 %y
+ ret i64 %and1.y
+}
+
diff --git a/test/Transforms/InstSimplify/undef.ll b/test/Transforms/InstSimplify/undef.ll
index 181c2ef..e8b49b6 100644
--- a/test/Transforms/InstSimplify/undef.ll
+++ b/test/Transforms/InstSimplify/undef.ll
@@ -160,3 +160,108 @@ define <4 x i8> @test19(<4 x i8> %a) {
%b = shl <4 x i8> %a, <i8 8, i8 9, i8 undef, i8 -1>
ret <4 x i8> %b
}
+
+; CHECK-LABEL: @test20
+; CHECK: ret i32 undef
+define i32 @test20(i32 %a) {
+ %b = udiv i32 %a, 0
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test21
+; CHECK: ret i32 undef
+define i32 @test21(i32 %a) {
+ %b = sdiv i32 %a, 0
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test22
+; CHECK: ret i32 undef
+define i32 @test22(i32 %a) {
+ %b = ashr exact i32 undef, %a
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test23
+; CHECK: ret i32 undef
+define i32 @test23(i32 %a) {
+ %b = lshr exact i32 undef, %a
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test24
+; CHECK: ret i32 undef
+define i32 @test24() {
+ %b = udiv i32 undef, 0
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test25
+; CHECK: ret i32 undef
+define i32 @test25() {
+ %b = lshr i32 0, undef
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test26
+; CHECK: ret i32 undef
+define i32 @test26() {
+ %b = ashr i32 0, undef
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test27
+; CHECK: ret i32 undef
+define i32 @test27() {
+ %b = shl i32 0, undef
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test28
+; CHECK: ret i32 undef
+define i32 @test28(i32 %a) {
+ %b = shl nsw i32 undef, %a
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test29
+; CHECK: ret i32 undef
+define i32 @test29(i32 %a) {
+ %b = shl nuw i32 undef, %a
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test30
+; CHECK: ret i32 undef
+define i32 @test30(i32 %a) {
+ %b = shl nsw nuw i32 undef, %a
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test31
+; CHECK: ret i32 0
+define i32 @test31(i32 %a) {
+ %b = shl i32 undef, %a
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test32
+; CHECK: ret i32 undef
+define i32 @test32(i32 %a) {
+ %b = shl i32 undef, 0
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test33
+; CHECK: ret i32 undef
+define i32 @test33(i32 %a) {
+ %b = ashr i32 undef, 0
+ ret i32 %b
+}
+
+; CHECK-LABEL: @test34
+; CHECK: ret i32 undef
+define i32 @test34(i32 %a) {
+ %b = lshr i32 undef, 0
+ ret i32 %b
+}
diff --git a/test/Transforms/JumpThreading/conservative-lvi.ll b/test/Transforms/JumpThreading/conservative-lvi.ll
new file mode 100644
index 0000000..1ea8cdc
--- /dev/null
+++ b/test/Transforms/JumpThreading/conservative-lvi.ll
@@ -0,0 +1,58 @@
+; RUN: opt -jump-threading -S %s | FileCheck %s
+
+; Check that we thread arg2neg -> checkpos -> end.
+;
+; LazyValueInfo would previously fail to analyze the value of %arg in arg2neg
+; because its predecessing blocks (checkneg) hadn't been processed yet (PR21238)
+
+; CHECK-LABEL: @test_jump_threading
+; CHECK: arg2neg:
+; CHECK-NEXT: br i1 %arg1, label %end, label %checkpos.thread
+; CHECK: checkpos.thread:
+; CHECK-NEXT: br label %end
+
+define i32 @test_jump_threading(i1 %arg1, i32 %arg2) {
+checkneg:
+ %cmp = icmp slt i32 %arg2, 0
+ br i1 %cmp, label %arg2neg, label %checkpos
+
+arg2neg:
+ br i1 %arg1, label %end, label %checkpos
+
+checkpos:
+ %cmp2 = icmp sgt i32 %arg2, 0
+ br i1 %cmp2, label %arg2pos, label %end
+
+arg2pos:
+ br label %end
+
+end:
+ %0 = phi i32 [ 1, %arg2neg ], [ 2, %checkpos ], [ 3, %arg2pos ]
+ ret i32 %0
+}
+
+
+; arg2neg has an edge back to itself. If LazyValueInfo is not careful when
+; visiting predecessors, it could get into an infinite loop.
+
+; CHECK-LABEL: test_infinite_loop
+
+define i32 @test_infinite_loop(i1 %arg1, i32 %arg2) {
+checkneg:
+ %cmp = icmp slt i32 %arg2, 0
+ br i1 %cmp, label %arg2neg, label %checkpos
+
+arg2neg:
+ br i1 %arg1, label %arg2neg, label %checkpos
+
+checkpos:
+ %cmp2 = icmp sgt i32 %arg2, 0
+ br i1 %cmp2, label %arg2pos, label %end
+
+arg2pos:
+ br label %end
+
+end:
+ %0 = phi i32 [ 2, %checkpos ], [ 3, %arg2pos ]
+ ret i32 %0
+}
diff --git a/test/Transforms/JumpThreading/phi-eq.ll b/test/Transforms/JumpThreading/phi-eq.ll
index e05d5ee..3dd2c36 100644
--- a/test/Transforms/JumpThreading/phi-eq.ll
+++ b/test/Transforms/JumpThreading/phi-eq.ll
@@ -101,7 +101,7 @@ get_filter_list.exit6: ; preds = %sw.bb3.i4, %sw.bb2.
%2 = load %struct._GList** %1, align 8
; We should have jump-threading insert an additional load here for the value
; coming out of the first switch, which is picked up by a subsequent phi
-; CHECK: {{%\.pr = load %[^%]* %0}}
+; CHECK: %.pr = load %struct._GList** %0
; CHECK-NEXT: br label %while.cond
br label %while.cond
diff --git a/test/Transforms/JumpThreading/pr22086.ll b/test/Transforms/JumpThreading/pr22086.ll
new file mode 100644
index 0000000..35d9aa5
--- /dev/null
+++ b/test/Transforms/JumpThreading/pr22086.ll
@@ -0,0 +1,28 @@
+; RUN: opt -S -jump-threading < %s | FileCheck %s
+
+
+; CHECK-LABEL: @f(
+; CHECK-LABEL: entry:
+; CHECK-NEXT: br label %[[loop:.*]]
+; CHECK: [[loop]]:
+; CHECK-NEXT: br label %[[loop]]
+
+define void @f() {
+entry:
+ br label %for.cond1
+
+if.end16:
+ %phi1 = phi i32 [ undef, %for.cond1 ]
+ %g.3 = phi i32 [ %g.1, %for.cond1 ]
+ %sext = shl i32 %g.3, 16
+ %conv20 = ashr exact i32 %sext, 16
+ %tobool21 = icmp eq i32 %phi1, 0
+ br i1 %tobool21, label %lor.rhs, label %for.cond1
+
+for.cond1:
+ %g.1 = phi i32 [ 0, %entry ], [ 0, %lor.rhs ], [ %g.3, %if.end16 ]
+ br i1 undef, label %lor.rhs, label %if.end16
+
+lor.rhs:
+ br label %for.cond1
+}
diff --git a/test/Transforms/JumpThreading/thread-loads.ll b/test/Transforms/JumpThreading/thread-loads.ll
index b13b767..4351f99 100644
--- a/test/Transforms/JumpThreading/thread-loads.ll
+++ b/test/Transforms/JumpThreading/thread-loads.ll
@@ -106,7 +106,7 @@ return:
ret i32 13
}
-!0 = metadata !{metadata !3, metadata !3, i64 0}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
-!3 = metadata !{metadata !"int", metadata !1}
+!0 = !{!3, !3, i64 0}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA", null}
+!3 = !{!"int", !1}
diff --git a/test/Transforms/LCSSA/indirectbr.ll b/test/Transforms/LCSSA/indirectbr.ll
index 9656448..345395b 100644
--- a/test/Transforms/LCSSA/indirectbr.ll
+++ b/test/Transforms/LCSSA/indirectbr.ll
@@ -1,11 +1,11 @@
-; RUN: opt < %s -lcssa -verify-loop-info -verify-dom-info -disable-output
-; PR5437
+; RUN: opt < %s -loop-simplify -lcssa -verify-loop-info -verify-dom-info -S | FileCheck %s
; LCSSA should work correctly in the case of an indirectbr that exits
; the loop, and the loop has exits with predecessors not within the loop
; (and btw these edges are unsplittable due to the indirectbr).
-
-define i32 @js_Interpret() nounwind {
+; PR5437
+define i32 @test0() nounwind {
+; CHECK-LABEL: @test0
entry:
br i1 undef, label %"4", label %"3"
@@ -540,3 +540,35 @@ entry:
"1862": ; preds = %"1836", %"692"
unreachable
}
+
+; An exit for Loop L1 may be the header of a disjoint Loop L2. Thus, when we
+; create PHIs in one of such exits we are also inserting PHIs in L2 header. This
+; could break LCSSA form for L2 because these inserted PHIs can also have uses
+; in L2 exits. Test that we don't assert/crash on that.
+define void @test1() {
+; CHECK-LABEL: @test1
+ br label %lab1
+
+lab1:
+ %tmp21 = add i32 undef, 677038203
+ br i1 undef, label %lab2, label %exit
+
+lab2:
+ indirectbr i8* undef, [label %lab1, label %lab3]
+
+lab3:
+; CHECK: %tmp21.lcssa1 = phi i32 [ %tmp21.lcssa1, %lab4 ], [ %tmp21, %lab2 ]
+ %tmp12 = phi i32 [ %tmp21, %lab2 ], [ %tmp12, %lab4 ]
+ br i1 undef, label %lab5, label %lab4
+
+lab4:
+ br label %lab3
+
+lab5:
+; CHECK: %tmp21.lcssa1.lcssa = phi i32 [ %tmp21.lcssa1, %lab3 ]
+ %tmp15 = add i32 %tmp12, undef
+ br label %exit
+
+exit:
+ ret void
+}
diff --git a/test/Transforms/LCSSA/unreachable-use.ll b/test/Transforms/LCSSA/unreachable-use.ll
index 71ae134..2ea7aeb 100644
--- a/test/Transforms/LCSSA/unreachable-use.ll
+++ b/test/Transforms/LCSSA/unreachable-use.ll
@@ -1,9 +1,11 @@
-; RUN: opt < %s -lcssa -S -verify-loop-info | grep "[%]tmp33 = load i1\*\* [%]tmp"
+; RUN: opt < %s -lcssa -S -verify-loop-info | FileCheck %s
; PR6546
; LCSSA doesn't need to transform uses in blocks not reachable
; from the entry block.
+; CHECK: %tmp33 = load i1** %tmp
+
define fastcc void @dfs() nounwind {
bb:
br label %bb44
diff --git a/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll b/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll
index 7cf7a32..5587142 100644
--- a/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll
+++ b/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll
@@ -30,10 +30,10 @@ for.end: ; preds = %for.inc
ret void
}
-!0 = metadata !{metadata !5, metadata !5, i64 0}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
-!3 = metadata !{metadata !"short", metadata !1}
-!4 = metadata !{metadata !6, metadata !6, i64 0}
-!5 = metadata !{metadata !"any pointer", metadata !1}
-!6 = metadata !{metadata !"int", metadata !1}
+!0 = !{!5, !5, i64 0}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA", null}
+!3 = !{!"short", !1}
+!4 = !{!6, !6, i64 0}
+!5 = !{!"any pointer", !1}
+!6 = !{!"int", !1}
diff --git a/test/Transforms/LICM/constexpr.ll b/test/Transforms/LICM/constexpr.ll
new file mode 100644
index 0000000..f788787
--- /dev/null
+++ b/test/Transforms/LICM/constexpr.ll
@@ -0,0 +1,46 @@
+; RUN: opt < %s -S -basicaa -licm | FileCheck %s
+; This fixes PR22460
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+@in = internal unnamed_addr global i32* null, align 8
+@out = internal unnamed_addr global i32* null, align 8
+
+; CHECK-LABEL: @bar
+; CHECK: entry:
+; CHECK: load i64* bitcast (i32** @in to i64*)
+; CHECK: do.body:
+; CHECK-NOT: load
+
+define i64 @bar(i32 %N) {
+entry:
+ br label %do.body
+
+do.body: ; preds = %l2, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %l2 ]
+ %total = phi i64 [ 0, %entry ], [ %next, %l2 ]
+ %c = icmp eq i32 %N, 6
+ br i1 %c, label %l1, label %do.body.l2_crit_edge
+
+do.body.l2_crit_edge: ; preds = %do.body
+ %inval.pre = load i32** @in, align 8
+ br label %l2
+
+l1: ; preds = %do.body
+ %v1 = load i64* bitcast (i32** @in to i64*), align 8
+ store i64 %v1, i64* bitcast (i32** @out to i64*), align 8
+ %0 = inttoptr i64 %v1 to i32*
+ br label %l2
+
+l2: ; preds = %do.body.l2_crit_edge, %l1
+ %inval = phi i32* [ %inval.pre, %do.body.l2_crit_edge ], [ %0, %l1 ]
+ %int = ptrtoint i32* %inval to i64
+ %next = add i64 %total, %int
+ %inc = add nsw i32 %i.0, 1
+ %cmp = icmp slt i32 %inc, %N
+ br i1 %cmp, label %do.body, label %do.end
+
+do.end: ; preds = %l2
+ ret i64 %total
+}
diff --git a/test/Transforms/LICM/debug-value.ll b/test/Transforms/LICM/debug-value.ll
index 0e0cd39..b49c559 100644
--- a/test/Transforms/LICM/debug-value.ll
+++ b/test/Transforms/LICM/debug-value.ll
@@ -15,7 +15,7 @@ if.then: ; preds = %for.body
if.then27: ; preds = %if.then
; CHECK: tail call void @llvm.dbg.value
- tail call void @llvm.dbg.value(metadata !18, i64 0, metadata !19, metadata !{}), !dbg !21
+ tail call void @llvm.dbg.value(metadata double undef, i64 0, metadata !19, metadata !{}), !dbg !21
br label %for.body61.us
if.end.if.end.split_crit_edge.critedge: ; preds = %if.then
@@ -36,30 +36,30 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.module.flags = !{!26}
!llvm.dbg.sp = !{!0, !6, !9, !10}
-!0 = metadata !{metadata !"0x2e\00idamax\00idamax\00\00112\000\001\000\006\00256\000\000", metadata !25, metadata !1, metadata !3, i32 0, null, null, null, null} ; [ DW_TAG_subprogram ]
-!1 = metadata !{metadata !"0x29", metadata !25} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang version 2.9 (trunk 127169)\001\00\000\00\000", metadata !25, metadata !8, metadata !8, metadata !8, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !25, metadata !1, null, metadata !4, i32 0} ; [ DW_TAG_subroutine_type ]
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !2} ; [ DW_TAG_base_type ]
-!6 = metadata !{metadata !"0x2e\00dscal\00dscal\00\00206\000\001\000\006\00256\000\000", metadata !25, metadata !1, metadata !7, i32 0, null, null, null, null} ; [ DW_TAG_subprogram ]
-!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !25, metadata !1, null, metadata !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!8 = metadata !{null}
-!9 = metadata !{metadata !"0x2e\00daxpy\00daxpy\00\00230\000\001\000\006\00256\000\000", metadata !25, metadata !1, metadata !7, i32 0, null, null, null, null} ; [ DW_TAG_subprogram ]
-!10 = metadata !{metadata !"0x2e\00dgefa\00dgefa\00\00267\000\001\000\006\00256\000\000", metadata !25, metadata !1, metadata !7, null, null, null, null, null} ; [ DW_TAG_subprogram ] [line 267] [def] [scope 0] [dgefa]
-!11 = metadata !{i32 281, i32 9, metadata !12, null}
-!12 = metadata !{metadata !"0xb\00272\005\0032", metadata !25, metadata !13} ; [ DW_TAG_lexical_block ]
-!13 = metadata !{metadata !"0xb\00271\005\0031", metadata !25, metadata !14} ; [ DW_TAG_lexical_block ]
-!14 = metadata !{metadata !"0xb\00267\001\0030", metadata !25, metadata !10} ; [ DW_TAG_lexical_block ]
-!15 = metadata !{i32 271, i32 5, metadata !14, null}
-!16 = metadata !{i32 284, i32 10, metadata !17, null}
-!17 = metadata !{metadata !"0xb\00282\009\0033", metadata !25, metadata !12} ; [ DW_TAG_lexical_block ]
-!18 = metadata !{double undef}
-!19 = metadata !{metadata !"0x100\00temp\00268\000", metadata !14, metadata !1, metadata !20} ; [ DW_TAG_auto_variable ]
-!20 = metadata !{metadata !"0x24\00double\000\0064\0064\000\000\004", null, metadata !2} ; [ DW_TAG_base_type ]
-!21 = metadata !{i32 286, i32 14, metadata !22, null}
-!22 = metadata !{metadata !"0xb\00285\0013\0034", metadata !25, metadata !17} ; [ DW_TAG_lexical_block ]
-!23 = metadata !{i32 296, i32 13, metadata !17, null}
-!24 = metadata !{i32 313, i32 1, metadata !14, null}
-!25 = metadata !{metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c", metadata !"/private/tmp"}
-!26 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00idamax\00idamax\00\00112\000\001\000\006\00256\000\000", !25, !1, !3, i32 0, null, null, null, null} ; [ DW_TAG_subprogram ]
+!1 = !{!"0x29", !25} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang version 2.9 (trunk 127169)\001\00\000\00\000", !25, !8, !8, !8, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !25, !1, null, !4, i32 0} ; [ DW_TAG_subroutine_type ]
+!4 = !{!5}
+!5 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !2} ; [ DW_TAG_base_type ]
+!6 = !{!"0x2e\00dscal\00dscal\00\00206\000\001\000\006\00256\000\000", !25, !1, !7, i32 0, null, null, null, null} ; [ DW_TAG_subprogram ]
+!7 = !{!"0x15\00\000\000\000\000\000\000", !25, !1, null, !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = !{null}
+!9 = !{!"0x2e\00daxpy\00daxpy\00\00230\000\001\000\006\00256\000\000", !25, !1, !7, i32 0, null, null, null, null} ; [ DW_TAG_subprogram ]
+!10 = !{!"0x2e\00dgefa\00dgefa\00\00267\000\001\000\006\00256\000\000", !25, !1, !7, null, null, null, null, null} ; [ DW_TAG_subprogram ] [line 267] [def] [scope 0] [dgefa]
+!11 = !MDLocation(line: 281, column: 9, scope: !12)
+!12 = !{!"0xb\00272\005\0032", !25, !13} ; [ DW_TAG_lexical_block ]
+!13 = !{!"0xb\00271\005\0031", !25, !14} ; [ DW_TAG_lexical_block ]
+!14 = !{!"0xb\00267\001\0030", !25, !10} ; [ DW_TAG_lexical_block ]
+!15 = !MDLocation(line: 271, column: 5, scope: !14)
+!16 = !MDLocation(line: 284, column: 10, scope: !17)
+!17 = !{!"0xb\00282\009\0033", !25, !12} ; [ DW_TAG_lexical_block ]
+!18 = !{double undef}
+!19 = !{!"0x100\00temp\00268\000", !14, !1, !20} ; [ DW_TAG_auto_variable ]
+!20 = !{!"0x24\00double\000\0064\0064\000\000\004", null, !2} ; [ DW_TAG_base_type ]
+!21 = !MDLocation(line: 286, column: 14, scope: !22)
+!22 = !{!"0xb\00285\0013\0034", !25, !17} ; [ DW_TAG_lexical_block ]
+!23 = !MDLocation(line: 296, column: 13, scope: !17)
+!24 = !MDLocation(line: 313, column: 1, scope: !14)
+!25 = !{!"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c", !"/private/tmp"}
+!26 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/LICM/hoist-invariant-load.ll b/test/Transforms/LICM/hoist-invariant-load.ll
index 1ba94d6..59904ba 100644
--- a/test/Transforms/LICM/hoist-invariant-load.ll
+++ b/test/Transforms/LICM/hoist-invariant-load.ll
@@ -37,4 +37,4 @@ for.end: ; preds = %for.cond
declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/LICM/preheader-safe.ll b/test/Transforms/LICM/preheader-safe.ll
new file mode 100644
index 0000000..260a5f6
--- /dev/null
+++ b/test/Transforms/LICM/preheader-safe.ll
@@ -0,0 +1,69 @@
+; RUN: opt -S -licm < %s | FileCheck %s
+
+declare void @use_nothrow(i64 %a) nounwind
+declare void @use(i64 %a)
+
+define void @nothrow(i64 %x, i64 %y, i1* %cond) {
+; CHECK-LABEL: nothrow
+; CHECK-LABEL: entry
+; CHECK: %div = udiv i64 %x, %y
+; CHECK-LABEL: loop
+; CHECK: call void @use_nothrow(i64 %div)
+entry:
+ br label %loop
+
+loop: ; preds = %entry, %for.inc
+ %div = udiv i64 %x, %y
+ call void @use_nothrow(i64 %div)
+ br label %loop
+}
+; Negative test
+define void @throw_header(i64 %x, i64 %y, i1* %cond) {
+; CHECK-LABEL: throw_header
+; CHECK-LABEL: loop
+; CHECK: %div = udiv i64 %x, %y
+; CHECK: call void @use(i64 %div)
+entry:
+ br label %loop
+
+loop: ; preds = %entry, %for.inc
+ %div = udiv i64 %x, %y
+ call void @use(i64 %div)
+ br label %loop
+}
+
+; The header is known no throw, but the loop is not. We can
+; still lift out of the header.
+define void @nothrow_header(i64 %x, i64 %y, i1 %cond) {
+; CHECK-LABEL: nothrow_header
+; CHECK-LABEL: entry
+; CHECK: %div = udiv i64 %x, %y
+; CHECK-LABEL: loop
+; CHECK: call void @use(i64 %div)
+entry:
+ br label %loop
+loop: ; preds = %entry, %for.inc
+ %div = udiv i64 %x, %y
+ br i1 %cond, label %loop-if, label %exit
+loop-if:
+ call void @use(i64 %div)
+ br label %loop
+exit:
+ ret void
+}
+; Negative test - can't move out of throwing block
+define void @nothrow_header_neg(i64 %x, i64 %y, i1 %cond) {
+; CHECK-LABEL: nothrow_header_neg
+; CHECK-LABEL: entry
+; CHECK-LABEL: loop
+; CHECK: %div = udiv i64 %x, %y
+; CHECK: call void @use(i64 %div)
+entry:
+ br label %loop
+loop: ; preds = %entry, %for.inc
+ br label %loop-if
+loop-if:
+ %div = udiv i64 %x, %y
+ call void @use(i64 %div)
+ br label %loop
+}
diff --git a/test/Transforms/LICM/promote-order.ll b/test/Transforms/LICM/promote-order.ll
index 86f11fe..a189cf2 100644
--- a/test/Transforms/LICM/promote-order.ll
+++ b/test/Transforms/LICM/promote-order.ll
@@ -36,8 +36,8 @@ for.end: ; preds = %for.cond.for.end_cr
ret i32* %r.0.lcssa
}
-!0 = metadata !{metadata !"minimal TBAA"}
-!1 = metadata !{metadata !3, metadata !3, i64 0}
-!2 = metadata !{metadata !4, metadata !4, i64 0}
-!3 = metadata !{metadata !"float", metadata !0}
-!4 = metadata !{metadata !"int", metadata !0}
+!0 = !{!"minimal TBAA"}
+!1 = !{!3, !3, i64 0}
+!2 = !{!4, !4, i64 0}
+!3 = !{!"float", !0}
+!4 = !{!"int", !0}
diff --git a/test/Transforms/LICM/scalar_promote.ll b/test/Transforms/LICM/scalar_promote.ll
index d7e7c6e..80afb3c 100644
--- a/test/Transforms/LICM/scalar_promote.ll
+++ b/test/Transforms/LICM/scalar_promote.ll
@@ -185,9 +185,9 @@ for.end: ; preds = %for.cond.for.end_cr
; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* %gi, align 4, !tbaa !0
}
-!0 = metadata !{metadata !4, metadata !4, i64 0}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA"}
-!3 = metadata !{metadata !5, metadata !5, i64 0}
-!4 = metadata !{metadata !"int", metadata !1}
-!5 = metadata !{metadata !"float", metadata !1}
+!0 = !{!4, !4, i64 0}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!5, !5, i64 0}
+!4 = !{!"int", !1}
+!5 = !{!"float", !1}
diff --git a/test/Transforms/LICM/sinking.ll b/test/Transforms/LICM/sinking.ll
index ccc9186..d7a8fcd 100644
--- a/test/Transforms/LICM/sinking.ll
+++ b/test/Transforms/LICM/sinking.ll
@@ -314,6 +314,84 @@ exit:
ret i32 %lcssa
}
+; Can't sink stores out of exit blocks containing indirectbr instructions
+; because loop simplify does not create dedicated exits for such blocks. Test
+; that by sinking the store from lab21 to lab22, but not further.
+define void @test12() {
+; CHECK-LABEL: @test12
+ br label %lab4
+
+lab4:
+ br label %lab20
+
+lab5:
+ br label %lab20
+
+lab6:
+ br label %lab4
+
+lab7:
+ br i1 undef, label %lab8, label %lab13
+
+lab8:
+ br i1 undef, label %lab13, label %lab10
+
+lab10:
+ br label %lab7
+
+lab13:
+ ret void
+
+lab20:
+ br label %lab21
+
+lab21:
+; CHECK: lab21:
+; CHECK-NOT: store
+; CHECK: br i1 false, label %lab21, label %lab22
+ store i32 36127957, i32* undef, align 4
+ br i1 undef, label %lab21, label %lab22
+
+lab22:
+; CHECK: lab22:
+; CHECK: store
+; CHECK-NEXT: indirectbr i8* undef
+ indirectbr i8* undef, [label %lab5, label %lab6, label %lab7]
+}
+
+; Test that we don't crash when trying to sink stores and there's no preheader
+; available (which is used for creating loads that may be used by the SSA
+; updater)
+define void @test13() {
+; CHECK-LABEL: @test13
+ br label %lab59
+
+lab19:
+ br i1 undef, label %lab20, label %lab38
+
+lab20:
+ br label %lab60
+
+lab21:
+ br i1 undef, label %lab22, label %lab38
+
+lab22:
+ br label %lab38
+
+lab38:
+ ret void
+
+lab59:
+ indirectbr i8* undef, [label %lab60, label %lab38]
+
+lab60:
+; CHECK: lab60:
+; CHECK: store
+; CHECK-NEXT: indirectbr
+ store i32 2145244101, i32* undef, align 4
+ indirectbr i8* undef, [label %lab21, label %lab19]
+}
+
declare void @f(i32*)
declare void @g()
diff --git a/test/Transforms/LoopIdiom/debug-line.ll b/test/Transforms/LoopIdiom/debug-line.ll
index ea3c4de..863df3c 100644
--- a/test/Transforms/LoopIdiom/debug-line.ll
+++ b/test/Transforms/LoopIdiom/debug-line.ll
@@ -5,8 +5,8 @@ target triple = "x86_64-apple-darwin10.0.0"
define void @foo(double* nocapture %a) nounwind ssp {
entry:
- tail call void @llvm.dbg.value(metadata !{double* %a}, i64 0, metadata !5, metadata !{}), !dbg !8
- tail call void @llvm.dbg.value(metadata !9, i64 0, metadata !10, metadata !{}), !dbg !14
+ tail call void @llvm.dbg.value(metadata double* %a, i64 0, metadata !5, metadata !{}), !dbg !8
+ tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !10, metadata !{}), !dbg !14
br label %for.body
for.body: ; preds = %entry, %for.body
@@ -30,23 +30,23 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.module.flags = !{!19}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\002\000\001\000\006\00256\000\000", metadata !18, metadata !1, metadata !3, null, void (double*)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 2] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !18} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang version 2.9 (trunk 127165:127174)\001\00\000\00\000", metadata !18, metadata !9, metadata !9, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !18, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{metadata !"0x101\00a\0016777218\000", metadata !0, metadata !1, metadata !6} ; [ DW_TAG_arg_variable ]
-!6 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, metadata !2, metadata !7} ; [ DW_TAG_pointer_type ]
-!7 = metadata !{metadata !"0x24\00double\000\0064\0064\000\000\004", null, metadata !2} ; [ DW_TAG_base_type ]
-!8 = metadata !{i32 2, i32 18, metadata !0, null}
-!9 = metadata !{i32 0}
-!10 = metadata !{metadata !"0x100\00i\003\000", metadata !11, metadata !1, metadata !13} ; [ DW_TAG_auto_variable ]
-!11 = metadata !{metadata !"0xb\003\003\001", metadata !18, metadata !12} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{metadata !"0xb\002\0021\000", metadata !18, metadata !0} ; [ DW_TAG_lexical_block ]
-!13 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !2} ; [ DW_TAG_base_type ]
-!14 = metadata !{i32 3, i32 3, metadata !12, null}
-!15 = metadata !{i32 4, i32 5, metadata !11, null}
-!16 = metadata !{i32 3, i32 29, metadata !11, null}
-!17 = metadata !{i32 5, i32 1, metadata !12, null}
-!18 = metadata !{metadata !"li.c", metadata !"/private/tmp"}
-!19 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00\002\000\001\000\006\00256\000\000", !18, !1, !3, null, void (double*)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 2] [def] [scope 0] [foo]
+!1 = !{!"0x29", !18} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang version 2.9 (trunk 127165:127174)\001\00\000\00\000", !18, !9, !9, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !18, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !{!"0x101\00a\0016777218\000", !0, !1, !6} ; [ DW_TAG_arg_variable ]
+!6 = !{!"0xf\00\000\0064\0064\000\000", null, !2, !7} ; [ DW_TAG_pointer_type ]
+!7 = !{!"0x24\00double\000\0064\0064\000\000\004", null, !2} ; [ DW_TAG_base_type ]
+!8 = !MDLocation(line: 2, column: 18, scope: !0)
+!9 = !{i32 0}
+!10 = !{!"0x100\00i\003\000", !11, !1, !13} ; [ DW_TAG_auto_variable ]
+!11 = !{!"0xb\003\003\001", !18, !12} ; [ DW_TAG_lexical_block ]
+!12 = !{!"0xb\002\0021\000", !18, !0} ; [ DW_TAG_lexical_block ]
+!13 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !2} ; [ DW_TAG_base_type ]
+!14 = !MDLocation(line: 3, column: 3, scope: !12)
+!15 = !MDLocation(line: 4, column: 5, scope: !11)
+!16 = !MDLocation(line: 3, column: 29, scope: !11)
+!17 = !MDLocation(line: 5, column: 1, scope: !12)
+!18 = !{!"li.c", !"/private/tmp"}
+!19 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/LoopReroll/basic.ll b/test/Transforms/LoopReroll/basic.ll
index 3bd6d7a..7533461 100644
--- a/test/Transforms/LoopReroll/basic.ll
+++ b/test/Transforms/LoopReroll/basic.ll
@@ -322,6 +322,260 @@ for.end: ; preds = %for.body
ret void
}
+; void multi1(int *x) {
+; y = foo(0)
+; for (int i = 0; i < 500; ++i) {
+; x[3*i] = y;
+; x[3*i+1] = y;
+; x[3*i+2] = y;
+; x[3*i+6] = y;
+; x[3*i+7] = y;
+; x[3*i+8] = y;
+; }
+; }
+
+; Function Attrs: nounwind uwtable
+define void @multi1(i32* nocapture %x) #0 {
+entry:
+ %call = tail call i32 @foo(i32 0) #1
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %0 = mul nsw i64 %indvars.iv, 3
+ %arrayidx = getelementptr inbounds i32* %x, i64 %0
+ store i32 %call, i32* %arrayidx, align 4
+ %1 = add nsw i64 %0, 1
+ %arrayidx4 = getelementptr inbounds i32* %x, i64 %1
+ store i32 %call, i32* %arrayidx4, align 4
+ %2 = add nsw i64 %0, 2
+ %arrayidx9 = getelementptr inbounds i32* %x, i64 %2
+ store i32 %call, i32* %arrayidx9, align 4
+ %3 = add nsw i64 %0, 6
+ %arrayidx6 = getelementptr inbounds i32* %x, i64 %3
+ store i32 %call, i32* %arrayidx6, align 4
+ %4 = add nsw i64 %0, 7
+ %arrayidx7 = getelementptr inbounds i32* %x, i64 %4
+ store i32 %call, i32* %arrayidx7, align 4
+ %5 = add nsw i64 %0, 8
+ %arrayidx8 = getelementptr inbounds i32* %x, i64 %5
+ store i32 %call, i32* %arrayidx8, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 500
+ br i1 %exitcond, label %for.end, label %for.body
+
+; CHECK-LABEL: @multi1
+
+; CHECK:for.body:
+; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+; CHECK: %0 = add i64 %indvars.iv, 6
+; CHECK: %arrayidx = getelementptr inbounds i32* %x, i64 %indvars.iv
+; CHECK: store i32 %call, i32* %arrayidx, align 4
+; CHECK: %arrayidx6 = getelementptr inbounds i32* %x, i64 %0
+; CHECK: store i32 %call, i32* %arrayidx6, align 4
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: %exitcond2 = icmp eq i64 %0, 1505
+; CHECK: br i1 %exitcond2, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; void multi2(int *x) {
+; y = foo(0)
+; for (int i = 0; i < 500; ++i) {
+; x[3*i] = y;
+; x[3*i+1] = y;
+; x[3*i+2] = y;
+; x[3*(i+1)] = y;
+; x[3*(i+1)+1] = y;
+; x[3*(i+1)+2] = y;
+; }
+; }
+
+; Function Attrs: nounwind uwtable
+define void @multi2(i32* nocapture %x) #0 {
+entry:
+ %call = tail call i32 @foo(i32 0) #1
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %0 = mul nsw i64 %indvars.iv, 3
+ %add = add nsw i64 %indvars.iv, 1
+ %newmul = mul nsw i64 %add, 3
+ %arrayidx = getelementptr inbounds i32* %x, i64 %0
+ store i32 %call, i32* %arrayidx, align 4
+ %1 = add nsw i64 %0, 1
+ %arrayidx4 = getelementptr inbounds i32* %x, i64 %1
+ store i32 %call, i32* %arrayidx4, align 4
+ %2 = add nsw i64 %0, 2
+ %arrayidx9 = getelementptr inbounds i32* %x, i64 %2
+ store i32 %call, i32* %arrayidx9, align 4
+ %arrayidx6 = getelementptr inbounds i32* %x, i64 %newmul
+ store i32 %call, i32* %arrayidx6, align 4
+ %3 = add nsw i64 %newmul, 1
+ %arrayidx7 = getelementptr inbounds i32* %x, i64 %3
+ store i32 %call, i32* %arrayidx7, align 4
+ %4 = add nsw i64 %newmul, 2
+ %arrayidx8 = getelementptr inbounds i32* %x, i64 %4
+ store i32 %call, i32* %arrayidx8, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 500
+ br i1 %exitcond, label %for.end, label %for.body
+
+; CHECK-LABEL: @multi2
+
+; CHECK:for.body:
+; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+; CHECK: %0 = add i64 %indvars.iv, 3
+; CHECK: %arrayidx = getelementptr inbounds i32* %x, i64 %indvars.iv
+; CHECK: store i32 %call, i32* %arrayidx, align 4
+; CHECK: %arrayidx6 = getelementptr inbounds i32* %x, i64 %0
+; CHECK: store i32 %call, i32* %arrayidx6, align 4
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: %exitcond2 = icmp eq i64 %indvars.iv, 1499
+; CHECK: br i1 %exitcond2, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; void multi3(int *x) {
+; y = foo(0)
+; for (int i = 0; i < 500; ++i) {
+; // Note: No zero index
+; x[3*i+3] = y;
+; x[3*i+4] = y;
+; x[3*i+5] = y;
+; }
+; }
+
+; Function Attrs: nounwind uwtable
+define void @multi3(i32* nocapture %x) #0 {
+entry:
+ %call = tail call i32 @foo(i32 0) #1
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %0 = mul nsw i64 %indvars.iv, 3
+ %x0 = add nsw i64 %0, 3
+ %add = add nsw i64 %indvars.iv, 1
+ %arrayidx = getelementptr inbounds i32* %x, i64 %x0
+ store i32 %call, i32* %arrayidx, align 4
+ %1 = add nsw i64 %0, 4
+ %arrayidx4 = getelementptr inbounds i32* %x, i64 %1
+ store i32 %call, i32* %arrayidx4, align 4
+ %2 = add nsw i64 %0, 5
+ %arrayidx9 = getelementptr inbounds i32* %x, i64 %2
+ store i32 %call, i32* %arrayidx9, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 500
+ br i1 %exitcond, label %for.end, label %for.body
+
+; CHECK-LABEL: @multi3
+; CHECK: for.body:
+; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+; CHECK: %0 = add i64 %indvars.iv, 3
+; CHECK: %arrayidx = getelementptr inbounds i32* %x, i64 %0
+; CHECK: store i32 %call, i32* %arrayidx, align 4
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: %exitcond1 = icmp eq i64 %0, 1502
+; CHECK: br i1 %exitcond1, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; int foo(int a);
+; void bar2(int *x, int y, int z) {
+; for (int i = 0; i < 500; i += 3) {
+; foo(i+y+i*z); // Slightly reordered instruction order
+; foo(i+1+y+(i+1)*z);
+; foo(i+2+y+(i+2)*z);
+; }
+; }
+
+; Function Attrs: nounwind uwtable
+define void @bar2(i32* nocapture readnone %x, i32 %y, i32 %z) #0 {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
+
+ %tmp1 = add i32 %i.08, %y
+ %tmp2 = mul i32 %i.08, %z
+ %tmp3 = add i32 %tmp2, %tmp1
+ %call = tail call i32 @foo(i32 %tmp3) #1
+
+ %add = add nsw i32 %i.08, 1
+ %tmp2a = mul i32 %add, %z
+ %tmp1a = add i32 %add, %y
+ %tmp3a = add i32 %tmp2a, %tmp1a
+ %calla = tail call i32 @foo(i32 %tmp3a) #1
+
+ %add2 = add nsw i32 %i.08, 2
+ %tmp2b = mul i32 %add2, %z
+ %tmp1b = add i32 %add2, %y
+ %tmp3b = add i32 %tmp2b, %tmp1b
+ %callb = tail call i32 @foo(i32 %tmp3b) #1
+
+ %add3 = add nsw i32 %i.08, 3
+
+ %exitcond = icmp eq i32 %add3, 500
+ br i1 %exitcond, label %for.end, label %for.body
+
+; CHECK-LABEL: @bar2
+
+; CHECK: for.body:
+; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
+; CHECK: %tmp1 = add i32 %indvar, %y
+; CHECK: %tmp2 = mul i32 %indvar, %z
+; CHECK: %tmp3 = add i32 %tmp2, %tmp1
+; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1
+; CHECK: %indvar.next = add i32 %indvar, 1
+; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
+; CHECK: br i1 %exitcond1, label %for.end, label %for.body
+
+; CHECK: ret
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+%struct.s = type { i32, i32 }
+
+; Function Attrs: nounwind uwtable
+define void @gep1(%struct.s* nocapture %x) #0 {
+entry:
+ %call = tail call i32 @foo(i32 0) #1
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %0 = mul nsw i64 %indvars.iv, 3
+ %arrayidx = getelementptr inbounds %struct.s* %x, i64 %0, i32 0
+ store i32 %call, i32* %arrayidx, align 4
+ %1 = add nsw i64 %0, 1
+ %arrayidx4 = getelementptr inbounds %struct.s* %x, i64 %1, i32 0
+ store i32 %call, i32* %arrayidx4, align 4
+ %2 = add nsw i64 %0, 2
+ %arrayidx9 = getelementptr inbounds %struct.s* %x, i64 %2, i32 0
+ store i32 %call, i32* %arrayidx9, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 500
+ br i1 %exitcond, label %for.end, label %for.body
+
+; CHECK-LABEL: @gep1
+; This test is a crash test only.
+; CHECK: ret
+for.end: ; preds = %for.body
+ ret void
+}
+
+
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind }
diff --git a/test/Transforms/LoopReroll/reduction.ll b/test/Transforms/LoopReroll/reduction.ll
index c9991c7..a4f168a 100644
--- a/test/Transforms/LoopReroll/reduction.ll
+++ b/test/Transforms/LoopReroll/reduction.ll
@@ -92,5 +92,41 @@ for.end: ; preds = %for.body
ret float %add12
}
+define i32 @foo_unusedphi(i32* nocapture readonly %x) #0 {
+entry:
+ br label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %r.029 = phi i32 [ 0, %entry ], [ %add12, %for.body ]
+ %arrayidx = getelementptr inbounds i32* %x, i64 %indvars.iv
+ %0 = load i32* %arrayidx, align 4
+ %add = add nsw i32 %0, %0
+ %1 = or i64 %indvars.iv, 1
+ %arrayidx3 = getelementptr inbounds i32* %x, i64 %1
+ %2 = load i32* %arrayidx3, align 4
+ %add4 = add nsw i32 %add, %2
+ %3 = or i64 %indvars.iv, 2
+ %arrayidx7 = getelementptr inbounds i32* %x, i64 %3
+ %4 = load i32* %arrayidx7, align 4
+ %add8 = add nsw i32 %add4, %4
+ %5 = or i64 %indvars.iv, 3
+ %arrayidx11 = getelementptr inbounds i32* %x, i64 %5
+ %6 = load i32* %arrayidx11, align 4
+ %add12 = add nsw i32 %add8, %6
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
+ %7 = trunc i64 %indvars.iv.next to i32
+ %cmp = icmp slt i32 %7, 400
+ br i1 %cmp, label %for.body, label %for.end
+
+; CHECK-LABEL: @foo_unusedphi
+; The above is just testing for a crash - no specific output expected.
+
+; CHECK: ret
+
+for.end: ; preds = %for.body
+ ret i32 %add12
+}
+
attributes #0 = { nounwind readonly uwtable }
diff --git a/test/Transforms/LoopRotate/crash.ll b/test/Transforms/LoopRotate/crash.ll
index fd922cb..e95f9a1 100644
--- a/test/Transforms/LoopRotate/crash.ll
+++ b/test/Transforms/LoopRotate/crash.ll
@@ -153,3 +153,21 @@ entry:
"5": ; preds = %"3", %entry
ret void
}
+
+; PR21968
+define void @test8(i1 %C, i8* %P) #0 {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ br i1 %C, label %l_bad, label %for.body
+
+for.body: ; preds = %for.cond
+ indirectbr i8* %P, [label %for.inc, label %l_bad]
+
+for.inc: ; preds = %for.body
+ br label %for.cond
+
+l_bad: ; preds = %for.body, %for.cond
+ ret void
+}
diff --git a/test/Transforms/LoopRotate/dbgvalue.ll b/test/Transforms/LoopRotate/dbgvalue.ll
index 4da0776..846b366 100644
--- a/test/Transforms/LoopRotate/dbgvalue.ll
+++ b/test/Transforms/LoopRotate/dbgvalue.ll
@@ -6,7 +6,7 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
define i32 @tak(i32 %x, i32 %y, i32 %z) nounwind ssp {
; CHECK-LABEL: define i32 @tak(
; CHECK: entry
-; CHECK-NEXT: call void @llvm.dbg.value(metadata !{i32 %x}
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %x
entry:
br label %tailrecurse
@@ -15,9 +15,9 @@ tailrecurse: ; preds = %if.then, %entry
%x.tr = phi i32 [ %x, %entry ], [ %call, %if.then ]
%y.tr = phi i32 [ %y, %entry ], [ %call9, %if.then ]
%z.tr = phi i32 [ %z, %entry ], [ %call14, %if.then ]
- tail call void @llvm.dbg.value(metadata !{i32 %x.tr}, i64 0, metadata !6, metadata !{}), !dbg !7
- tail call void @llvm.dbg.value(metadata !{i32 %y.tr}, i64 0, metadata !8, metadata !{}), !dbg !9
- tail call void @llvm.dbg.value(metadata !{i32 %z.tr}, i64 0, metadata !10, metadata !{}), !dbg !11
+ tail call void @llvm.dbg.value(metadata i32 %x.tr, i64 0, metadata !6, metadata !{}), !dbg !7
+ tail call void @llvm.dbg.value(metadata i32 %y.tr, i64 0, metadata !8, metadata !{}), !dbg !9
+ tail call void @llvm.dbg.value(metadata i32 %z.tr, i64 0, metadata !10, metadata !{}), !dbg !11
%cmp = icmp slt i32 %y.tr, %x.tr, !dbg !12
br i1 %cmp, label %if.then, label %if.end, !dbg !12
@@ -72,7 +72,7 @@ for.body:
for.inc:
%dec = add i64 %i.0, -1
- tail call void @llvm.dbg.value(metadata !{i64 %dec}, i64 0, metadata !{metadata !"undef"}, metadata !{})
+ tail call void @llvm.dbg.value(metadata i64 %dec, i64 0, metadata !{!"undef"}, metadata !{})
br label %for.cond
for.end:
@@ -84,24 +84,24 @@ for.end:
!llvm.module.flags = !{!20}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00tak\00tak\00\0032\000\001\000\006\00256\000\000", metadata !18, metadata !1, metadata !3, null, i32 (i32, i32, i32)* @tak, null, null, null} ; [ DW_TAG_subprogram ] [line 32] [def] [scope 0] [tak]
-!1 = metadata !{metadata !"0x29", metadata !18} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang version 2.9 (trunk 125492)\001\00\000\00\000", metadata !18, metadata !19, metadata !19, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !18, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !2} ; [ DW_TAG_base_type ]
-!6 = metadata !{metadata !"0x101\00x\0032\000", metadata !0, metadata !1, metadata !5} ; [ DW_TAG_arg_variable ]
-!7 = metadata !{i32 32, i32 13, metadata !0, null}
-!8 = metadata !{metadata !"0x101\00y\0032\000", metadata !0, metadata !1, metadata !5} ; [ DW_TAG_arg_variable ]
-!9 = metadata !{i32 32, i32 20, metadata !0, null}
-!10 = metadata !{metadata !"0x101\00z\0032\000", metadata !0, metadata !1, metadata !5} ; [ DW_TAG_arg_variable ]
-!11 = metadata !{i32 32, i32 27, metadata !0, null}
-!12 = metadata !{i32 33, i32 3, metadata !13, null}
-!13 = metadata !{metadata !"0xb\0032\0030\006", metadata !18, metadata !0} ; [ DW_TAG_lexical_block ]
-!14 = metadata !{i32 34, i32 5, metadata !15, null}
-!15 = metadata !{metadata !"0xb\0033\0014\007", metadata !18, metadata !13} ; [ DW_TAG_lexical_block ]
-!16 = metadata !{i32 36, i32 3, metadata !13, null}
-!17 = metadata !{i32 37, i32 1, metadata !13, null}
-!18 = metadata !{metadata !"/Volumes/Lalgate/cj/llvm/projects/llvm-test/SingleSource/Benchmarks/BenchmarkGame/recursive.c", metadata !"/Volumes/Lalgate/cj/D/projects/llvm-test/SingleSource/Benchmarks/BenchmarkGame"}
-!19 = metadata !{i32 0}
-!20 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00tak\00tak\00\0032\000\001\000\006\00256\000\000", !18, !1, !3, null, i32 (i32, i32, i32)* @tak, null, null, null} ; [ DW_TAG_subprogram ] [line 32] [def] [scope 0] [tak]
+!1 = !{!"0x29", !18} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang version 2.9 (trunk 125492)\001\00\000\00\000", !18, !19, !19, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !18, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{!5}
+!5 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !2} ; [ DW_TAG_base_type ]
+!6 = !{!"0x101\00x\0032\000", !0, !1, !5} ; [ DW_TAG_arg_variable ]
+!7 = !MDLocation(line: 32, column: 13, scope: !0)
+!8 = !{!"0x101\00y\0032\000", !0, !1, !5} ; [ DW_TAG_arg_variable ]
+!9 = !MDLocation(line: 32, column: 20, scope: !0)
+!10 = !{!"0x101\00z\0032\000", !0, !1, !5} ; [ DW_TAG_arg_variable ]
+!11 = !MDLocation(line: 32, column: 27, scope: !0)
+!12 = !MDLocation(line: 33, column: 3, scope: !13)
+!13 = !{!"0xb\0032\0030\006", !18, !0} ; [ DW_TAG_lexical_block ]
+!14 = !MDLocation(line: 34, column: 5, scope: !15)
+!15 = !{!"0xb\0033\0014\007", !18, !13} ; [ DW_TAG_lexical_block ]
+!16 = !MDLocation(line: 36, column: 3, scope: !13)
+!17 = !MDLocation(line: 37, column: 1, scope: !13)
+!18 = !{!"/Volumes/Lalgate/cj/llvm/projects/llvm-test/SingleSource/Benchmarks/BenchmarkGame/recursive.c", !"/Volumes/Lalgate/cj/D/projects/llvm-test/SingleSource/Benchmarks/BenchmarkGame"}
+!19 = !{i32 0}
+!20 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/LoopRotate/pr22337.ll b/test/Transforms/LoopRotate/pr22337.ll
new file mode 100644
index 0000000..c2893db
--- /dev/null
+++ b/test/Transforms/LoopRotate/pr22337.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -loop-rotate -S | FileCheck %s
+
+@a = external global i8, align 4
+@tmp = global i8* @a
+
+define void @f() {
+; CHECK-LABEL: define void @f(
+; CHECK: getelementptr i8* @a, i32 0
+entry:
+ br label %for.preheader
+
+for.preheader:
+ br i1 undef, label %if.then8, label %for.body
+
+for.body:
+ br i1 undef, label %if.end, label %if.then8
+
+if.end:
+ %arrayidx = getelementptr i8* @a, i32 0
+ br label %for.preheader
+
+if.then8:
+ unreachable
+}
diff --git a/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll b/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll
index 173a582..39471eb 100644
--- a/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll
+++ b/test/Transforms/LoopSimplify/2011-12-14-LandingpadHeader.ll
@@ -12,7 +12,7 @@ entry:
; CHECK-NEXT: landingpad
; CHECK: br label %catch
-; CHECK: catch.split-lp:
+; CHECK: catch.preheader.split-lp:
; CHECK-NEXT: landingpad
; CHECK: br label %catch
diff --git a/test/Transforms/LoopStrengthReduce/AArch64/lsr-memset.ll b/test/Transforms/LoopStrengthReduce/AArch64/lsr-memset.ll
index 10b2c3a..48b7094 100644
--- a/test/Transforms/LoopStrengthReduce/AArch64/lsr-memset.ll
+++ b/test/Transforms/LoopStrengthReduce/AArch64/lsr-memset.ll
@@ -96,6 +96,6 @@ done: ; preds = %while.cond, %while.
ret i8* %dest
}
-!0 = metadata !{metadata !"omnipotent char", metadata !1}
-!1 = metadata !{metadata !"Simple C/C++ TBAA"}
-!2 = metadata !{metadata !"long long", metadata !0}
+!0 = !{!"omnipotent char", !1}
+!1 = !{!"Simple C/C++ TBAA"}
+!2 = !{!"long long", !0}
diff --git a/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll b/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll
index f4edf09..26b2940 100644
--- a/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll
+++ b/test/Transforms/LoopStrengthReduce/ARM/ivchain-ARM.ll
@@ -201,7 +201,7 @@ for.end: ; preds = %for.body
;
; 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
+; the store chain. ISEL also fails to convert all but one of 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!
@@ -210,7 +210,7 @@ for.end: ; preds = %for.body
; A9: %.lr.ph
; A9-NOT: lsl.w
; A9-NOT: {{ldr|str|adds|add r}}
-; A9: add.w r
+; A9: vst1.8 {{.*}} [r{{[0-9]+}}]!
; A9-NOT: {{ldr|str|adds|add r}}
; A9: add.w r
; A9-NOT: {{ldr|str|adds|add r}}
diff --git a/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll b/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll
index 937791d..d8636a8 100644
--- a/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll
+++ b/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll
@@ -59,7 +59,9 @@ exit:
;
; X32: @user
; expensive address computation in the preheader
-; X32: imul
+; X32: shll $4
+; X32: lea
+; X32: lea
; X32: %loop
; complex address modes
; X32: (%{{[^)]+}},%{{[^)]+}},
diff --git a/test/Transforms/LoopStrengthReduce/count-to-zero.ll b/test/Transforms/LoopStrengthReduce/count-to-zero.ll
index feb79f8..0e96f02 100644
--- a/test/Transforms/LoopStrengthReduce/count-to-zero.ll
+++ b/test/Transforms/LoopStrengthReduce/count-to-zero.ll
@@ -19,7 +19,7 @@ bb3: ; preds = %bb1
%tmp4 = add i32 %c_addr.1, -1 ; <i32> [#uses=1]
%c_addr.1.be = select i1 %tmp2, i32 %tmp3, i32 %tmp4 ; <i32> [#uses=1]
%indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
-; CHECK: add i32 %lsr.iv, -1
+; CHECK: add nsw i32 %lsr.iv, -1
br label %bb6
bb6: ; preds = %bb3, %entry
diff --git a/test/Transforms/LoopStrengthReduce/pr12018.ll b/test/Transforms/LoopStrengthReduce/pr12018.ll
index 1e3df6c..e493cf8 100644
--- a/test/Transforms/LoopStrengthReduce/pr12018.ll
+++ b/test/Transforms/LoopStrengthReduce/pr12018.ll
@@ -16,7 +16,7 @@ for.body: ; preds = %_ZN8nsTArray9Elemen
%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, metadata !{}) nounwind
+ call void @llvm.dbg.value(metadata %struct.nsTArray* %aValues, i64 0, metadata !0, metadata !{}) nounwind
br label %_ZN8nsTArray9ElementAtEi.exit
_ZN8nsTArray9ElementAtEi.exit: ; preds = %for.body
@@ -35,4 +35,4 @@ declare %struct.nsTArrayHeader* @_ZN8nsTArray4Hdr2Ev()
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
-!0 = metadata !{metadata !"0x101"} ; [ DW_TAG_arg_variable ]
+!0 = !{!"0x101"} ; [ DW_TAG_arg_variable ]
diff --git a/test/Transforms/LoopStrengthReduce/pr18165.ll b/test/Transforms/LoopStrengthReduce/pr18165.ll
index c38d6a6..cc878c4 100644
--- a/test/Transforms/LoopStrengthReduce/pr18165.ll
+++ b/test/Transforms/LoopStrengthReduce/pr18165.ll
@@ -77,12 +77,12 @@ attributes #2 = { nounwind optsize }
!llvm.ident = !{!0}
-!0 = metadata !{metadata !"clang version 3.5 "}
-!1 = metadata !{metadata !2, metadata !3, i64 0}
-!2 = metadata !{metadata !"", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8}
-!3 = metadata !{metadata !"int", metadata !4, i64 0}
-!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
-!5 = metadata !{metadata !"Simple C/C++ TBAA"}
-!6 = metadata !{metadata !2, metadata !3, i64 8}
-!7 = metadata !{metadata !3, metadata !3, i64 0}
-!8 = metadata !{metadata !2, metadata !3, i64 4}
+!0 = !{!"clang version 3.5 "}
+!1 = !{!2, !3, i64 0}
+!2 = !{!"", !3, i64 0, !3, i64 4, !3, i64 8}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C/C++ TBAA"}
+!6 = !{!2, !3, i64 8}
+!7 = !{!3, !3, i64 0}
+!8 = !{!2, !3, i64 4}
diff --git a/test/Transforms/LoopStrengthReduce/uglygep.ll b/test/Transforms/LoopStrengthReduce/uglygep.ll
index 4562d29..5155087 100644
--- a/test/Transforms/LoopStrengthReduce/uglygep.ll
+++ b/test/Transforms/LoopStrengthReduce/uglygep.ll
@@ -59,7 +59,7 @@ bb:
; CHECK: loop0:
; Induction variable is initialized to -2.
; CHECK-NEXT: [[PHIIV:%[^ ]+]] = phi i32 [ [[IVNEXT:%[^ ]+]], %loop0 ], [ -2, %bb ]
-; CHECK-NEXT: [[IVNEXT]] = add i32 [[PHIIV]], 1
+; CHECK-NEXT: [[IVNEXT]] = add nuw nsw i32 [[PHIIV]], 1
; CHECK-NEXT: br i1 false, label %loop0, label %bb0
loop0: ; preds = %loop0, %bb
%i0 = phi i32 [ %i0.next, %loop0 ], [ 0, %bb ] ; <i32> [#uses=2]
diff --git a/test/Transforms/LoopUnroll/PowerPC/p7-unrolling.ll b/test/Transforms/LoopUnroll/PowerPC/p7-unrolling.ll
new file mode 100644
index 0000000..7a50fc0
--- /dev/null
+++ b/test/Transforms/LoopUnroll/PowerPC/p7-unrolling.ll
@@ -0,0 +1,99 @@
+; RUN: opt < %s -S -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -loop-unroll | FileCheck %s
+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-LABEL: @unroll_opt_for_size
+; 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: 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
+
+define void @unroll_default() nounwind {
+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-LABEL: @unroll_default
+; 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: 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/full-unroll-heuristics.ll b/test/Transforms/LoopUnroll/full-unroll-heuristics.ll
new file mode 100644
index 0000000..a1bb4c5
--- /dev/null
+++ b/test/Transforms/LoopUnroll/full-unroll-heuristics.ll
@@ -0,0 +1,62 @@
+; In this test we check how heuristics for complete unrolling work. We have
+; three knobs:
+; 1) -unroll-threshold
+; 2) -unroll-absolute-threshold and
+; 3) -unroll-percent-of-optimized-for-complete-unroll
+;
+; They control loop-unrolling according to the following rules:
+; * If size of unrolled loop exceeds the absoulte threshold, we don't unroll
+; this loop under any circumstances.
+; * If size of unrolled loop is below the '-unroll-threshold', then we'll
+; consider this loop as a very small one, and completely unroll it.
+; * If a loop size is between these two tresholds, we only do complete unroll
+; it if estimated number of potentially optimized instructions is high (we
+; specify the minimal percent of such instructions).
+
+; In this particular test-case, complete unrolling will allow later
+; optimizations to remove ~55% of the instructions, the loop body size is 9,
+; and unrolled size is 65.
+
+; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-absolute-threshold=10 -unroll-threshold=10 -unroll-percent-of-optimized-for-complete-unroll=30 | FileCheck %s -check-prefix=TEST1
+; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-absolute-threshold=100 -unroll-threshold=10 -unroll-percent-of-optimized-for-complete-unroll=30 | FileCheck %s -check-prefix=TEST2
+; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-absolute-threshold=100 -unroll-threshold=10 -unroll-percent-of-optimized-for-complete-unroll=80 | FileCheck %s -check-prefix=TEST3
+; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-absolute-threshold=100 -unroll-threshold=100 -unroll-percent-of-optimized-for-complete-unroll=80 | FileCheck %s -check-prefix=TEST4
+
+; If the absolute threshold is too low, or if we can't optimize away requested
+; percent of instructions, we shouldn't unroll:
+; TEST1: %array_const_idx = getelementptr inbounds [9 x i32]* @known_constant, i64 0, i64 %iv
+; TEST3: %array_const_idx = getelementptr inbounds [9 x i32]* @known_constant, i64 0, i64 %iv
+
+; Otherwise, we should:
+; TEST2-NOT: %array_const_idx = getelementptr inbounds [9 x i32]* @known_constant, i64 0, i64 %iv
+
+; Also, we should unroll if the 'unroll-threshold' is big enough:
+; TEST4-NOT: %array_const_idx = getelementptr inbounds [9 x i32]* @known_constant, i64 0, i64 %iv
+
+; And check that we don't crash when we're not allowed to do any analysis.
+; RUN: opt < %s -loop-unroll -unroll-max-iteration-count-to-analyze=0 -disable-output
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+@known_constant = internal unnamed_addr constant [9 x i32] [i32 0, i32 -1, i32 0, i32 -1, i32 5, i32 -1, i32 0, i32 -1, i32 0], align 16
+
+define i32 @foo(i32* noalias nocapture readonly %src) {
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %iv = phi i64 [ 0, %entry ], [ %inc, %loop ]
+ %r = phi i32 [ 0, %entry ], [ %add, %loop ]
+ %arrayidx = getelementptr inbounds i32* %src, i64 %iv
+ %src_element = load i32* %arrayidx, align 4
+ %array_const_idx = getelementptr inbounds [9 x i32]* @known_constant, i64 0, i64 %iv
+ %const_array_element = load i32* %array_const_idx, align 4
+ %mul = mul nsw i32 %src_element, %const_array_element
+ %add = add nsw i32 %mul, %r
+ %inc = add nuw nsw i64 %iv, 1
+ %exitcond86.i = icmp eq i64 %inc, 9
+ br i1 %exitcond86.i, label %loop.end, label %loop
+
+loop.end: ; preds = %loop
+ %r.lcssa = phi i32 [ %r, %loop ]
+ ret i32 %r.lcssa
+}
diff --git a/test/Transforms/LoopUnroll/partial-unroll-optsize.ll b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
index 3179d55..a650317 100644
--- a/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
+++ b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
@@ -1,7 +1,7 @@
; 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.
+; by 32 times because (1 * 32) + 2 < 50 (whereas (1 * 64 + 2) is not).
define void @unroll_opt_for_size() nounwind optsize {
entry:
br label %loop
@@ -32,4 +32,21 @@ exit:
; 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: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
+; CHECK-NEXT: add
; CHECK-NEXT: icmp
+
diff --git a/test/Transforms/LoopUnroll/runtime-loop.ll b/test/Transforms/LoopUnroll/runtime-loop.ll
index 05d03f2..80571ec 100644
--- a/test/Transforms/LoopUnroll/runtime-loop.ll
+++ b/test/Transforms/LoopUnroll/runtime-loop.ll
@@ -4,9 +4,7 @@
; CHECK: %xtraiter = and i32 %n
; CHECK: %lcmp.mod = icmp ne i32 %xtraiter, 0
-; CHECK: %lcmp.overflow = icmp eq i32 %n, 0
-; CHECK: %lcmp.or = or i1 %lcmp.overflow, %lcmp.mod
-; CHECK: br i1 %lcmp.or, label %for.body.prol, label %for.body.preheader.split
+; CHECK: br i1 %lcmp.mod, label %for.body.prol, label %for.body.preheader.split
; CHECK: for.body.prol:
; CHECK: %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %for.body.prol ], [ 0, %for.body.preheader ]
@@ -115,6 +113,6 @@ for.end: ; preds = %for.cond.for.end_cr
ret i16 %res.0.lcssa
}
-; CHECK: !0 = metadata !{metadata !0, metadata !1}
-; CHECK: !1 = metadata !{metadata !"llvm.loop.unroll.disable"}
+; CHECK: !0 = distinct !{!0, !1}
+; CHECK: !1 = !{!"llvm.loop.unroll.disable"}
diff --git a/test/Transforms/LoopUnroll/runtime-loop1.ll b/test/Transforms/LoopUnroll/runtime-loop1.ll
index 38b4f32..5ff75e3 100644
--- a/test/Transforms/LoopUnroll/runtime-loop1.ll
+++ b/test/Transforms/LoopUnroll/runtime-loop1.ll
@@ -3,7 +3,7 @@
; This tests that setting the unroll count works
; CHECK: for.body.prol:
-; CHECK: br i1 %prol.iter.cmp, label %for.body.prol, label %for.body.preheader.split
+; CHECK: br label %for.body.preheader.split
; CHECK: for.body:
; CHECK: br i1 %exitcond.1, label %for.end.loopexit.unr-lcssa, label %for.body
; CHECK-NOT: br i1 %exitcond.4, label %for.end.loopexit{{.*}}, label %for.body
diff --git a/test/Transforms/LoopUnroll/runtime-loop2.ll b/test/Transforms/LoopUnroll/runtime-loop2.ll
index 7205c68..176362a 100644
--- a/test/Transforms/LoopUnroll/runtime-loop2.ll
+++ b/test/Transforms/LoopUnroll/runtime-loop2.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -S -loop-unroll -unroll-threshold=50 -unroll-runtime -unroll-count=8 | FileCheck %s
+; RUN: opt < %s -S -loop-unroll -unroll-threshold=25 -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
diff --git a/test/Transforms/LoopUnroll/tripcount-overflow.ll b/test/Transforms/LoopUnroll/tripcount-overflow.ll
index d593685..052077c 100644
--- a/test/Transforms/LoopUnroll/tripcount-overflow.ll
+++ b/test/Transforms/LoopUnroll/tripcount-overflow.ll
@@ -1,19 +1,28 @@
; RUN: opt < %s -S -unroll-runtime -unroll-count=2 -loop-unroll | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
-; When prologue is fully unrolled, the branch on its end is unconditional.
-; Unrolling it is illegal if we can't prove that trip-count+1 doesn't overflow,
-; like in this example, where it comes from an argument.
-;
-; This test is based on an example from here:
-; http://stackoverflow.com/questions/23838661/why-is-clang-optimizing-this-code-out
-;
+; This test case documents how runtime loop unrolling handles the case
+; when the backedge-count is -1.
+
+; If %N, the backedge-taken count, is -1 then %0 unsigned-overflows
+; and is 0. %xtraiter too is 0, signifying that the total trip-count
+; is divisible by 2. The prologue then branches to the unrolled loop
+; and executes the 2^32 iterations there, in groups of 2.
+
+
+; CHECK: entry:
+; CHECK-NEXT: %0 = add i32 %N, 1
+; CHECK-NEXT: %xtraiter = and i32 %0, 1
+; CHECK-NEXT: %lcmp.mod = icmp ne i32 %xtraiter, 0
+; CHECK-NEXT: br i1 %lcmp.mod, label %while.body.prol, label %entry.split
+
; CHECK: while.body.prol:
-; CHECK: br i1
+; CHECK: br label %entry.split
+
; CHECK: entry.split:
; Function Attrs: nounwind readnone ssp uwtable
-define i32 @foo(i32 %N) #0 {
+define i32 @foo(i32 %N) {
entry:
br label %while.body
@@ -26,5 +35,3 @@ while.body: ; preds = %while.body, %entry
while.end: ; preds = %while.body
ret i32 %i
}
-
-attributes #0 = { nounwind readnone ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
diff --git a/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll b/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll
index db18f25..4f934a6 100644
--- a/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll
+++ b/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll
@@ -30,10 +30,10 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!1 = metadata !{metadata !1, metadata !2, metadata !3, metadata !4}
-!2 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
-!3 = metadata !{metadata !"llvm.loop.unroll.count", i32 4}
-!4 = metadata !{metadata !"llvm.loop.vectorize.width", i32 8}
+!1 = !{!1, !2, !3, !4}
+!2 = !{!"llvm.loop.vectorize.enable", i1 true}
+!3 = !{!"llvm.loop.unroll.count", i32 4}
+!4 = !{!"llvm.loop.vectorize.width", i32 8}
; #pragma clang loop unroll(full)
;
@@ -63,8 +63,8 @@ for.body: ; preds = %entry, %for.body
for.end: ; preds = %for.body, %entry
ret void
}
-!5 = metadata !{metadata !5, metadata !6}
-!6 = metadata !{metadata !"llvm.loop.unroll.full"}
+!5 = !{!5, !6}
+!6 = !{!"llvm.loop.unroll.full"}
; #pragma clang loop unroll(disable)
;
@@ -89,8 +89,8 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!7 = metadata !{metadata !7, metadata !8}
-!8 = metadata !{metadata !"llvm.loop.unroll.disable"}
+!7 = !{!7, !8}
+!8 = !{!"llvm.loop.unroll.disable"}
; This function contains two loops which share the same llvm.loop metadata node
; with an llvm.loop.unroll.count 2 hint. Both loops should be unrolled. This
@@ -134,16 +134,16 @@ for.body3.1: ; preds = %for.body3.1.prehead
for.inc5.1: ; preds = %for.body3.1
ret void
}
-!9 = metadata !{metadata !9, metadata !10}
-!10 = metadata !{metadata !"llvm.loop.unroll.count", i32 2}
-
-
-; CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[VEC_ENABLE:.*]], metadata ![[WIDTH_8:.*]], metadata ![[UNROLL_DISABLE:.*]]}
-; CHECK: ![[VEC_ENABLE]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
-; CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 8}
-; CHECK: ![[UNROLL_DISABLE]] = metadata !{metadata !"llvm.loop.unroll.disable"}
-; CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2]], metadata ![[UNROLL_FULL:.*]]}
-; CHECK: ![[UNROLL_FULL]] = metadata !{metadata !"llvm.loop.unroll.full"}
-; CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_DISABLE:.*]]}
-; CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[UNROLL_DISABLE:.*]]}
-; CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLL_DISABLE:.*]]}
+!9 = !{!9, !10}
+!10 = !{!"llvm.loop.unroll.count", i32 2}
+
+
+; CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[VEC_ENABLE:.*]], ![[WIDTH_8:.*]], ![[UNROLL_DISABLE:.*]]}
+; CHECK: ![[VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true}
+; CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
+; CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+; CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_FULL:.*]]}
+; CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
+; CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_DISABLE:.*]]}
+; CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[UNROLL_DISABLE:.*]]}
+; CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_DISABLE:.*]]}
diff --git a/test/Transforms/LoopUnroll/unroll-pragmas.ll b/test/Transforms/LoopUnroll/unroll-pragmas.ll
index 1ca249d..5831557 100644
--- a/test/Transforms/LoopUnroll/unroll-pragmas.ll
+++ b/test/Transforms/LoopUnroll/unroll-pragmas.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -loop-unroll -S | FileCheck %s
-; RUN: opt < %s -loop-unroll -loop-unroll -S | FileCheck %s
+; RUN: opt < %s -loop-unroll -pragma-unroll-threshold=1024 -S | FileCheck %s
+; RUN: opt < %s -loop-unroll -loop-unroll -pragma-unroll-threshold=1024 -S | FileCheck %s
;
; Run loop unrolling twice to verify that loop unrolling metadata is properly
; removed and further unrolling is disabled after the pass is run once.
@@ -54,8 +54,8 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!1 = metadata !{metadata !1, metadata !2}
-!2 = metadata !{metadata !"llvm.loop.unroll.disable"}
+!1 = !{!1, !2}
+!2 = !{!"llvm.loop.unroll.disable"}
; loop64 has a high enough count that it should *not* be unrolled by
; the default unrolling heuristic. It serves as the control for the
@@ -105,8 +105,8 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!3 = metadata !{metadata !3, metadata !4}
-!4 = metadata !{metadata !"llvm.loop.unroll.full"}
+!3 = !{!3, !4}
+!4 = !{!"llvm.loop.unroll.full"}
; #pragma clang loop unroll_count(4)
; Loop should be unrolled 4 times.
@@ -135,8 +135,8 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!5 = metadata !{metadata !5, metadata !6}
-!6 = metadata !{metadata !"llvm.loop.unroll.count", i32 4}
+!5 = !{!5, !6}
+!6 = !{!"llvm.loop.unroll.count", i32 4}
; #pragma clang loop unroll(full)
; Full unrolling is requested, but loop has a dynamic trip count so
@@ -165,7 +165,7 @@ for.body: ; preds = %entry, %for.body
for.end: ; preds = %for.body, %entry
ret void
}
-!8 = metadata !{metadata !8, metadata !4}
+!8 = !{!8, !4}
; #pragma clang loop unroll_count(4)
; Loop has a dynamic trip count. Unrolling should occur, but no
@@ -202,7 +202,7 @@ for.body: ; preds = %entry, %for.body
for.end: ; preds = %for.body, %entry
ret void
}
-!9 = metadata !{metadata !9, metadata !6}
+!9 = !{!9, !6}
; #pragma clang loop unroll_count(1)
; Loop should not be unrolled
@@ -228,8 +228,8 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!10 = metadata !{metadata !10, metadata !11}
-!11 = metadata !{metadata !"llvm.loop.unroll.count", i32 1}
+!10 = !{!10, !11}
+!11 = !{!"llvm.loop.unroll.count", i32 1}
; #pragma clang loop unroll(full)
; Loop has very high loop count (1 million) and full unrolling was requested.
@@ -256,4 +256,4 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
-!12 = metadata !{metadata !12, metadata !4}
+!12 = !{!12, !4}
diff --git a/test/Transforms/LoopVectorize/AArch64/arbitrary-induction-step.ll b/test/Transforms/LoopVectorize/AArch64/arbitrary-induction-step.ll
new file mode 100644
index 0000000..95734bf
--- /dev/null
+++ b/test/Transforms/LoopVectorize/AArch64/arbitrary-induction-step.ll
@@ -0,0 +1,150 @@
+; RUN: opt -S < %s -loop-vectorize 2>&1 | FileCheck %s
+; RUN: opt -S < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 | FileCheck %s --check-prefix=FORCE-VEC
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-gnueabi"
+
+; Test integer induction variable of step 2:
+; for (int i = 0; i < 1024; i+=2) {
+; int tmp = *A++;
+; sum += i * tmp;
+; }
+
+; CHECK-LABEL: @ind_plus2(
+; CHECK: load <4 x i32>*
+; CHECK: load <4 x i32>*
+; CHECK: mul nsw <4 x i32>
+; CHECK: mul nsw <4 x i32>
+; CHECK: add nsw <4 x i32>
+; CHECK: add nsw <4 x i32>
+; CHECK: %index.next = add i64 %index, 8
+; CHECK: icmp eq i64 %index.next, 512
+
+; FORCE-VEC-LABEL: @ind_plus2(
+; FORCE-VEC: %wide.load = load <2 x i32>*
+; FORCE-VEC: mul nsw <2 x i32>
+; FORCE-VEC: add nsw <2 x i32>
+; FORCE-VEC: %index.next = add i64 %index, 2
+; FORCE-VEC: icmp eq i64 %index.next, 512
+define i32 @ind_plus2(i32* %A) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %A.addr = phi i32* [ %A, %entry ], [ %inc.ptr, %for.body ]
+ %i = phi i32 [ 0, %entry ], [ %add1, %for.body ]
+ %sum = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %inc.ptr = getelementptr inbounds i32* %A.addr, i64 1
+ %0 = load i32* %A.addr, align 4
+ %mul = mul nsw i32 %0, %i
+ %add = add nsw i32 %mul, %sum
+ %add1 = add nsw i32 %i, 2
+ %cmp = icmp slt i32 %add1, 1024
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body
+ %add.lcssa = phi i32 [ %add, %for.body ]
+ ret i32 %add.lcssa
+}
+
+
+; Test integer induction variable of step -2:
+; for (int i = 1024; i > 0; i-=2) {
+; int tmp = *A++;
+; sum += i * tmp;
+; }
+
+; CHECK-LABEL: @ind_minus2(
+; CHECK: load <4 x i32>*
+; CHECK: load <4 x i32>*
+; CHECK: mul nsw <4 x i32>
+; CHECK: mul nsw <4 x i32>
+; CHECK: add nsw <4 x i32>
+; CHECK: add nsw <4 x i32>
+; CHECK: %index.next = add i64 %index, 8
+; CHECK: icmp eq i64 %index.next, 512
+
+; FORCE-VEC-LABEL: @ind_minus2(
+; FORCE-VEC: %wide.load = load <2 x i32>*
+; FORCE-VEC: mul nsw <2 x i32>
+; FORCE-VEC: add nsw <2 x i32>
+; FORCE-VEC: %index.next = add i64 %index, 2
+; FORCE-VEC: icmp eq i64 %index.next, 512
+define i32 @ind_minus2(i32* %A) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %A.addr = phi i32* [ %A, %entry ], [ %inc.ptr, %for.body ]
+ %i = phi i32 [ 1024, %entry ], [ %sub, %for.body ]
+ %sum = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %inc.ptr = getelementptr inbounds i32* %A.addr, i64 1
+ %0 = load i32* %A.addr, align 4
+ %mul = mul nsw i32 %0, %i
+ %add = add nsw i32 %mul, %sum
+ %sub = add nsw i32 %i, -2
+ %cmp = icmp sgt i32 %i, 2
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body
+ %add.lcssa = phi i32 [ %add, %for.body ]
+ ret i32 %add.lcssa
+}
+
+
+; Test pointer induction variable of step 2. As currently we don't support
+; masked load/store, vectorization is possible but not beneficial. If loop
+; vectorization is not enforced, LV will only do interleave.
+; for (int i = 0; i < 1024; i++) {
+; int tmp0 = *A++;
+; int tmp1 = *A++;
+; sum += tmp0 * tmp1;
+; }
+
+; CHECK-LABEL: @ptr_ind_plus2(
+; CHECK: load i32*
+; CHECK: load i32*
+; CHECK: load i32*
+; CHECK: load i32*
+; CHECK: mul nsw i32
+; CHECK: mul nsw i32
+; CHECK: add nsw i32
+; CHECK: add nsw i32
+; CHECK: %index.next = add i64 %index, 2
+; CHECK: %21 = icmp eq i64 %index.next, 1024
+
+; FORCE-VEC-LABEL: @ptr_ind_plus2(
+; FORCE-VEC: load i32*
+; FORCE-VEC: insertelement <2 x i32>
+; FORCE-VEC: load i32*
+; FORCE-VEC: insertelement <2 x i32>
+; FORCE-VEC: load i32*
+; FORCE-VEC: insertelement <2 x i32>
+; FORCE-VEC: load i32*
+; FORCE-VEC: insertelement <2 x i32>
+; FORCE-VEC: mul nsw <2 x i32>
+; FORCE-VEC: add nsw <2 x i32>
+; FORCE-VEC: %index.next = add i64 %index, 2
+; FORCE-VEC: icmp eq i64 %index.next, 1024
+define i32 @ptr_ind_plus2(i32* %A) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %A.addr = phi i32* [ %A, %entry ], [ %inc.ptr1, %for.body ]
+ %sum = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %inc.ptr = getelementptr inbounds i32* %A.addr, i64 1
+ %0 = load i32* %A.addr, align 4
+ %inc.ptr1 = getelementptr inbounds i32* %A.addr, i64 2
+ %1 = load i32* %inc.ptr, align 4
+ %mul = mul nsw i32 %1, %0
+ %add = add nsw i32 %mul, %sum
+ %inc = add nsw i32 %i, 1
+ %exitcond = icmp eq i32 %inc, 1024
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ %add.lcssa = phi i32 [ %add, %for.body ]
+ ret i32 %add.lcssa
+}
diff --git a/test/Transforms/LoopVectorize/PowerPC/small-loop-rdx.ll b/test/Transforms/LoopVectorize/PowerPC/small-loop-rdx.ll
new file mode 100644
index 0000000..25e7d24
--- /dev/null
+++ b/test/Transforms/LoopVectorize/PowerPC/small-loop-rdx.ll
@@ -0,0 +1,47 @@
+; RUN: opt < %s -loop-vectorize -S | FileCheck %s
+
+; CHECK: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT: fadd
+; CHECK-NEXT-NOT: fadd
+
+target datalayout = "e-m:e-i64:64-n32:64"
+target triple = "powerpc64le-ibm-linux-gnu"
+
+define void @test(double* nocapture readonly %arr, i32 signext %len) #0 {
+entry:
+ %cmp4 = icmp sgt i32 %len, 0
+ br i1 %cmp4, label %for.body.lr.ph, label %for.end
+
+for.body.lr.ph: ; preds = %entry
+ %0 = add i32 %len, -1
+ br label %for.body
+
+for.body: ; preds = %for.body, %for.body.lr.ph
+ %indvars.iv = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next, %for.body ]
+ %redx.05 = phi double [ 0.000000e+00, %for.body.lr.ph ], [ %add, %for.body ]
+ %arrayidx = getelementptr inbounds double* %arr, i64 %indvars.iv
+ %1 = load double* %arrayidx, align 8
+ %add = fadd fast double %1, %redx.05
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %lftr.wideiv = trunc i64 %indvars.iv to i32
+ %exitcond = icmp eq i32 %lftr.wideiv, %0
+ br i1 %exitcond, label %for.end.loopexit, label %for.body
+
+for.end.loopexit: ; preds = %for.body
+ %add.lcssa = phi double [ %add, %for.body ]
+ br label %for.end
+
+for.end: ; preds = %for.end.loopexit, %entry
+ %redx.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add.lcssa, %for.end.loopexit ]
+ ret void
+}
diff --git a/test/Transforms/LoopVectorize/X86/already-vectorized.ll b/test/Transforms/LoopVectorize/X86/already-vectorized.ll
index 9c69ba8..29d74a0 100644
--- a/test/Transforms/LoopVectorize/X86/already-vectorized.ll
+++ b/test/Transforms/LoopVectorize/X86/already-vectorized.ll
@@ -39,8 +39,8 @@ for.end: ; preds = %for.body
}
; Now, we check for the Hint metadata
-; CHECK: [[vect]] = metadata !{metadata [[vect]], metadata [[width:![0-9]+]], metadata [[unroll:![0-9]+]]}
-; CHECK: [[width]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
-; CHECK: [[unroll]] = metadata !{metadata !"llvm.loop.interleave.count", i32 1}
-; CHECK: [[scalar]] = metadata !{metadata [[scalar]], metadata [[width]], metadata [[unroll]]}
+; CHECK: [[vect]] = distinct !{[[vect]], [[width:![0-9]+]], [[unroll:![0-9]+]]}
+; CHECK: [[width]] = !{!"llvm.loop.vectorize.width", i32 1}
+; CHECK: [[unroll]] = !{!"llvm.loop.interleave.count", i32 1}
+; CHECK: [[scalar]] = distinct !{[[scalar]], [[width]], [[unroll]]}
diff --git a/test/Transforms/LoopVectorize/X86/illegal-parallel-loop-uniform-write.ll b/test/Transforms/LoopVectorize/X86/illegal-parallel-loop-uniform-write.ll
index 0650d94..46efaf0 100644
--- a/test/Transforms/LoopVectorize/X86/illegal-parallel-loop-uniform-write.ll
+++ b/test/Transforms/LoopVectorize/X86/illegal-parallel-loop-uniform-write.ll
@@ -50,7 +50,7 @@ for.end15: ; preds = %for.end.us, %entry
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!3 = metadata !{metadata !4, metadata !5}
-!4 = metadata !{metadata !4}
-!5 = metadata !{metadata !5}
+!3 = !{!4, !5}
+!4 = !{!4}
+!5 = !{!5}
diff --git a/test/Transforms/LoopVectorize/X86/masked_load_store.ll b/test/Transforms/LoopVectorize/X86/masked_load_store.ll
new file mode 100644
index 0000000..9e2de80
--- /dev/null
+++ b/test/Transforms/LoopVectorize/X86/masked_load_store.ll
@@ -0,0 +1,502 @@
+; RUN: opt < %s -O3 -mcpu=corei7-avx -S | FileCheck %s -check-prefix=AVX1
+; RUN: opt < %s -O3 -mcpu=core-avx2 -S | FileCheck %s -check-prefix=AVX2
+; RUN: opt < %s -O3 -mcpu=knl -S | FileCheck %s -check-prefix=AVX512
+
+;AVX1-NOT: llvm.masked
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc_linux"
+
+; The source code:
+;
+;void foo1(int *A, int *B, int *trigger) {
+;
+; for (int i=0; i<10000; i++) {
+; if (trigger[i] < 100) {
+; A[i] = B[i] + trigger[i];
+; }
+; }
+;}
+
+;AVX2-LABEL: @foo1
+;AVX2: icmp slt <8 x i32> %wide.load, <i32 100, i32 100, i32 100
+;AVX2: call <8 x i32> @llvm.masked.load.v8i32
+;AVX2: add nsw <8 x i32>
+;AVX2: call void @llvm.masked.store.v8i32
+;AVX2: ret void
+
+;AVX512-LABEL: @foo1
+;AVX512: icmp slt <16 x i32> %wide.load, <i32 100, i32 100, i32 100
+;AVX512: call <16 x i32> @llvm.masked.load.v16i32
+;AVX512: add nsw <16 x i32>
+;AVX512: call void @llvm.masked.store.v16i32
+;AVX512: ret void
+
+; Function Attrs: nounwind uwtable
+define void @foo1(i32* %A, i32* %B, i32* %trigger) {
+entry:
+ %A.addr = alloca i32*, align 8
+ %B.addr = alloca i32*, align 8
+ %trigger.addr = alloca i32*, align 8
+ %i = alloca i32, align 4
+ store i32* %A, i32** %A.addr, align 8
+ store i32* %B, i32** %B.addr, align 8
+ store i32* %trigger, i32** %trigger.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 slt i32 %0, 10000
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i32* %i, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32** %trigger.addr, align 8
+ %arrayidx = getelementptr inbounds i32* %2, i64 %idxprom
+ %3 = load i32* %arrayidx, align 4
+ %cmp1 = icmp slt i32 %3, 100
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %4 = load i32* %i, align 4
+ %idxprom2 = sext i32 %4 to i64
+ %5 = load i32** %B.addr, align 8
+ %arrayidx3 = getelementptr inbounds i32* %5, i64 %idxprom2
+ %6 = load i32* %arrayidx3, align 4
+ %7 = load i32* %i, align 4
+ %idxprom4 = sext i32 %7 to i64
+ %8 = load i32** %trigger.addr, align 8
+ %arrayidx5 = getelementptr inbounds i32* %8, i64 %idxprom4
+ %9 = load i32* %arrayidx5, align 4
+ %add = add nsw i32 %6, %9
+ %10 = load i32* %i, align 4
+ %idxprom6 = sext i32 %10 to i64
+ %11 = load i32** %A.addr, align 8
+ %arrayidx7 = getelementptr inbounds i32* %11, i64 %idxprom6
+ store i32 %add, i32* %arrayidx7, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %12 = load i32* %i, align 4
+ %inc = add nsw i32 %12, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+; The source code:
+;
+;void foo2(float *A, float *B, int *trigger) {
+;
+; for (int i=0; i<10000; i++) {
+; if (trigger[i] < 100) {
+; A[i] = B[i] + trigger[i];
+; }
+; }
+;}
+
+;AVX2-LABEL: @foo2
+;AVX2: icmp slt <8 x i32> %wide.load, <i32 100, i32 100, i32 100
+;AVX2: call <8 x float> @llvm.masked.load.v8f32
+;AVX2: fadd <8 x float>
+;AVX2: call void @llvm.masked.store.v8f32
+;AVX2: ret void
+
+;AVX512-LABEL: @foo2
+;AVX512: icmp slt <16 x i32> %wide.load, <i32 100, i32 100, i32 100
+;AVX512: call <16 x float> @llvm.masked.load.v16f32
+;AVX512: fadd <16 x float>
+;AVX512: call void @llvm.masked.store.v16f32
+;AVX512: ret void
+
+; Function Attrs: nounwind uwtable
+define void @foo2(float* %A, float* %B, i32* %trigger) {
+entry:
+ %A.addr = alloca float*, align 8
+ %B.addr = alloca float*, align 8
+ %trigger.addr = alloca i32*, align 8
+ %i = alloca i32, align 4
+ store float* %A, float** %A.addr, align 8
+ store float* %B, float** %B.addr, align 8
+ store i32* %trigger, i32** %trigger.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 slt i32 %0, 10000
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i32* %i, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32** %trigger.addr, align 8
+ %arrayidx = getelementptr inbounds i32* %2, i64 %idxprom
+ %3 = load i32* %arrayidx, align 4
+ %cmp1 = icmp slt i32 %3, 100
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %4 = load i32* %i, align 4
+ %idxprom2 = sext i32 %4 to i64
+ %5 = load float** %B.addr, align 8
+ %arrayidx3 = getelementptr inbounds float* %5, i64 %idxprom2
+ %6 = load float* %arrayidx3, align 4
+ %7 = load i32* %i, align 4
+ %idxprom4 = sext i32 %7 to i64
+ %8 = load i32** %trigger.addr, align 8
+ %arrayidx5 = getelementptr inbounds i32* %8, i64 %idxprom4
+ %9 = load i32* %arrayidx5, align 4
+ %conv = sitofp i32 %9 to float
+ %add = fadd float %6, %conv
+ %10 = load i32* %i, align 4
+ %idxprom6 = sext i32 %10 to i64
+ %11 = load float** %A.addr, align 8
+ %arrayidx7 = getelementptr inbounds float* %11, i64 %idxprom6
+ store float %add, float* %arrayidx7, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %12 = load i32* %i, align 4
+ %inc = add nsw i32 %12, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+; The source code:
+;
+;void foo3(double *A, double *B, int *trigger) {
+;
+; for (int i=0; i<10000; i++) {
+; if (trigger[i] < 100) {
+; A[i] = B[i] + trigger[i];
+; }
+; }
+;}
+
+;AVX2-LABEL: @foo3
+;AVX2: icmp slt <4 x i32> %wide.load, <i32 100, i32 100,
+;AVX2: call <4 x double> @llvm.masked.load.v4f64
+;AVX2: sitofp <4 x i32> %wide.load to <4 x double>
+;AVX2: fadd <4 x double>
+;AVX2: call void @llvm.masked.store.v4f64
+;AVX2: ret void
+
+;AVX512-LABEL: @foo3
+;AVX512: icmp slt <8 x i32> %wide.load, <i32 100, i32 100,
+;AVX512: call <8 x double> @llvm.masked.load.v8f64
+;AVX512: sitofp <8 x i32> %wide.load to <8 x double>
+;AVX512: fadd <8 x double>
+;AVX512: call void @llvm.masked.store.v8f64
+;AVX512: ret void
+
+
+; Function Attrs: nounwind uwtable
+define void @foo3(double* %A, double* %B, i32* %trigger) #0 {
+entry:
+ %A.addr = alloca double*, align 8
+ %B.addr = alloca double*, align 8
+ %trigger.addr = alloca i32*, align 8
+ %i = alloca i32, align 4
+ store double* %A, double** %A.addr, align 8
+ store double* %B, double** %B.addr, align 8
+ store i32* %trigger, i32** %trigger.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 slt i32 %0, 10000
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i32* %i, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32** %trigger.addr, align 8
+ %arrayidx = getelementptr inbounds i32* %2, i64 %idxprom
+ %3 = load i32* %arrayidx, align 4
+ %cmp1 = icmp slt i32 %3, 100
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %4 = load i32* %i, align 4
+ %idxprom2 = sext i32 %4 to i64
+ %5 = load double** %B.addr, align 8
+ %arrayidx3 = getelementptr inbounds double* %5, i64 %idxprom2
+ %6 = load double* %arrayidx3, align 8
+ %7 = load i32* %i, align 4
+ %idxprom4 = sext i32 %7 to i64
+ %8 = load i32** %trigger.addr, align 8
+ %arrayidx5 = getelementptr inbounds i32* %8, i64 %idxprom4
+ %9 = load i32* %arrayidx5, align 4
+ %conv = sitofp i32 %9 to double
+ %add = fadd double %6, %conv
+ %10 = load i32* %i, align 4
+ %idxprom6 = sext i32 %10 to i64
+ %11 = load double** %A.addr, align 8
+ %arrayidx7 = getelementptr inbounds double* %11, i64 %idxprom6
+ store double %add, double* %arrayidx7, align 8
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %12 = load i32* %i, align 4
+ %inc = add nsw i32 %12, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+; The source code:
+;
+;void foo4(double *A, double *B, int *trigger) {
+;
+; for (int i=0; i<10000; i++) {
+; if (trigger[i] < 100) {
+; A[i] = B[i*2] + trigger[i]; << non-cosecutive access
+; }
+; }
+;}
+
+;AVX2-LABEL: @foo4
+;AVX2-NOT: llvm.masked
+;AVX2: ret void
+
+;AVX512-LABEL: @foo4
+;AVX512-NOT: llvm.masked
+;AVX512: ret void
+
+; Function Attrs: nounwind uwtable
+define void @foo4(double* %A, double* %B, i32* %trigger) {
+entry:
+ %A.addr = alloca double*, align 8
+ %B.addr = alloca double*, align 8
+ %trigger.addr = alloca i32*, align 8
+ %i = alloca i32, align 4
+ store double* %A, double** %A.addr, align 8
+ store double* %B, double** %B.addr, align 8
+ store i32* %trigger, i32** %trigger.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 slt i32 %0, 10000
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i32* %i, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32** %trigger.addr, align 8
+ %arrayidx = getelementptr inbounds i32* %2, i64 %idxprom
+ %3 = load i32* %arrayidx, align 4
+ %cmp1 = icmp slt i32 %3, 100
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %4 = load i32* %i, align 4
+ %mul = mul nsw i32 %4, 2
+ %idxprom2 = sext i32 %mul to i64
+ %5 = load double** %B.addr, align 8
+ %arrayidx3 = getelementptr inbounds double* %5, i64 %idxprom2
+ %6 = load double* %arrayidx3, align 8
+ %7 = load i32* %i, align 4
+ %idxprom4 = sext i32 %7 to i64
+ %8 = load i32** %trigger.addr, align 8
+ %arrayidx5 = getelementptr inbounds i32* %8, i64 %idxprom4
+ %9 = load i32* %arrayidx5, align 4
+ %conv = sitofp i32 %9 to double
+ %add = fadd double %6, %conv
+ %10 = load i32* %i, align 4
+ %idxprom6 = sext i32 %10 to i64
+ %11 = load double** %A.addr, align 8
+ %arrayidx7 = getelementptr inbounds double* %11, i64 %idxprom6
+ store double %add, double* %arrayidx7, align 8
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %12 = load i32* %i, align 4
+ %inc = add nsw i32 %12, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+@a = common global [1 x i32*] zeroinitializer, align 8
+@c = common global i32* null, align 8
+
+; The loop here should not be vectorized due to trapping
+; constant expression
+;AVX2-LABEL: @foo5
+;AVX2-NOT: llvm.masked
+;AVX2: store i32 sdiv
+;AVX2: ret void
+
+;AVX512-LABEL: @foo5
+;AVX512-NOT: llvm.masked
+;AVX512: store i32 sdiv
+;AVX512: ret void
+
+; Function Attrs: nounwind uwtable
+define void @foo5(i32* %A, i32* %B, i32* %trigger) {
+entry:
+ %A.addr = alloca i32*, align 8
+ %B.addr = alloca i32*, align 8
+ %trigger.addr = alloca i32*, align 8
+ %i = alloca i32, align 4
+ store i32* %A, i32** %A.addr, align 8
+ store i32* %B, i32** %B.addr, align 8
+ store i32* %trigger, i32** %trigger.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 slt i32 %0, 10000
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i32* %i, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32** %trigger.addr, align 8
+ %arrayidx = getelementptr inbounds i32* %2, i64 %idxprom
+ %3 = load i32* %arrayidx, align 4
+ %cmp1 = icmp slt i32 %3, 100
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %4 = load i32* %i, align 4
+ %idxprom2 = sext i32 %4 to i64
+ %5 = load i32** %B.addr, align 8
+ %arrayidx3 = getelementptr inbounds i32* %5, i64 %idxprom2
+ %6 = load i32* %arrayidx3, align 4
+ %7 = load i32* %i, align 4
+ %idxprom4 = sext i32 %7 to i64
+ %8 = load i32** %trigger.addr, align 8
+ %arrayidx5 = getelementptr inbounds i32* %8, i64 %idxprom4
+ %9 = load i32* %arrayidx5, align 4
+ %add = add nsw i32 %6, %9
+ %10 = load i32* %i, align 4
+ %idxprom6 = sext i32 %10 to i64
+ %11 = load i32** %A.addr, align 8
+ %arrayidx7 = getelementptr inbounds i32* %11, i64 %idxprom6
+ store i32 sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*]* @a, i64 0, i64 1), i32** @c) to i32)), i32* %arrayidx7, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %12 = load i32* %i, align 4
+ %inc = add nsw i32 %12, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+; Reverse loop
+;void foo6(double *in, double *out, unsigned size, int *trigger) {
+;
+; for (int i=SIZE-1; i>=0; i--) {
+; if (trigger[i] > 0) {
+; out[i] = in[i] + (double) 0.5;
+; }
+; }
+;}
+;AVX2-LABEL: @foo6
+;AVX2: icmp sgt <4 x i32> %reverse, zeroinitializer
+;AVX2: shufflevector <4 x i1>{{.*}}<4 x i32> <i32 3, i32 2, i32 1, i32 0>
+;AVX2: call <4 x double> @llvm.masked.load.v4f64
+;AVX2: fadd <4 x double>
+;AVX2: call void @llvm.masked.store.v4f64
+;AVX2: ret void
+
+;AVX512-LABEL: @foo6
+;AVX512: icmp sgt <8 x i32> %reverse, zeroinitializer
+;AVX512: shufflevector <8 x i1>{{.*}}<8 x i32> <i32 7, i32 6, i32 5, i32 4
+;AVX512: call <8 x double> @llvm.masked.load.v8f64
+;AVX512: fadd <8 x double>
+;AVX512: call void @llvm.masked.store.v8f64
+;AVX512: ret void
+
+
+define void @foo6(double* %in, double* %out, i32 %size, i32* %trigger) {
+entry:
+ %in.addr = alloca double*, align 8
+ %out.addr = alloca double*, align 8
+ %size.addr = alloca i32, align 4
+ %trigger.addr = alloca i32*, align 8
+ %i = alloca i32, align 4
+ store double* %in, double** %in.addr, align 8
+ store double* %out, double** %out.addr, align 8
+ store i32 %size, i32* %size.addr, align 4
+ store i32* %trigger, i32** %trigger.addr, align 8
+ store i32 4095, i32* %i, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %0 = load i32* %i, align 4
+ %cmp = icmp sge i32 %0, 0
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %1 = load i32* %i, align 4
+ %idxprom = sext i32 %1 to i64
+ %2 = load i32** %trigger.addr, align 8
+ %arrayidx = getelementptr inbounds i32* %2, i64 %idxprom
+ %3 = load i32* %arrayidx, align 4
+ %cmp1 = icmp sgt i32 %3, 0
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %4 = load i32* %i, align 4
+ %idxprom2 = sext i32 %4 to i64
+ %5 = load double** %in.addr, align 8
+ %arrayidx3 = getelementptr inbounds double* %5, i64 %idxprom2
+ %6 = load double* %arrayidx3, align 8
+ %add = fadd double %6, 5.000000e-01
+ %7 = load i32* %i, align 4
+ %idxprom4 = sext i32 %7 to i64
+ %8 = load double** %out.addr, align 8
+ %arrayidx5 = getelementptr inbounds double* %8, i64 %idxprom4
+ store double %add, double* %arrayidx5, align 8
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %9 = load i32* %i, align 4
+ %dec = add nsw i32 %9, -1
+ store i32 %dec, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+
diff --git a/test/Transforms/LoopVectorize/X86/metadata-enable.ll b/test/Transforms/LoopVectorize/X86/metadata-enable.ll
index 8e0ca41..7feb66c 100644
--- a/test/Transforms/LoopVectorize/X86/metadata-enable.ll
+++ b/test/Transforms/LoopVectorize/X86/metadata-enable.ll
@@ -170,7 +170,7 @@ for.end: ; preds = %for.body
ret i32 %1
}
-!0 = metadata !{metadata !0, metadata !1}
-!1 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 1}
-!2 = metadata !{metadata !2, metadata !3}
-!3 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 0}
+!0 = !{!0, !1}
+!1 = !{!"llvm.loop.vectorize.enable", i1 1}
+!2 = !{!2, !3}
+!3 = !{!"llvm.loop.vectorize.enable", i1 0}
diff --git a/test/Transforms/LoopVectorize/X86/parallel-loops-after-reg2mem.ll b/test/Transforms/LoopVectorize/X86/parallel-loops-after-reg2mem.ll
index 0b542a9..ad01044 100644
--- a/test/Transforms/LoopVectorize/X86/parallel-loops-after-reg2mem.ll
+++ b/test/Transforms/LoopVectorize/X86/parallel-loops-after-reg2mem.ll
@@ -46,4 +46,4 @@ for.end: ; preds = %for.body
ret void
}
-!3 = metadata !{metadata !3}
+!3 = !{!3}
diff --git a/test/Transforms/LoopVectorize/X86/parallel-loops.ll b/test/Transforms/LoopVectorize/X86/parallel-loops.ll
index b580d73..22ab521 100644
--- a/test/Transforms/LoopVectorize/X86/parallel-loops.ll
+++ b/test/Transforms/LoopVectorize/X86/parallel-loops.ll
@@ -104,8 +104,8 @@ for.end: ; preds = %for.body
ret void
}
-!3 = metadata !{metadata !3}
-!4 = metadata !{metadata !4}
-!5 = metadata !{metadata !3, metadata !4}
-!6 = metadata !{metadata !6}
-!7 = metadata !{metadata !7}
+!3 = !{!3}
+!4 = !{!4}
+!5 = !{!3, !4}
+!6 = !{!6}
+!7 = !{!7}
diff --git a/test/Transforms/LoopVectorize/X86/small-size.ll b/test/Transforms/LoopVectorize/X86/small-size.ll
index f9a0281..8c7a881 100644
--- a/test/Transforms/LoopVectorize/X86/small-size.ll
+++ b/test/Transforms/LoopVectorize/X86/small-size.ll
@@ -139,7 +139,7 @@ define void @example4(i32 %n, i32* noalias nocapture %p, i32* noalias nocapture
ret void
}
-!0 = metadata !{metadata !"branch_weights", i32 64, i32 4}
+!0 = !{!"branch_weights", i32 64, i32 4}
; We can't vectorize this one because we need a runtime ptr check.
;CHECK-LABEL: @example23(
diff --git a/test/Transforms/LoopVectorize/X86/vect.omp.force.ll b/test/Transforms/LoopVectorize/X86/vect.omp.force.ll
index 074313b..a781fbe 100644
--- a/test/Transforms/LoopVectorize/X86/vect.omp.force.ll
+++ b/test/Transforms/LoopVectorize/X86/vect.omp.force.ll
@@ -52,8 +52,8 @@ for.end:
ret void
}
-!1 = metadata !{metadata !1, metadata !2}
-!2 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+!1 = !{!1, !2}
+!2 = !{!"llvm.loop.vectorize.enable", i1 true}
;
; This method will not be vectorized, as scalar cost is lower than any of vector costs.
@@ -89,5 +89,5 @@ for.end:
declare float @llvm.sin.f32(float) nounwind readnone
; Dummy metadata
-!3 = metadata !{metadata !3}
+!3 = !{!3}
diff --git a/test/Transforms/LoopVectorize/X86/vect.omp.force.small-tc.ll b/test/Transforms/LoopVectorize/X86/vect.omp.force.small-tc.ll
index 97c31a1..e39e6b5 100644
--- a/test/Transforms/LoopVectorize/X86/vect.omp.force.small-tc.ll
+++ b/test/Transforms/LoopVectorize/X86/vect.omp.force.small-tc.ll
@@ -43,8 +43,8 @@ for.end:
ret void
}
-!1 = metadata !{metadata !1, metadata !2}
-!2 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+!1 = !{!1, !2}
+!2 = !{!"llvm.loop.vectorize.enable", i1 true}
;
; This loop will not be vectorized as the trip count is below the threshold.
@@ -69,5 +69,5 @@ for.end:
ret void
}
-!3 = metadata !{metadata !3}
+!3 = !{!3}
diff --git a/test/Transforms/LoopVectorize/X86/vector-scalar-select-cost.ll b/test/Transforms/LoopVectorize/X86/vector-scalar-select-cost.ll
index 3b3a787..ece9895 100644
--- a/test/Transforms/LoopVectorize/X86/vector-scalar-select-cost.ll
+++ b/test/Transforms/LoopVectorize/X86/vector-scalar-select-cost.ll
@@ -50,8 +50,8 @@ define void @vectorselect(i1 %cond) {
%7 = getelementptr inbounds [2048 x i32]* @a, i64 0, i64 %indvars.iv
%8 = icmp ult i64 %indvars.iv, 8
-; A vector select has a cost of 4 on core2
-; CHECK: cost of 4 for VF 2 {{.*}} select i1 %8, i32 %6, i32 0
+; A vector select has a cost of 1 on core2
+; CHECK: cost of 1 for VF 2 {{.*}} select i1 %8, i32 %6, i32 0
%sel = select i1 %8, i32 %6, i32 zeroinitializer
store i32 %sel, i32* %7, align 4
diff --git a/test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll b/test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll
index 7bce11d..011ce8e 100644
--- a/test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll
+++ b/test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll
@@ -122,40 +122,40 @@ attributes #0 = { nounwind }
!llvm.module.flags = !{!9, !10}
!llvm.ident = !{!11}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0\001\00\006\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [./source.cpp] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"source.cpp", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4, metadata !7, metadata !8}
-!4 = metadata !{metadata !"0x2e\00test\00test\00\001\000\001\000\006\00256\001\001", metadata !1, metadata !5, metadata !6, null, void (i32*, i32)* @_Z4testPii, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [test]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./source.cpp]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !"0x2e\00test_disabled\00test_disabled\00\0010\000\001\000\006\00256\001\0010", metadata !1, metadata !5, metadata !6, null, void (i32*, i32)* @_Z13test_disabledPii, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 10] [def] [test_disabled]
-!8 = metadata !{metadata !"0x2e\00test_array_bounds\00test_array_bounds\00\0016\000\001\000\006\00256\001\0016", metadata !1, metadata !5, metadata !6, null, void (i32*, i32*, i32)* @_Z17test_array_boundsPiS_i, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 16] [def] [test_array_bounds]
-!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!10 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!11 = metadata !{metadata !"clang version 3.5.0"}
-!12 = metadata !{i32 3, i32 8, metadata !13, null}
-!13 = metadata !{metadata !"0xb\003\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ]
-!14 = metadata !{metadata !14, metadata !15, metadata !15}
-!15 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
-!16 = metadata !{i32 4, i32 5, metadata !17, null}
-!17 = metadata !{metadata !"0xb\003\0036\000", metadata !1, metadata !13} ; [ DW_TAG_lexical_block ]
-!18 = metadata !{metadata !19, metadata !19, i64 0}
-!19 = metadata !{metadata !"int", metadata !20, i64 0}
-!20 = metadata !{metadata !"omnipotent char", metadata !21, i64 0}
-!21 = metadata !{metadata !"Simple C/C++ TBAA"}
-!22 = metadata !{i32 5, i32 9, metadata !23, null}
-!23 = metadata !{metadata !"0xb\005\009\000", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ]
-!24 = metadata !{i32 8, i32 1, metadata !4, null}
-!25 = metadata !{i32 12, i32 8, metadata !26, null}
-!26 = metadata !{metadata !"0xb\0012\003\000", metadata !1, metadata !7} ; [ DW_TAG_lexical_block ]
-!27 = metadata !{metadata !27, metadata !28, metadata !29}
-!28 = metadata !{metadata !"llvm.loop.interleave.count", i32 1}
-!29 = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
-!30 = metadata !{i32 13, i32 5, metadata !26, null}
-!31 = metadata !{i32 14, i32 1, metadata !7, null}
-!32 = metadata !{i32 18, i32 8, metadata !33, null}
-!33 = metadata !{metadata !"0xb\0018\003\000", metadata !1, metadata !8} ; [ DW_TAG_lexical_block ]
-!34 = metadata !{metadata !34, metadata !15}
-!35 = metadata !{i32 19, i32 5, metadata !33, null}
-!36 = metadata !{i32 20, i32 1, metadata !8, null}
+!0 = !{!"0x11\004\00clang version 3.5.0\001\00\006\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [./source.cpp] [DW_LANG_C_plus_plus]
+!1 = !{!"source.cpp", !"."}
+!2 = !{}
+!3 = !{!4, !7, !8}
+!4 = !{!"0x2e\00test\00test\00\001\000\001\000\006\00256\001\001", !1, !5, !6, null, void (i32*, i32)* @_Z4testPii, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [test]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./source.cpp]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!"0x2e\00test_disabled\00test_disabled\00\0010\000\001\000\006\00256\001\0010", !1, !5, !6, null, void (i32*, i32)* @_Z13test_disabledPii, null, null, !2} ; [ DW_TAG_subprogram ] [line 10] [def] [test_disabled]
+!8 = !{!"0x2e\00test_array_bounds\00test_array_bounds\00\0016\000\001\000\006\00256\001\0016", !1, !5, !6, null, void (i32*, i32*, i32)* @_Z17test_array_boundsPiS_i, null, null, !2} ; [ DW_TAG_subprogram ] [line 16] [def] [test_array_bounds]
+!9 = !{i32 2, !"Dwarf Version", i32 2}
+!10 = !{i32 2, !"Debug Info Version", i32 2}
+!11 = !{!"clang version 3.5.0"}
+!12 = !MDLocation(line: 3, column: 8, scope: !13)
+!13 = !{!"0xb\003\003\000", !1, !4} ; [ DW_TAG_lexical_block ]
+!14 = !{!14, !15, !15}
+!15 = !{!"llvm.loop.vectorize.enable", i1 true}
+!16 = !MDLocation(line: 4, column: 5, scope: !17)
+!17 = !{!"0xb\003\0036\000", !1, !13} ; [ DW_TAG_lexical_block ]
+!18 = !{!19, !19, i64 0}
+!19 = !{!"int", !20, i64 0}
+!20 = !{!"omnipotent char", !21, i64 0}
+!21 = !{!"Simple C/C++ TBAA"}
+!22 = !MDLocation(line: 5, column: 9, scope: !23)
+!23 = !{!"0xb\005\009\000", !1, !17} ; [ DW_TAG_lexical_block ]
+!24 = !MDLocation(line: 8, column: 1, scope: !4)
+!25 = !MDLocation(line: 12, column: 8, scope: !26)
+!26 = !{!"0xb\0012\003\000", !1, !7} ; [ DW_TAG_lexical_block ]
+!27 = !{!27, !28, !29}
+!28 = !{!"llvm.loop.interleave.count", i32 1}
+!29 = !{!"llvm.loop.vectorize.width", i32 1}
+!30 = !MDLocation(line: 13, column: 5, scope: !26)
+!31 = !MDLocation(line: 14, column: 1, scope: !7)
+!32 = !MDLocation(line: 18, column: 8, scope: !33)
+!33 = !{!"0xb\0018\003\000", !1, !8} ; [ DW_TAG_lexical_block ]
+!34 = !{!34, !15}
+!35 = !MDLocation(line: 19, column: 5, scope: !33)
+!36 = !MDLocation(line: 20, column: 1, scope: !8)
diff --git a/test/Transforms/LoopVectorize/X86/vectorization-remarks.ll b/test/Transforms/LoopVectorize/X86/vectorization-remarks.ll
index 14e541a..16fe370 100644
--- a/test/Transforms/LoopVectorize/X86/vectorization-remarks.ll
+++ b/test/Transforms/LoopVectorize/X86/vectorization-remarks.ll
@@ -49,26 +49,26 @@ declare void @ibar(i32*) #1
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!1 = metadata !{metadata !"vectorization-remarks.c", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\005\000\001\000\006\00256\001\006", metadata !1, metadata !5, metadata !6, null, i32 (i32)* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 5] [def] [scope 6] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./vectorization-remarks.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!8 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5.0 "}
-!10 = metadata !{i32 8, i32 3, metadata !4, null}
-!11 = metadata !{metadata !12, metadata !12, i64 0}
-!12 = metadata !{metadata !"int", metadata !13, i64 0}
-!13 = metadata !{metadata !"omnipotent char", metadata !14, i64 0}
-!14 = metadata !{metadata !"Simple C/C++ TBAA"}
-!15 = metadata !{i32 17, i32 8, metadata !16, null}
-!16 = metadata !{metadata !"0xb\0017\008\002", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
-!17 = metadata !{metadata !"0xb\0017\008\001", metadata !1, metadata !18} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
-!18 = metadata !{metadata !"0xb\0017\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
-!19 = metadata !{i32 18, i32 5, metadata !20, null}
-!20 = metadata !{metadata !"0xb\0017\0027\000", metadata !1, metadata !18} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
-!21 = metadata !{metadata !13, metadata !13, i64 0}
-!22 = metadata !{i32 20, i32 3, metadata !4, null}
-!23 = metadata !{i32 21, i32 3, metadata !4, null}
+!1 = !{!"vectorization-remarks.c", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00foo\00foo\00\005\000\001\000\006\00256\001\006", !1, !5, !6, null, i32 (i32)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 5] [def] [scope 6] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./vectorization-remarks.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 1, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5.0 "}
+!10 = !MDLocation(line: 8, column: 3, scope: !4)
+!11 = !{!12, !12, i64 0}
+!12 = !{!"int", !13, i64 0}
+!13 = !{!"omnipotent char", !14, i64 0}
+!14 = !{!"Simple C/C++ TBAA"}
+!15 = !MDLocation(line: 17, column: 8, scope: !16)
+!16 = !{!"0xb\0017\008\002", !1, !17} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
+!17 = !{!"0xb\0017\008\001", !1, !18} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
+!18 = !{!"0xb\0017\003\000", !1, !4} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
+!19 = !MDLocation(line: 18, column: 5, scope: !20)
+!20 = !{!"0xb\0017\0027\000", !1, !18} ; [ DW_TAG_lexical_block ] [./vectorization-remarks.c]
+!21 = !{!13, !13, i64 0}
+!22 = !MDLocation(line: 20, column: 3, scope: !4)
+!23 = !MDLocation(line: 21, column: 3, scope: !4)
diff --git a/test/Transforms/LoopVectorize/conditional-assignment.ll b/test/Transforms/LoopVectorize/conditional-assignment.ll
index 50fa329..38e9c4f 100644
--- a/test/Transforms/LoopVectorize/conditional-assignment.ll
+++ b/test/Transforms/LoopVectorize/conditional-assignment.ll
@@ -36,23 +36,23 @@ attributes #0 = { nounwind }
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.6.0\001\00\000\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ]
-!1 = metadata !{metadata !"source.c", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00conditional_store\00conditional_store\00\001\000\001\000\006\00256\001\001", metadata !1, metadata !5, metadata !6, null, void (i32*)* @conditional_store, null, null, metadata !2} ; [ DW_TAG_subprogram ]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!8 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.6.0"}
-!10 = metadata !{i32 2, i32 8, metadata !11, null}
-!11 = metadata !{metadata !"0xb\002\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{i32 3, i32 9, metadata !13, null}
-!13 = metadata !{metadata !"0xb\003\009\000", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ]
-!14 = metadata !{metadata !15, metadata !15, i64 0}
-!15 = metadata !{metadata !"int", metadata !16, i64 0}
-!16 = metadata !{metadata !"omnipotent char", metadata !17, i64 0}
-!17 = metadata !{metadata !"Simple C/C++ TBAA"}
-!18 = metadata !{i32 3, i32 29, metadata !13, null}
-!19 = metadata !{i32 4, i32 1, metadata !4, null}
+!0 = !{!"0x11\0012\00clang version 3.6.0\001\00\000\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ]
+!1 = !{!"source.c", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00conditional_store\00conditional_store\00\001\000\001\000\006\00256\001\001", !1, !5, !6, null, void (i32*)* @conditional_store, null, null, !2} ; [ DW_TAG_subprogram ]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ]
+!7 = !{i32 2, !"Dwarf Version", i32 2}
+!8 = !{i32 2, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.6.0"}
+!10 = !MDLocation(line: 2, column: 8, scope: !11)
+!11 = !{!"0xb\002\003\000", !1, !4} ; [ DW_TAG_lexical_block ]
+!12 = !MDLocation(line: 3, column: 9, scope: !13)
+!13 = !{!"0xb\003\009\000", !1, !11} ; [ DW_TAG_lexical_block ]
+!14 = !{!15, !15, i64 0}
+!15 = !{!"int", !16, i64 0}
+!16 = !{!"omnipotent char", !17, i64 0}
+!17 = !{!"Simple C/C++ TBAA"}
+!18 = !MDLocation(line: 3, column: 29, scope: !13)
+!19 = !MDLocation(line: 4, column: 1, scope: !4)
diff --git a/test/Transforms/LoopVectorize/control-flow.ll b/test/Transforms/LoopVectorize/control-flow.ll
index 452b7ae..1882c3f 100644
--- a/test/Transforms/LoopVectorize/control-flow.ll
+++ b/test/Transforms/LoopVectorize/control-flow.ll
@@ -55,24 +55,24 @@ attributes #0 = { nounwind }
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0\001\00\006\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [./source.cpp] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"source.cpp", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00test\00test\00\001\000\001\000\006\00256\001\002", metadata !1, metadata !5, metadata !6, null, i32 (i32*, i32)* @_Z4testPii, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [scope 2] [test]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./source.cpp]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!8 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5.0"}
-!10 = metadata !{i32 3, i32 8, metadata !11, null}
-!11 = metadata !{metadata !"0xb\003\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{i32 5, i32 9, metadata !13, null}
-!13 = metadata !{metadata !"0xb\005\009\000", metadata !1, metadata !14} ; [ DW_TAG_lexical_block ]
-!14 = metadata !{metadata !"0xb\004\003\000", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ]
-!15 = metadata !{metadata !16, metadata !16, i64 0}
-!16 = metadata !{metadata !"int", metadata !17, i64 0}
-!17 = metadata !{metadata !"omnipotent char", metadata !18, i64 0}
-!18 = metadata !{metadata !"Simple C/C++ TBAA"}
-!19 = metadata !{i32 8, i32 7, metadata !13, null}
-!20 = metadata !{i32 12, i32 3, metadata !4, null}
+!0 = !{!"0x11\004\00clang version 3.5.0\001\00\006\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [./source.cpp] [DW_LANG_C_plus_plus]
+!1 = !{!"source.cpp", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00test\00test\00\001\000\001\000\006\00256\001\002", !1, !5, !6, null, i32 (i32*, i32)* @_Z4testPii, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [scope 2] [test]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./source.cpp]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 2}
+!8 = !{i32 2, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5.0"}
+!10 = !MDLocation(line: 3, column: 8, scope: !11)
+!11 = !{!"0xb\003\003\000", !1, !4} ; [ DW_TAG_lexical_block ]
+!12 = !MDLocation(line: 5, column: 9, scope: !13)
+!13 = !{!"0xb\005\009\000", !1, !14} ; [ DW_TAG_lexical_block ]
+!14 = !{!"0xb\004\003\000", !1, !11} ; [ DW_TAG_lexical_block ]
+!15 = !{!16, !16, i64 0}
+!16 = !{!"int", !17, i64 0}
+!17 = !{!"omnipotent char", !18, i64 0}
+!18 = !{!"Simple C/C++ TBAA"}
+!19 = !MDLocation(line: 8, column: 7, scope: !13)
+!20 = !MDLocation(line: 12, column: 3, scope: !4)
diff --git a/test/Transforms/LoopVectorize/dbg.value.ll b/test/Transforms/LoopVectorize/dbg.value.ll
index 91d07d4..92d3154 100644
--- a/test/Transforms/LoopVectorize/dbg.value.ll
+++ b/test/Transforms/LoopVectorize/dbg.value.ll
@@ -11,7 +11,7 @@ target triple = "x86_64-apple-macosx10.8.0"
; CHECK-LABEL: @test(
define i32 @test() #0 {
entry:
- tail call void @llvm.dbg.value(metadata !1, i64 0, metadata !9, metadata !{}), !dbg !18
+ tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !9, metadata !{}), !dbg !18
br label %for.body, !dbg !18
for.body:
@@ -44,27 +44,27 @@ attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!26}
-!0 = metadata !{metadata !"0x11\004\00clang\001\00\000\00\000", metadata !25, metadata !1, metadata !1, metadata !2, metadata !11, null} ; [ DW_TAG_compile_unit ]
-!1 = metadata !{i32 0}
-!2 = metadata !{metadata !3}
-!3 = metadata !{metadata !"0x2e\00test\00test\00test\005\000\001\000\006\00256\001\005", metadata !25, metadata !4, metadata !5, null, i32 ()* @test, null, null, metadata !8} ; [ DW_TAG_subprogram ]
-!4 = metadata !{metadata !"0x29", metadata !25} ; [ DW_TAG_file_type ]
-!5 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !6, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!6 = metadata !{metadata !7}
-!7 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ]
-!8 = metadata !{metadata !9}
-!9 = metadata !{metadata !"0x100\00i\006\000", metadata !10, metadata !4, metadata !7} ; [ DW_TAG_auto_variable ]
-!10 = metadata !{metadata !"0xb\006\000\000", metadata !25, metadata !3} ; [ DW_TAG_lexical_block ]
-!11 = metadata !{metadata !12, metadata !16, metadata !17}
-!12 = metadata !{metadata !"0x34\00A\00A\00\001\000\001", null, metadata !4, metadata !13, [1024 x i32]* @A, null} ; [ DW_TAG_variable ]
-!13 = metadata !{metadata !"0x1\00\000\0032768\0032\000\000", null, null, metadata !7, metadata !14, i32 0, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 32768, align 32, offset 0] [from int]
-!14 = metadata !{metadata !15}
-!15 = metadata !{i32 786465, i64 0, i64 1024}
-!16 = metadata !{metadata !"0x34\00B\00B\00\002\000\001", null, metadata !4, metadata !13, [1024 x i32]* @B, null} ; [ DW_TAG_variable ]
-!17 = metadata !{metadata !"0x34\00C\00C\00\003\000\001", null, metadata !4, metadata !13, [1024 x i32]* @C, null} ; [ DW_TAG_variable ]
-!18 = metadata !{i32 6, i32 0, metadata !10, null}
-!19 = metadata !{i32 7, i32 0, metadata !20, null}
-!20 = metadata !{metadata !"0xb\006\000\001", metadata !25, metadata !10} ; [ DW_TAG_lexical_block ]
-!24 = metadata !{i32 9, i32 0, metadata !3, null}
-!25 = metadata !{metadata !"test", metadata !"/path/to/somewhere"}
-!26 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\004\00clang\001\00\000\00\000", !25, !1, !1, !2, !11, null} ; [ DW_TAG_compile_unit ]
+!1 = !{i32 0}
+!2 = !{!3}
+!3 = !{!"0x2e\00test\00test\00test\005\000\001\000\006\00256\001\005", !25, !4, !5, null, i32 ()* @test, null, null, !8} ; [ DW_TAG_subprogram ]
+!4 = !{!"0x29", !25} ; [ DW_TAG_file_type ]
+!5 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !6, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!6 = !{!7}
+!7 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ]
+!8 = !{!9}
+!9 = !{!"0x100\00i\006\000", !10, !4, !7} ; [ DW_TAG_auto_variable ]
+!10 = !{!"0xb\006\000\000", !25, !3} ; [ DW_TAG_lexical_block ]
+!11 = !{!12, !16, !17}
+!12 = !{!"0x34\00A\00A\00\001\000\001", null, !4, !13, [1024 x i32]* @A, null} ; [ DW_TAG_variable ]
+!13 = !{!"0x1\00\000\0032768\0032\000\000", null, null, !7, !14, i32 0, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 32768, align 32, offset 0] [from int]
+!14 = !{!15}
+!15 = !{i32 786465, i64 0, i64 1024}
+!16 = !{!"0x34\00B\00B\00\002\000\001", null, !4, !13, [1024 x i32]* @B, null} ; [ DW_TAG_variable ]
+!17 = !{!"0x34\00C\00C\00\003\000\001", null, !4, !13, [1024 x i32]* @C, null} ; [ DW_TAG_variable ]
+!18 = !MDLocation(line: 6, scope: !10)
+!19 = !MDLocation(line: 7, scope: !20)
+!20 = !{!"0xb\006\000\001", !25, !10} ; [ DW_TAG_lexical_block ]
+!24 = !MDLocation(line: 9, scope: !3)
+!25 = !{!"test", !"/path/to/somewhere"}
+!26 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/LoopVectorize/debugloc.ll b/test/Transforms/LoopVectorize/debugloc.ll
index 6350296..634bf79 100644
--- a/test/Transforms/LoopVectorize/debugloc.ll
+++ b/test/Transforms/LoopVectorize/debugloc.ll
@@ -19,10 +19,10 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
define i32 @f(i32* nocapture %a, i32 %size) #0 {
entry:
- tail call void @llvm.dbg.value(metadata !{i32* %a}, i64 0, metadata !13, metadata !{}), !dbg !19
- tail call void @llvm.dbg.value(metadata !{i32 %size}, i64 0, metadata !14, metadata !{}), !dbg !19
- tail call void @llvm.dbg.value(metadata !2, i64 0, metadata !15, metadata !{}), !dbg !20
- tail call void @llvm.dbg.value(metadata !2, i64 0, metadata !16, metadata !{}), !dbg !21
+ tail call void @llvm.dbg.value(metadata i32* %a, i64 0, metadata !13, metadata !{}), !dbg !19
+ tail call void @llvm.dbg.value(metadata i32 %size, i64 0, metadata !14, metadata !{}), !dbg !19
+ tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !15, metadata !{}), !dbg !20
+ tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !16, metadata !{}), !dbg !21
%cmp4 = icmp eq i32 %size, 0, !dbg !21
br i1 %cmp4, label %for.end, label %for.body.lr.ph, !dbg !21
@@ -35,7 +35,7 @@ for.body: ; preds = %for.body.lr.ph, %fo
%arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv, !dbg !22
%0 = load i32* %arrayidx, align 4, !dbg !22
%add = add i32 %0, %sum.05, !dbg !22
- tail call void @llvm.dbg.value(metadata !{i32 %add.lcssa}, i64 0, metadata !15, metadata !{}), !dbg !22
+ tail call void @llvm.dbg.value(metadata i32 %add.lcssa, i64 0, metadata !15, metadata !{}), !dbg !22
%indvars.iv.next = add i64 %indvars.iv, 1, !dbg !21
tail call void @llvm.dbg.value(metadata !{null}, i64 0, metadata !16, metadata !{}), !dbg !21
%lftr.wideiv = trunc i64 %indvars.iv.next to i32, !dbg !21
@@ -63,28 +63,28 @@ attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!18, !27}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.4 (trunk 185038) (llvm/trunk 185097)\001\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/Volumes/Data/backedup/dev/os/llvm/debug/-] [DW_LANG_C99]
-!1 = metadata !{metadata !"-", metadata !"/Volumes/Data/backedup/dev/os/llvm/debug"}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00f\00f\00\003\000\001\000\006\00256\001\003", metadata !5, metadata !6, metadata !7, null, i32 (i32*, i32)* @f, null, null, metadata !12} ; [ DW_TAG_subprogram ] [line 3] [def] [f]
-!5 = metadata !{metadata !"<stdin>", metadata !"/Volumes/Data/backedup/dev/os/llvm/debug"}
-!6 = metadata !{metadata !"0x29", metadata !5} ; [ DW_TAG_file_type ] [/Volumes/Data/backedup/dev/os/llvm/debug/<stdin>]
-!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!8 = metadata !{metadata !9, metadata !10, metadata !11}
-!9 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!10 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
-!11 = metadata !{metadata !"0x24\00unsigned int\000\0032\0032\000\000\007", null, null} ; [ DW_TAG_base_type ] [unsigned int] [line 0, size 32, align 32, offset 0, enc DW_ATE_unsigned]
-!12 = metadata !{metadata !13, metadata !14, metadata !15, metadata !16}
-!13 = metadata !{metadata !"0x101\00a\0016777219\000", metadata !4, metadata !6, metadata !10} ; [ DW_TAG_arg_variable ] [a] [line 3]
-!14 = metadata !{metadata !"0x101\00size\0033554435\000", metadata !4, metadata !6, metadata !11} ; [ DW_TAG_arg_variable ] [size] [line 3]
-!15 = metadata !{metadata !"0x100\00sum\004\000", metadata !4, metadata !6, metadata !11} ; [ DW_TAG_auto_variable ] [sum] [line 4]
-!16 = metadata !{metadata !"0x100\00i\005\000", metadata !17, metadata !6, metadata !11} ; [ DW_TAG_auto_variable ] [i] [line 5]
-!17 = metadata !{metadata !"0xb\005\000\000", metadata !5, metadata !4} ; [ DW_TAG_lexical_block ] [/Volumes/Data/backedup/dev/os/llvm/debug/<stdin>]
-!18 = metadata !{i32 2, metadata !"Dwarf Version", i32 3}
-!19 = metadata !{i32 3, i32 0, metadata !4, null}
-!20 = metadata !{i32 4, i32 0, metadata !4, null}
-!21 = metadata !{i32 5, i32 0, metadata !17, null}
-!22 = metadata !{i32 6, i32 0, metadata !17, null}
-!26 = metadata !{i32 7, i32 0, metadata !4, null}
-!27 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\0012\00clang version 3.4 (trunk 185038) (llvm/trunk 185097)\001\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/Volumes/Data/backedup/dev/os/llvm/debug/-] [DW_LANG_C99]
+!1 = !{!"-", !"/Volumes/Data/backedup/dev/os/llvm/debug"}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00f\00f\00\003\000\001\000\006\00256\001\003", !5, !6, !7, null, i32 (i32*, i32)* @f, null, null, !12} ; [ DW_TAG_subprogram ] [line 3] [def] [f]
+!5 = !{!"<stdin>", !"/Volumes/Data/backedup/dev/os/llvm/debug"}
+!6 = !{!"0x29", !5} ; [ DW_TAG_file_type ] [/Volumes/Data/backedup/dev/os/llvm/debug/<stdin>]
+!7 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = !{!9, !10, !11}
+!9 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!10 = !{!"0xf\00\000\0064\0064\000\000", null, null, !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
+!11 = !{!"0x24\00unsigned int\000\0032\0032\000\000\007", null, null} ; [ DW_TAG_base_type ] [unsigned int] [line 0, size 32, align 32, offset 0, enc DW_ATE_unsigned]
+!12 = !{!13, !14, !15, !16}
+!13 = !{!"0x101\00a\0016777219\000", !4, !6, !10} ; [ DW_TAG_arg_variable ] [a] [line 3]
+!14 = !{!"0x101\00size\0033554435\000", !4, !6, !11} ; [ DW_TAG_arg_variable ] [size] [line 3]
+!15 = !{!"0x100\00sum\004\000", !4, !6, !11} ; [ DW_TAG_auto_variable ] [sum] [line 4]
+!16 = !{!"0x100\00i\005\000", !17, !6, !11} ; [ DW_TAG_auto_variable ] [i] [line 5]
+!17 = !{!"0xb\005\000\000", !5, !4} ; [ DW_TAG_lexical_block ] [/Volumes/Data/backedup/dev/os/llvm/debug/<stdin>]
+!18 = !{i32 2, !"Dwarf Version", i32 3}
+!19 = !MDLocation(line: 3, scope: !4)
+!20 = !MDLocation(line: 4, scope: !4)
+!21 = !MDLocation(line: 5, scope: !17)
+!22 = !MDLocation(line: 6, scope: !17)
+!26 = !MDLocation(line: 7, scope: !4)
+!27 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/LoopVectorize/duplicated-metadata.ll b/test/Transforms/LoopVectorize/duplicated-metadata.ll
index 8353dca..bf2f899 100644
--- a/test/Transforms/LoopVectorize/duplicated-metadata.ll
+++ b/test/Transforms/LoopVectorize/duplicated-metadata.ll
@@ -24,7 +24,7 @@ for.end: ; preds = %for.body
ret void
}
-!0 = metadata !{metadata !0, metadata !1}
-!1 = metadata !{metadata !"llvm.loop.vectorize.width", i32 4}
+!0 = !{!0, !1}
+!1 = !{!"llvm.loop.vectorize.width", i32 4}
; CHECK-NOT: !{metadata !"llvm.loop.vectorize.width", i32 4}
-; CHECK: !{metadata !"llvm.loop.interleave.count", i32 1}
+; CHECK: !{!"llvm.loop.interleave.count", i32 1}
diff --git a/test/Transforms/LoopVectorize/gcc-examples.ll b/test/Transforms/LoopVectorize/gcc-examples.ll
index 6c8af0b..6a2c2c6 100644
--- a/test/Transforms/LoopVectorize/gcc-examples.ll
+++ b/test/Transforms/LoopVectorize/gcc-examples.ll
@@ -388,9 +388,8 @@ define void @example12() nounwind uwtable ssp {
ret void
}
-; Can't vectorize because of reductions.
;CHECK-LABEL: @example13(
-;CHECK-NOT: <4 x i32>
+;CHECK: <4 x i32>
;CHECK: ret void
define void @example13(i32** nocapture %A, i32** nocapture %B, i32* nocapture %out) nounwind uwtable ssp {
br label %.preheader
diff --git a/test/Transforms/LoopVectorize/if-conversion-edgemasks.ll b/test/Transforms/LoopVectorize/if-conversion-edgemasks.ll
index 27c274d..8b8408b 100644
--- a/test/Transforms/LoopVectorize/if-conversion-edgemasks.ll
+++ b/test/Transforms/LoopVectorize/if-conversion-edgemasks.ll
@@ -20,7 +20,10 @@ entry:
br i1 %cmp88, label %for.body.lr.ph, label %for.end
for.body.lr.ph:
- %0 = load i32** @b, align 8 %1 = load i32** @a, align 8 %2 = load i32** @c, align 8 br label %for.body
+ %0 = load i32** @b, align 8
+ %1 = load i32** @a, align 8
+ %2 = load i32** @c, align 8
+ br label %for.body
for.body:
%indvars.iv = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next, %_ZL3fn3ii.exit58 ]
diff --git a/test/Transforms/LoopVectorize/if-conversion.ll b/test/Transforms/LoopVectorize/if-conversion.ll
index 9e18528..a220203 100644
--- a/test/Transforms/LoopVectorize/if-conversion.ll
+++ b/test/Transforms/LoopVectorize/if-conversion.ll
@@ -19,9 +19,9 @@ target triple = "x86_64-apple-macosx10.9.0"
;CHECK-LABEL: @function0(
;CHECK: load <4 x i32>
-;CHECK: icmp sgt <4 x i32>
;CHECK: mul <4 x i32>
;CHECK: add <4 x i32>
+;CHECK: icmp sle <4 x i32>
;CHECK: select <4 x i1>
;CHECK: ret i32
define i32 @function0(i32* nocapture %a, i32* nocapture %b, i32 %start, i32 %end) nounwind uwtable ssp {
@@ -72,8 +72,8 @@ for.end:
;CHECK-LABEL: @reduction_func(
;CHECK: load <4 x i32>
-;CHECK: icmp sgt <4 x i32>
;CHECK: add <4 x i32>
+;CHECK: icmp sle <4 x i32>
;CHECK: select <4 x i1>
;CHECK: ret i32
define i32 @reduction_func(i32* nocapture %A, i32 %n) nounwind uwtable readonly ssp {
diff --git a/test/Transforms/LoopVectorize/incorrect-dom-info.ll b/test/Transforms/LoopVectorize/incorrect-dom-info.ll
index 624ee7e..b8624fd 100644
--- a/test/Transforms/LoopVectorize/incorrect-dom-info.ll
+++ b/test/Transforms/LoopVectorize/incorrect-dom-info.ll
@@ -139,4 +139,4 @@ attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-po
!llvm.ident = !{!0}
-!0 = metadata !{metadata !"clang version 3.6.0 "}
+!0 = !{!"clang version 3.6.0 "}
diff --git a/test/Transforms/LoopVectorize/loop-form.ll b/test/Transforms/LoopVectorize/loop-form.ll
new file mode 100644
index 0000000..138df1d
--- /dev/null
+++ b/test/Transforms/LoopVectorize/loop-form.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -loop-vectorize < %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+; Check that we vectorize only bottom-tested loops.
+; This is a reduced testcase from PR21302.
+;
+; rdar://problem/18886083
+
+%struct.X = type { i32, i16 }
+; CHECK-LABEL: @foo(
+; CHECK-NOT: vector.body
+
+define void @foo(i32 %n) {
+entry:
+ br label %for.cond
+
+for.cond:
+ %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %cmp = icmp slt i32 %i, %n
+ br i1 %cmp, label %for.body, label %if.end
+
+for.body:
+ %iprom = sext i32 %i to i64
+ %b = getelementptr inbounds %struct.X* undef, i64 %iprom, i32 1
+ store i16 0, i16* %b, align 4
+ %inc = add nsw i32 %i, 1
+ br label %for.cond
+
+if.end:
+ ret void
+}
diff --git a/test/Transforms/LoopVectorize/loop-vect-memdep.ll b/test/Transforms/LoopVectorize/loop-vect-memdep.ll
new file mode 100644
index 0000000..e2c7524
--- /dev/null
+++ b/test/Transforms/LoopVectorize/loop-vect-memdep.ll
@@ -0,0 +1,26 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+; RUN: opt < %s -S -loop-vectorize -debug-only=loop-vectorize 2>&1 | FileCheck %s
+; REQUIRES: asserts
+; CHECK: LV: Can't vectorize due to memory conflicts
+
+define void @test_loop_novect(double** %arr, i64 %n) {
+for.body.lr.ph:
+ %t = load double** %arr, align 8
+ br label %for.body
+
+for.body: ; preds = %for.body, %for.body.lr.ph
+ %i = phi i64 [ 0, %for.body.lr.ph ], [ %i.next, %for.body ]
+ %a = getelementptr inbounds double* %t, i64 %i
+ %i.next = add nuw nsw i64 %i, 1
+ %a.next = getelementptr inbounds double* %t, i64 %i.next
+ %t1 = load double* %a, align 8
+ %t2 = load double* %a.next, align 8
+ store double %t1, double* %a.next, align 8
+ store double %t2, double* %a, align 8
+ %c = icmp eq i64 %i, %n
+ br i1 %c, label %final, label %for.body
+
+final: ; preds = %for.body
+ ret void
+}
diff --git a/test/Transforms/LoopVectorize/metadata-unroll.ll b/test/Transforms/LoopVectorize/metadata-unroll.ll
index 848f1f9..36a2314 100644
--- a/test/Transforms/LoopVectorize/metadata-unroll.ll
+++ b/test/Transforms/LoopVectorize/metadata-unroll.ll
@@ -37,5 +37,5 @@ define void @inc(i32 %n) nounwind uwtable noinline ssp {
ret void
}
-!0 = metadata !{metadata !0, metadata !1}
-!1 = metadata !{metadata !"llvm.loop.interleave.count", i32 2}
+!0 = !{!0, !1}
+!1 = !{!"llvm.loop.interleave.count", i32 2}
diff --git a/test/Transforms/LoopVectorize/metadata-width.ll b/test/Transforms/LoopVectorize/metadata-width.ll
index da0c622..dee4fee 100644
--- a/test/Transforms/LoopVectorize/metadata-width.ll
+++ b/test/Transforms/LoopVectorize/metadata-width.ll
@@ -27,5 +27,5 @@ for.end: ; preds = %for.body, %entry
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!0 = metadata !{metadata !0, metadata !1}
-!1 = metadata !{metadata !"llvm.loop.vectorize.width", i32 8}
+!0 = !{!0, !1}
+!1 = !{!"llvm.loop.vectorize.width", i32 8}
diff --git a/test/Transforms/LoopVectorize/metadata.ll b/test/Transforms/LoopVectorize/metadata.ll
index 14f60b3..a258f7c 100644
--- a/test/Transforms/LoopVectorize/metadata.ll
+++ b/test/Transforms/LoopVectorize/metadata.ll
@@ -27,18 +27,18 @@ for.end: ; preds = %for.body
; CHECK: store <4 x i32> %{{.*}}, <4 x i32>* %{{.*}}, align 4, !tbaa ![[TINT:[0-9]+]]
; CHECK: ret i32 0
-; CHECK-DAG: ![[TFLT]] = metadata !{metadata ![[TFLT1:[0-9]+]]
-; CHECK-DAG: ![[TFLT1]] = metadata !{metadata !"float"
+; CHECK-DAG: ![[TFLT]] = !{![[TFLT1:[0-9]+]]
+; CHECK-DAG: ![[TFLT1]] = !{!"float"
-; CHECK-DAG: ![[TINT]] = metadata !{metadata ![[TINT1:[0-9]+]]
-; CHECK-DAG: ![[TINT1]] = metadata !{metadata !"int"
+; CHECK-DAG: ![[TINT]] = !{![[TINT1:[0-9]+]]
+; CHECK-DAG: ![[TINT1]] = !{!"int"
attributes #0 = { nounwind uwtable }
-!0 = metadata !{metadata !1, metadata !1, i64 0}
-!1 = metadata !{metadata !"float", metadata !2, i64 0}
-!2 = metadata !{metadata !"omnipotent char", metadata !3, i64 0}
-!3 = metadata !{metadata !"Simple C/C++ TBAA"}
-!4 = metadata !{metadata !5, metadata !5, i64 0}
-!5 = metadata !{metadata !"int", metadata !2, i64 0}
+!0 = !{!1, !1, i64 0}
+!1 = !{!"float", !2, i64 0}
+!2 = !{!"omnipotent char", !3, i64 0}
+!3 = !{!"Simple C/C++ TBAA"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !2, i64 0}
diff --git a/test/Transforms/LoopVectorize/minmax_reduction.ll b/test/Transforms/LoopVectorize/minmax_reduction.ll
index e73e69d..1984cdd 100644
--- a/test/Transforms/LoopVectorize/minmax_reduction.ll
+++ b/test/Transforms/LoopVectorize/minmax_reduction.ll
@@ -516,7 +516,7 @@ for.end:
}
; CHECK-LABEL: @unordered_max_red_float(
-; CHECK: fcmp ugt <2 x float>
+; CHECK: fcmp ole <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp ogt <2 x float>
@@ -542,7 +542,7 @@ for.end:
}
; CHECK-LABEL: @unordered_max_red_float_ge(
-; CHECK: fcmp uge <2 x float>
+; CHECK: fcmp olt <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp ogt <2 x float>
@@ -568,7 +568,7 @@ for.end:
}
; CHECK-LABEL: @inverted_unordered_max_red_float(
-; CHECK: fcmp ult <2 x float>
+; CHECK: fcmp oge <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp ogt <2 x float>
@@ -594,7 +594,7 @@ for.end:
}
; CHECK-LABEL: @inverted_unordered_max_red_float_le(
-; CHECK: fcmp ule <2 x float>
+; CHECK: fcmp ogt <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp ogt <2 x float>
@@ -727,7 +727,7 @@ for.end:
}
; CHECK-LABEL: @unordered_min_red_float(
-; CHECK: fcmp ult <2 x float>
+; CHECK: fcmp oge <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp olt <2 x float>
@@ -753,7 +753,7 @@ for.end:
}
; CHECK-LABEL: @unordered_min_red_float_le(
-; CHECK: fcmp ule <2 x float>
+; CHECK: fcmp ogt <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp olt <2 x float>
@@ -779,7 +779,7 @@ for.end:
}
; CHECK-LABEL: @inverted_unordered_min_red_float(
-; CHECK: fcmp ugt <2 x float>
+; CHECK: fcmp ole <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp olt <2 x float>
@@ -805,7 +805,7 @@ for.end:
}
; CHECK-LABEL: @inverted_unordered_min_red_float_ge(
-; CHECK: fcmp uge <2 x float>
+; CHECK: fcmp olt <2 x float>
; CHECK: select <2 x i1>
; CHECK: middle.block
; CHECK: fcmp olt <2 x float>
diff --git a/test/Transforms/LoopVectorize/no_array_bounds.ll b/test/Transforms/LoopVectorize/no_array_bounds.ll
index a39b44f..d3bd755 100644
--- a/test/Transforms/LoopVectorize/no_array_bounds.ll
+++ b/test/Transforms/LoopVectorize/no_array_bounds.ll
@@ -72,30 +72,30 @@ attributes #0 = { nounwind }
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0\001\00\000\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ]
-!1 = metadata !{metadata !"no_array_bounds.cpp", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00test\00test\00\001\000\001\000\006\00256\001\002", metadata !1, metadata !5, metadata !6, null, void (i32*, i32*, i32)* @_Z4testPiS_i, null, null, metadata !2} ; [ DW_TAG_subprogram ]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!8 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5.0"}
-!10 = metadata !{i32 4, i32 8, metadata !11, null}
-!11 = metadata !{metadata !"0xb\004\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{metadata !12, metadata !13}
-!13 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
-!14 = metadata !{i32 5, i32 5, metadata !15, null}
-!15 = metadata !{metadata !"0xb\004\0036\000", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ]
-!16 = metadata !{i32 9, i32 8, metadata !17, null}
-!17 = metadata !{metadata !"0xb\009\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ]
-!18 = metadata !{metadata !18, metadata !13, metadata !19}
-!19 = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
-!20 = metadata !{i32 10, i32 5, metadata !21, null}
-!21 = metadata !{metadata !"0xb\009\0036\000", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ]
-!22 = metadata !{metadata !23, metadata !23, i64 0}
-!23 = metadata !{metadata !"int", metadata !24, i64 0}
-!24 = metadata !{metadata !"omnipotent char", metadata !25, i64 0}
-!25 = metadata !{metadata !"Simple C/C++ TBAA"}
-!26 = metadata !{i32 12, i32 1, metadata !4, null}
+!0 = !{!"0x11\004\00clang version 3.5.0\001\00\000\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ]
+!1 = !{!"no_array_bounds.cpp", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00test\00test\00\001\000\001\000\006\00256\001\002", !1, !5, !6, null, void (i32*, i32*, i32)* @_Z4testPiS_i, null, null, !2} ; [ DW_TAG_subprogram ]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ]
+!7 = !{i32 2, !"Dwarf Version", i32 2}
+!8 = !{i32 2, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5.0"}
+!10 = !MDLocation(line: 4, column: 8, scope: !11)
+!11 = !{!"0xb\004\003\000", !1, !4} ; [ DW_TAG_lexical_block ]
+!12 = !{!12, !13}
+!13 = !{!"llvm.loop.vectorize.enable", i1 true}
+!14 = !MDLocation(line: 5, column: 5, scope: !15)
+!15 = !{!"0xb\004\0036\000", !1, !11} ; [ DW_TAG_lexical_block ]
+!16 = !MDLocation(line: 9, column: 8, scope: !17)
+!17 = !{!"0xb\009\003\000", !1, !4} ; [ DW_TAG_lexical_block ]
+!18 = !{!18, !13, !19}
+!19 = !{!"llvm.loop.vectorize.width", i32 1}
+!20 = !MDLocation(line: 10, column: 5, scope: !21)
+!21 = !{!"0xb\009\0036\000", !1, !17} ; [ DW_TAG_lexical_block ]
+!22 = !{!23, !23, i64 0}
+!23 = !{!"int", !24, i64 0}
+!24 = !{!"omnipotent char", !25, i64 0}
+!25 = !{!"Simple C/C++ TBAA"}
+!26 = !MDLocation(line: 12, column: 1, scope: !4)
diff --git a/test/Transforms/LoopVectorize/no_switch.ll b/test/Transforms/LoopVectorize/no_switch.ll
index c989c6b..64aab37 100644
--- a/test/Transforms/LoopVectorize/no_switch.ll
+++ b/test/Transforms/LoopVectorize/no_switch.ll
@@ -59,28 +59,28 @@ attributes #0 = { nounwind }
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0\001\00\006\00\002", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [./source.cpp] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"source.cpp", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00test_switch\00test_switch\00\001\000\001\000\006\00256\001\001", metadata !1, metadata !5, metadata !6, null, void (i32*, i32)* @_Z11test_switchPii, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [test_switch]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./source.cpp]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!8 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5.0"}
-!10 = metadata !{i32 3, i32 8, metadata !11, null}
-!11 = metadata !{metadata !"0xb\003\003\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{metadata !12, metadata !13, metadata !13}
-!13 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
-!14 = metadata !{i32 4, i32 5, metadata !15, null}
-!15 = metadata !{metadata !"0xb\003\0036\000", metadata !1, metadata !11} ; [ DW_TAG_lexical_block ]
-!16 = metadata !{metadata !17, metadata !17, i64 0}
-!17 = metadata !{metadata !"int", metadata !18, i64 0}
-!18 = metadata !{metadata !"omnipotent char", metadata !19, i64 0}
-!19 = metadata !{metadata !"Simple C/C++ TBAA"}
-!20 = metadata !{i32 6, i32 7, metadata !21, null}
-!21 = metadata !{metadata !"0xb\004\0018\000", metadata !1, metadata !15} ; [ DW_TAG_lexical_block ]
-!22 = metadata !{i32 7, i32 5, metadata !21, null}
-!23 = metadata !{i32 9, i32 7, metadata !21, null}
-!24 = metadata !{i32 14, i32 1, metadata !4, null}
+!0 = !{!"0x11\004\00clang version 3.5.0\001\00\006\00\002", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [./source.cpp] [DW_LANG_C_plus_plus]
+!1 = !{!"source.cpp", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00test_switch\00test_switch\00\001\000\001\000\006\00256\001\001", !1, !5, !6, null, void (i32*, i32)* @_Z11test_switchPii, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [test_switch]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./source.cpp]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 2}
+!8 = !{i32 2, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5.0"}
+!10 = !MDLocation(line: 3, column: 8, scope: !11)
+!11 = !{!"0xb\003\003\000", !1, !4} ; [ DW_TAG_lexical_block ]
+!12 = !{!12, !13, !13}
+!13 = !{!"llvm.loop.vectorize.enable", i1 true}
+!14 = !MDLocation(line: 4, column: 5, scope: !15)
+!15 = !{!"0xb\003\0036\000", !1, !11} ; [ DW_TAG_lexical_block ]
+!16 = !{!17, !17, i64 0}
+!17 = !{!"int", !18, i64 0}
+!18 = !{!"omnipotent char", !19, i64 0}
+!19 = !{!"Simple C/C++ TBAA"}
+!20 = !MDLocation(line: 6, column: 7, scope: !21)
+!21 = !{!"0xb\004\0018\000", !1, !15} ; [ DW_TAG_lexical_block ]
+!22 = !MDLocation(line: 7, column: 5, scope: !21)
+!23 = !MDLocation(line: 9, column: 7, scope: !21)
+!24 = !MDLocation(line: 14, column: 1, scope: !4)
diff --git a/test/Transforms/LoopVectorize/reverse_induction.ll b/test/Transforms/LoopVectorize/reverse_induction.ll
index da02d01..d379606 100644
--- a/test/Transforms/LoopVectorize/reverse_induction.ll
+++ b/test/Transforms/LoopVectorize/reverse_induction.ll
@@ -97,7 +97,7 @@ loopend:
; CHECK: vector.body
; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
; CHECK: %normalized.idx = sub i64 %index, 0
-; CHECK: %reverse.idx = sub i64 1023, %normalized.idx
+; CHECK: %offset.idx = sub i64 1023, %normalized.idx
; CHECK: trunc i64 %index to i8
define void @reverse_forward_induction_i64_i8() {
@@ -124,7 +124,7 @@ while.end:
; CHECK: vector.body:
; CHECK: %index = phi i64 [ 129, %vector.ph ], [ %index.next, %vector.body ]
; CHECK: %normalized.idx = sub i64 %index, 129
-; CHECK: %reverse.idx = sub i64 1023, %normalized.idx
+; CHECK: %offset.idx = sub i64 1023, %normalized.idx
; CHECK: trunc i64 %index to i8
define void @reverse_forward_induction_i64_i8_signed() {
diff --git a/test/Transforms/LoopVectorize/runtime-check-address-space.ll b/test/Transforms/LoopVectorize/runtime-check-address-space.ll
index 34bbe52..ec56f80 100644
--- a/test/Transforms/LoopVectorize/runtime-check-address-space.ll
+++ b/test/Transforms/LoopVectorize/runtime-check-address-space.ll
@@ -31,25 +31,23 @@ define void @foo(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
-
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %idxprom
%0 = load i32 addrspace(1)* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds i32 addrspace(1)* %a, i64 %idxprom1
store i32 %mul, i32 addrspace(1)* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
@@ -60,25 +58,23 @@ define void @bar0(i32* %a, i32 addrspace(1)* %b, i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
-
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %idxprom
%0 = load i32 addrspace(1)* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds i32* %a, i64 %idxprom1
store i32 %mul, i32* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
@@ -89,25 +85,23 @@ define void @bar1(i32 addrspace(1)* %a, i32* %b, i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
-
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32* %b, i64 %idxprom
%0 = load i32* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds i32 addrspace(1)* %a, i64 %idxprom1
store i32 %mul, i32 addrspace(1)* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
@@ -119,25 +113,23 @@ define void @bar2(i32* noalias %a, i32 addrspace(1)* noalias %b, i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
-
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %idxprom
%0 = load i32 addrspace(1)* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds i32* %a, i64 %idxprom1
store i32 %mul, i32* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
@@ -149,25 +141,23 @@ define void @arst0(i32* %b, i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
-
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds i32* %b, i64 %idxprom
%0 = load i32* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds [1024 x i32] addrspace(1)* @g_as1, i64 0, i64 %idxprom1
store i32 %mul, i32 addrspace(1)* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
@@ -180,25 +170,23 @@ define void @arst1(i32* %b, i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
-
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds [1024 x i32] addrspace(1)* @g_as1, i64 0, i64 %idxprom
%0 = load i32 addrspace(1)* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds i32* %b, i64 %idxprom1
store i32 %mul, i32* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
@@ -210,25 +198,23 @@ define void @aoeu(i32 %n) #0 {
; CHECK: ret
entry:
- br label %for.cond
+ %cmp1 = icmp slt i32 0, %n
+ br i1 %cmp1, label %for.body, label %for.end
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp slt i32 %i.0, %n
- br i1 %cmp, label %for.body, label %for.end
-
-for.body: ; preds = %for.cond
- %idxprom = sext i32 %i.0 to i64
+for.body: ; preds = %entry, %for.body
+ %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+ %idxprom = sext i32 %i.02 to i64
%arrayidx = getelementptr inbounds [1024 x i32] addrspace(2)* @q_as2, i64 0, i64 %idxprom
%0 = load i32 addrspace(2)* %arrayidx, align 4
%mul = mul nsw i32 %0, 3
- %idxprom1 = sext i32 %i.0 to i64
+ %idxprom1 = sext i32 %i.02 to i64
%arrayidx2 = getelementptr inbounds [1024 x i32] addrspace(1)* @g_as1, i64 0, i64 %idxprom1
store i32 %mul, i32 addrspace(1)* %arrayidx2, align 4
- %inc = add nsw i32 %i.0, 1
- br label %for.cond
+ %inc = add nsw i32 %i.02, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body, %entry
ret void
}
diff --git a/test/Transforms/LoopVectorize/runtime-check-readonly-address-space.ll b/test/Transforms/LoopVectorize/runtime-check-readonly-address-space.ll
index 56f1f99..12ba3ce 100644
--- a/test/Transforms/LoopVectorize/runtime-check-readonly-address-space.ll
+++ b/test/Transforms/LoopVectorize/runtime-check-readonly-address-space.ll
@@ -8,26 +8,24 @@ define void @add_ints_1_1_1(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addr
; CHECK-LABEL: @add_ints_1_1_1(
; CHECK: <4 x i32>
; CHECK: ret
-entry:
- br label %for.cond
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp ult i64 %i.0, 200
- br i1 %cmp, label %for.body, label %for.end
+entry:
+ br label %for.body
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.0
+for.body: ; preds = %entry, %for.body
+ %i.01 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.01
%0 = load i32 addrspace(1)* %arrayidx, align 4
- %arrayidx1 = getelementptr inbounds i32 addrspace(1)* %c, i64 %i.0
+ %arrayidx1 = getelementptr inbounds i32 addrspace(1)* %c, i64 %i.01
%1 = load i32 addrspace(1)* %arrayidx1, align 4
%add = add nsw i32 %0, %1
- %arrayidx2 = getelementptr inbounds i32 addrspace(1)* %a, i64 %i.0
+ %arrayidx2 = getelementptr inbounds i32 addrspace(1)* %a, i64 %i.01
store i32 %add, i32 addrspace(1)* %arrayidx2, align 4
- %inc = add i64 %i.0, 1
- br label %for.cond
+ %inc = add i64 %i.01, 1
+ %cmp = icmp ult i64 %inc, 200
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body
ret void
}
@@ -35,26 +33,24 @@ define void @add_ints_as_1_0_0(i32 addrspace(1)* %a, i32* %b, i32* %c) #0 {
; CHECK-LABEL: @add_ints_as_1_0_0(
; CHECK-NOT: <4 x i32>
; CHECK: ret
-entry:
- br label %for.cond
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp ult i64 %i.0, 200
- br i1 %cmp, label %for.body, label %for.end
+entry:
+ br label %for.body
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32* %b, i64 %i.0
+for.body: ; preds = %entry, %for.body
+ %i.01 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %arrayidx = getelementptr inbounds i32* %b, i64 %i.01
%0 = load i32* %arrayidx, align 4
- %arrayidx1 = getelementptr inbounds i32* %c, i64 %i.0
+ %arrayidx1 = getelementptr inbounds i32* %c, i64 %i.01
%1 = load i32* %arrayidx1, align 4
%add = add nsw i32 %0, %1
- %arrayidx2 = getelementptr inbounds i32 addrspace(1)* %a, i64 %i.0
+ %arrayidx2 = getelementptr inbounds i32 addrspace(1)* %a, i64 %i.01
store i32 %add, i32 addrspace(1)* %arrayidx2, align 4
- %inc = add i64 %i.0, 1
- br label %for.cond
+ %inc = add i64 %i.01, 1
+ %cmp = icmp ult i64 %inc, 200
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body
ret void
}
@@ -62,26 +58,24 @@ define void @add_ints_as_0_1_0(i32* %a, i32 addrspace(1)* %b, i32* %c) #0 {
; CHECK-LABEL: @add_ints_as_0_1_0(
; CHECK-NOT: <4 x i32>
; CHECK: ret
-entry:
- br label %for.cond
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp ult i64 %i.0, 200
- br i1 %cmp, label %for.body, label %for.end
+entry:
+ br label %for.body
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.0
+for.body: ; preds = %entry, %for.body
+ %i.01 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.01
%0 = load i32 addrspace(1)* %arrayidx, align 4
- %arrayidx1 = getelementptr inbounds i32* %c, i64 %i.0
+ %arrayidx1 = getelementptr inbounds i32* %c, i64 %i.01
%1 = load i32* %arrayidx1, align 4
%add = add nsw i32 %0, %1
- %arrayidx2 = getelementptr inbounds i32* %a, i64 %i.0
+ %arrayidx2 = getelementptr inbounds i32* %a, i64 %i.01
store i32 %add, i32* %arrayidx2, align 4
- %inc = add i64 %i.0, 1
- br label %for.cond
+ %inc = add i64 %i.01, 1
+ %cmp = icmp ult i64 %inc, 200
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body
ret void
}
@@ -89,26 +83,24 @@ define void @add_ints_as_0_1_1(i32* %a, i32 addrspace(1)* %b, i32 addrspace(1)*
; CHECK-LABEL: @add_ints_as_0_1_1(
; CHECK-NOT: <4 x i32>
; CHECK: ret
-entry:
- br label %for.cond
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp ult i64 %i.0, 200
- br i1 %cmp, label %for.body, label %for.end
+entry:
+ br label %for.body
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.0
+for.body: ; preds = %entry, %for.body
+ %i.01 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.01
%0 = load i32 addrspace(1)* %arrayidx, align 4
- %arrayidx1 = getelementptr inbounds i32 addrspace(1)* %c, i64 %i.0
+ %arrayidx1 = getelementptr inbounds i32 addrspace(1)* %c, i64 %i.01
%1 = load i32 addrspace(1)* %arrayidx1, align 4
%add = add nsw i32 %0, %1
- %arrayidx2 = getelementptr inbounds i32* %a, i64 %i.0
+ %arrayidx2 = getelementptr inbounds i32* %a, i64 %i.01
store i32 %add, i32* %arrayidx2, align 4
- %inc = add i64 %i.0, 1
- br label %for.cond
+ %inc = add i64 %i.01, 1
+ %cmp = icmp ult i64 %inc, 200
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body
ret void
}
@@ -116,26 +108,24 @@ define void @add_ints_as_0_1_2(i32* %a, i32 addrspace(1)* %b, i32 addrspace(2)*
; CHECK-LABEL: @add_ints_as_0_1_2(
; CHECK-NOT: <4 x i32>
; CHECK: ret
-entry:
- br label %for.cond
-for.cond: ; preds = %for.body, %entry
- %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
- %cmp = icmp ult i64 %i.0, 200
- br i1 %cmp, label %for.body, label %for.end
+entry:
+ br label %for.body
-for.body: ; preds = %for.cond
- %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.0
+for.body: ; preds = %entry, %for.body
+ %i.01 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %arrayidx = getelementptr inbounds i32 addrspace(1)* %b, i64 %i.01
%0 = load i32 addrspace(1)* %arrayidx, align 4
- %arrayidx1 = getelementptr inbounds i32 addrspace(2)* %c, i64 %i.0
+ %arrayidx1 = getelementptr inbounds i32 addrspace(2)* %c, i64 %i.01
%1 = load i32 addrspace(2)* %arrayidx1, align 4
%add = add nsw i32 %0, %1
- %arrayidx2 = getelementptr inbounds i32* %a, i64 %i.0
+ %arrayidx2 = getelementptr inbounds i32* %a, i64 %i.01
store i32 %add, i32* %arrayidx2, align 4
- %inc = add i64 %i.0, 1
- br label %for.cond
+ %inc = add i64 %i.01, 1
+ %cmp = icmp ult i64 %inc, 200
+ br i1 %cmp, label %for.body, label %for.end
-for.end: ; preds = %for.cond
+for.end: ; preds = %for.body
ret void
}
diff --git a/test/Transforms/LoopVectorize/scev-exitlim-crash.ll b/test/Transforms/LoopVectorize/scev-exitlim-crash.ll
index 1bce3f8..5154771 100644
--- a/test/Transforms/LoopVectorize/scev-exitlim-crash.ll
+++ b/test/Transforms/LoopVectorize/scev-exitlim-crash.ll
@@ -106,9 +106,9 @@ declare i32 @fn2(double) #1
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!0 = metadata !{metadata !"int", metadata !1}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA"}
-!3 = metadata !{metadata !"double", metadata !1}
-!4 = metadata !{metadata !0, metadata !0, i64 0}
-!5 = metadata !{metadata !3, metadata !3, i64 0}
+!0 = !{!"int", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"double", !1}
+!4 = !{!0, !0, i64 0}
+!5 = !{!3, !3, i64 0}
diff --git a/test/Transforms/LoopVectorize/tbaa-nodep.ll b/test/Transforms/LoopVectorize/tbaa-nodep.ll
index 5cd104c..be3e74f 100644
--- a/test/Transforms/LoopVectorize/tbaa-nodep.ll
+++ b/test/Transforms/LoopVectorize/tbaa-nodep.ll
@@ -93,10 +93,10 @@ for.end: ; preds = %for.body
attributes #0 = { nounwind uwtable }
-!0 = metadata !{metadata !1, metadata !1, i64 0}
-!1 = metadata !{metadata !"float", metadata !2, i64 0}
-!2 = metadata !{metadata !"omnipotent char", metadata !3, i64 0}
-!3 = metadata !{metadata !"Simple C/C++ TBAA"}
-!4 = metadata !{metadata !5, metadata !5, i64 0}
-!5 = metadata !{metadata !"int", metadata !2, i64 0}
+!0 = !{!1, !1, i64 0}
+!1 = !{!"float", !2, i64 0}
+!2 = !{!"omnipotent char", !3, i64 0}
+!3 = !{!"Simple C/C++ TBAA"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !2, i64 0}
diff --git a/test/Transforms/LoopVectorize/vect.omp.persistence.ll b/test/Transforms/LoopVectorize/vect.omp.persistence.ll
index b0fe7a5..ea7be9c 100644
--- a/test/Transforms/LoopVectorize/vect.omp.persistence.ll
+++ b/test/Transforms/LoopVectorize/vect.omp.persistence.ll
@@ -61,8 +61,8 @@ for.end:
ret void
}
-!1 = metadata !{metadata !1, metadata !2}
-!2 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+!1 = !{!1, !2}
+!2 = !{!"llvm.loop.vectorize.enable", i1 true}
;
; Test #2
@@ -84,5 +84,5 @@ return:
ret i32 0
}
-!3 = metadata !{metadata !3, metadata !4}
-!4 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+!3 = !{!3, !4}
+!4 = !{!"llvm.loop.vectorize.enable", i1 true}
diff --git a/test/Transforms/LoopVectorize/vect.stats.ll b/test/Transforms/LoopVectorize/vect.stats.ll
index 556da45..c5b6e64 100644
--- a/test/Transforms/LoopVectorize/vect.stats.ll
+++ b/test/Transforms/LoopVectorize/vect.stats.ll
@@ -13,53 +13,47 @@ target triple = "x86_64-unknown-linux-gnu"
define void @vectorized(float* nocapture %a, i64 %size) {
entry:
- %cmp1 = icmp sgt i64 %size, 0
- br i1 %cmp1, label %for.header, label %for.end
-
-for.header:
- %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
- %cmp2 = icmp sgt i64 %indvars.iv, %size
- br i1 %cmp2, label %for.end, label %for.body
-
-for.body:
-
- %arrayidx = getelementptr inbounds float* %a, i64 %indvars.iv
+ %cmp1 = icmp sle i64 %size, 0
+ %cmp21 = icmp sgt i64 0, %size
+ %or.cond = or i1 %cmp1, %cmp21
+ br i1 %or.cond, label %for.end, label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %indvars.iv2 = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
+ %arrayidx = getelementptr inbounds float* %a, i64 %indvars.iv2
%0 = load float* %arrayidx, align 4
%mul = fmul float %0, %0
store float %mul, float* %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv2, 1
+ %cmp2 = icmp sgt i64 %indvars.iv.next, %size
+ br i1 %cmp2, label %for.end, label %for.body
- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
- br label %for.header
-
-for.end:
+for.end: ; preds = %entry, %for.body
ret void
}
define void @not_vectorized(float* nocapture %a, i64 %size) {
entry:
- %cmp1 = icmp sgt i64 %size, 0
- br i1 %cmp1, label %for.header, label %for.end
-
-for.header:
- %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
- %cmp2 = icmp sgt i64 %indvars.iv, %size
- br i1 %cmp2, label %for.end, label %for.body
-
-for.body:
-
- %0 = add nsw i64 %indvars.iv, -5
+ %cmp1 = icmp sle i64 %size, 0
+ %cmp21 = icmp sgt i64 0, %size
+ %or.cond = or i1 %cmp1, %cmp21
+ br i1 %or.cond, label %for.end, label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %indvars.iv2 = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
+ %0 = add nsw i64 %indvars.iv2, -5
%arrayidx = getelementptr inbounds float* %a, i64 %0
%1 = load float* %arrayidx, align 4
- %2 = add nsw i64 %indvars.iv, 2
+ %2 = add nsw i64 %indvars.iv2, 2
%arrayidx2 = getelementptr inbounds float* %a, i64 %2
%3 = load float* %arrayidx2, align 4
%mul = fmul float %1, %3
- %arrayidx4 = getelementptr inbounds float* %a, i64 %indvars.iv
+ %arrayidx4 = getelementptr inbounds float* %a, i64 %indvars.iv2
store float %mul, float* %arrayidx4, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv2, 1
+ %cmp2 = icmp sgt i64 %indvars.iv.next, %size
+ br i1 %cmp2, label %for.end, label %for.body
- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
- br label %for.header
-
-for.end:
+for.end: ; preds = %entry, %for.body
ret void
}
diff --git a/test/Transforms/LoopVectorize/vectorize-once.ll b/test/Transforms/LoopVectorize/vectorize-once.ll
index cee4b16..a9b2a53 100644
--- a/test/Transforms/LoopVectorize/vectorize-once.ll
+++ b/test/Transforms/LoopVectorize/vectorize-once.ll
@@ -68,10 +68,10 @@ _ZSt10accumulateIPiiET0_T_S2_S1_.exit: ; preds = %for.body.i, %entry
attributes #0 = { nounwind readonly ssp uwtable "fp-contract-model"="standard" "no-frame-pointer-elim" "no-frame-pointer-elim-non-leaf" "realign-stack" "relocation-model"="pic" "ssp-buffers-size"="8" }
-; CHECK: !0 = metadata !{metadata !0, metadata !1, metadata !2}
-; CHECK: !1 = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
-; CHECK: !2 = metadata !{metadata !"llvm.loop.interleave.count", i32 1}
-; CHECK: !3 = metadata !{metadata !3, metadata !1, metadata !2}
+; CHECK: !0 = distinct !{!0, !1, !2}
+; CHECK: !1 = !{!"llvm.loop.vectorize.width", i32 1}
+; CHECK: !2 = !{!"llvm.loop.interleave.count", i32 1}
+; CHECK: !3 = distinct !{!3, !1, !2}
-!0 = metadata !{metadata !0, metadata !1}
-!1 = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
+!0 = !{!0, !1}
+!1 = !{!"llvm.loop.vectorize.width", i32 1}
diff --git a/test/Transforms/LoopVectorize/version-mem-access.ll b/test/Transforms/LoopVectorize/version-mem-access.ll
index 7ac2fca..37145aa 100644
--- a/test/Transforms/LoopVectorize/version-mem-access.ll
+++ b/test/Transforms/LoopVectorize/version-mem-access.ll
@@ -2,10 +2,16 @@
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+; Check that we version this loop with speculating the value 1 for symbolic
+; strides. This also checks that the symbolic stride information is correctly
+; propagated to the memcheck generation. Without this the loop wouldn't
+; vectorize because we couldn't determine the array bounds for the required
+; memchecks.
+
; CHECK-LABEL: test
-define void @test(i32* noalias %A, i64 %AStride,
- i32* noalias %B, i32 %BStride,
- i32* noalias %C, i64 %CStride, i32 %N) {
+define void @test(i32* %A, i64 %AStride,
+ i32* %B, i32 %BStride,
+ i32* %C, i64 %CStride, i32 %N) {
entry:
%cmp13 = icmp eq i32 %N, 0
br i1 %cmp13, label %for.end, label %for.body.preheader
diff --git a/test/Transforms/LowerBitSets/constant.ll b/test/Transforms/LowerBitSets/constant.ll
new file mode 100644
index 0000000..230c57c
--- /dev/null
+++ b/test/Transforms/LowerBitSets/constant.ll
@@ -0,0 +1,34 @@
+; RUN: opt -S -lowerbitsets < %s | FileCheck %s
+
+target datalayout = "e-p:32:32"
+
+@a = constant i32 1
+@b = constant [2 x i32] [i32 2, i32 3]
+
+!0 = !{!"bitset1", i32* @a, i32 0}
+!1 = !{!"bitset1", [2 x i32]* @b, i32 4}
+
+!llvm.bitsets = !{ !0, !1 }
+
+declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+; CHECK: @foo(
+define i1 @foo() {
+ ; CHECK: ret i1 true
+ %x = call i1 @llvm.bitset.test(i8* bitcast (i32* @a to i8*), metadata !"bitset1")
+ ret i1 %x
+}
+
+; CHECK: @bar(
+define i1 @bar() {
+ ; CHECK: ret i1 true
+ %x = call i1 @llvm.bitset.test(i8* bitcast (i32* getelementptr ([2 x i32]* @b, i32 0, i32 1) to i8*), metadata !"bitset1")
+ ret i1 %x
+}
+
+; CHECK: @baz(
+define i1 @baz() {
+ ; CHECK-NOT: ret i1 true
+ %x = call i1 @llvm.bitset.test(i8* bitcast (i32* getelementptr ([2 x i32]* @b, i32 0, i32 0) to i8*), metadata !"bitset1")
+ ret i1 %x
+}
diff --git a/test/Transforms/LowerBitSets/layout.ll b/test/Transforms/LowerBitSets/layout.ll
new file mode 100644
index 0000000..a0c6e77
--- /dev/null
+++ b/test/Transforms/LowerBitSets/layout.ll
@@ -0,0 +1,35 @@
+; RUN: opt -S -lowerbitsets < %s | FileCheck %s
+
+target datalayout = "e-p:32:32"
+
+; Tests that this set of globals is laid out according to our layout algorithm
+; (see GlobalLayoutBuilder in include/llvm/Transforms/IPO/LowerBitSets.h).
+; The chosen layout in this case is a, e, b, d, c.
+
+; CHECK: private constant { i32, [0 x i8], i32, [0 x i8], i32, [0 x i8], i32, [0 x i8], i32 } { i32 1, [0 x i8] zeroinitializer, i32 5, [0 x i8] zeroinitializer, i32 2, [0 x i8] zeroinitializer, i32 4, [0 x i8] zeroinitializer, i32 3 }
+@a = constant i32 1
+@b = constant i32 2
+@c = constant i32 3
+@d = constant i32 4
+@e = constant i32 5
+
+!0 = !{!"bitset1", i32* @a, i32 0}
+!1 = !{!"bitset1", i32* @b, i32 0}
+!2 = !{!"bitset1", i32* @c, i32 0}
+
+!3 = !{!"bitset2", i32* @b, i32 0}
+!4 = !{!"bitset2", i32* @d, i32 0}
+
+!5 = !{!"bitset3", i32* @a, i32 0}
+!6 = !{!"bitset3", i32* @e, i32 0}
+
+!llvm.bitsets = !{ !0, !1, !2, !3, !4, !5, !6 }
+
+declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+define void @foo() {
+ %x = call i1 @llvm.bitset.test(i8* undef, metadata !"bitset1")
+ %y = call i1 @llvm.bitset.test(i8* undef, metadata !"bitset2")
+ %z = call i1 @llvm.bitset.test(i8* undef, metadata !"bitset3")
+ ret void
+}
diff --git a/test/Transforms/LowerBitSets/simple.ll b/test/Transforms/LowerBitSets/simple.ll
new file mode 100644
index 0000000..0928524
--- /dev/null
+++ b/test/Transforms/LowerBitSets/simple.ll
@@ -0,0 +1,122 @@
+; RUN: opt -S -lowerbitsets < %s | FileCheck %s
+; RUN: opt -S -O3 < %s | FileCheck -check-prefix=CHECK-NODISCARD %s
+
+target datalayout = "e-p:32:32"
+
+; CHECK: [[G:@[^ ]*]] = private constant { i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] } { i32 1, [0 x i8] zeroinitializer, [63 x i32] zeroinitializer, [4 x i8] zeroinitializer, i32 3, [0 x i8] zeroinitializer, [2 x i32] [i32 4, i32 5] }
+@a = constant i32 1
+@b = constant [63 x i32] zeroinitializer
+@c = constant i32 3
+@d = constant [2 x i32] [i32 4, i32 5]
+
+; Offset 0, 4 byte alignment
+; CHECK: @bitset1.bits = private constant [9 x i8] c"\03\00\00\00\00\00\00\00\08"
+!0 = !{!"bitset1", i32* @a, i32 0}
+; CHECK-NODISCARD-DAG: !{!"bitset1", i32* @a, i32 0}
+!1 = !{!"bitset1", [63 x i32]* @b, i32 0}
+; CHECK-NODISCARD-DAG: !{!"bitset1", [63 x i32]* @b, i32 0}
+!2 = !{!"bitset1", [2 x i32]* @d, i32 4}
+; CHECK-NODISCARD-DAG: !{!"bitset1", [2 x i32]* @d, i32 4}
+
+; Offset 4, 256 byte alignment
+; CHECK: @bitset2.bits = private constant [1 x i8] c"\03"
+!3 = !{!"bitset2", [63 x i32]* @b, i32 0}
+; CHECK-NODISCARD-DAG: !{!"bitset2", [63 x i32]* @b, i32 0}
+!4 = !{!"bitset2", i32* @c, i32 0}
+; CHECK-NODISCARD-DAG: !{!"bitset2", i32* @c, i32 0}
+
+; Offset 0, 4 byte alignment
+; CHECK: @bitset3.bits = private constant [9 x i8] c"\01\00\00\00\00\00\00\00\02"
+!5 = !{!"bitset3", i32* @a, i32 0}
+; CHECK-NODISCARD-DAG: !{!"bitset3", i32* @a, i32 0}
+!6 = !{!"bitset3", i32* @c, i32 0}
+; CHECK-NODISCARD-DAG: !{!"bitset3", i32* @c, i32 0}
+
+; Entries whose second operand is null (the result of a global being DCE'd)
+; should be ignored.
+!7 = !{!"bitset2", null, i32 0}
+
+!llvm.bitsets = !{ !0, !1, !2, !3, !4, !5, !6, !7 }
+
+; CHECK: @a = alias getelementptr inbounds ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]], i32 0, i32 0)
+; CHECK: @b = alias getelementptr inbounds ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]], i32 0, i32 2)
+; CHECK: @c = alias getelementptr inbounds ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]], i32 0, i32 4)
+; CHECK: @d = alias getelementptr inbounds ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]], i32 0, i32 6)
+
+declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+; CHECK: @foo(i32* [[A0:%[^ ]*]])
+define i1 @foo(i32* %p) {
+ ; CHECK-NOT: llvm.bitset.test
+
+ ; CHECK: [[R0:%[^ ]*]] = bitcast i32* [[A0]] to i8*
+ %pi8 = bitcast i32* %p to i8*
+ ; CHECK: [[R1:%[^ ]*]] = ptrtoint i8* [[R0]] to i32
+ ; CHECK: [[R2:%[^ ]*]] = sub i32 [[R1]], ptrtoint ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]] to i32)
+ ; CHECK: [[R3:%[^ ]*]] = lshr i32 [[R2]], 2
+ ; CHECK: [[R4:%[^ ]*]] = shl i32 [[R2]], 30
+ ; CHECK: [[R5:%[^ ]*]] = or i32 [[R3]], [[R4]]
+ ; CHECK: [[R6:%[^ ]*]] = icmp ult i32 [[R5]], 68
+ ; CHECK: br i1 [[R6]]
+
+ ; CHECK: [[R8:%[^ ]*]] = lshr i32 [[R5]], 5
+ ; CHECK: [[R9:%[^ ]*]] = getelementptr i32* bitcast ([9 x i8]* @bitset1.bits to i32*), i32 [[R8]]
+ ; CHECK: [[R10:%[^ ]*]] = load i32* [[R9]]
+ ; CHECK: [[R11:%[^ ]*]] = and i32 [[R5]], 31
+ ; CHECK: [[R12:%[^ ]*]] = shl i32 1, [[R11]]
+ ; CHECK: [[R13:%[^ ]*]] = and i32 [[R10]], [[R12]]
+ ; CHECK: [[R14:%[^ ]*]] = icmp ne i32 [[R13]], 0
+
+ ; CHECK: [[R16:%[^ ]*]] = phi i1 [ false, {{%[^ ]*}} ], [ [[R14]], {{%[^ ]*}} ]
+ %x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset1")
+
+ ; CHECK-NOT: llvm.bitset.test
+ %y = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset1")
+
+ ; CHECK: ret i1 [[R16]]
+ ret i1 %x
+}
+
+; CHECK: @bar(i32* [[B0:%[^ ]*]])
+define i1 @bar(i32* %p) {
+ ; CHECK: [[S0:%[^ ]*]] = bitcast i32* [[B0]] to i8*
+ %pi8 = bitcast i32* %p to i8*
+ ; CHECK: [[S1:%[^ ]*]] = ptrtoint i8* [[S0]] to i32
+ ; CHECK: [[S2:%[^ ]*]] = sub i32 [[S1]], add (i32 ptrtoint ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]] to i32), i32 4)
+ ; CHECK: [[S3:%[^ ]*]] = lshr i32 [[S2]], 8
+ ; CHECK: [[S4:%[^ ]*]] = shl i32 [[S2]], 24
+ ; CHECK: [[S5:%[^ ]*]] = or i32 [[S3]], [[S4]]
+ ; CHECK: [[S6:%[^ ]*]] = icmp ult i32 [[S5]], 2
+ %x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset2")
+
+ ; CHECK: ret i1 [[S6]]
+ ret i1 %x
+}
+
+; CHECK: @baz(i32* [[C0:%[^ ]*]])
+define i1 @baz(i32* %p) {
+ ; CHECK: [[T0:%[^ ]*]] = bitcast i32* [[C0]] to i8*
+ %pi8 = bitcast i32* %p to i8*
+ ; CHECK: [[T1:%[^ ]*]] = ptrtoint i8* [[T0]] to i32
+ ; CHECK: [[T2:%[^ ]*]] = sub i32 [[T1]], ptrtoint ({ i32, [0 x i8], [63 x i32], [4 x i8], i32, [0 x i8], [2 x i32] }* [[G]] to i32)
+ ; CHECK: [[T3:%[^ ]*]] = lshr i32 [[T2]], 2
+ ; CHECK: [[T4:%[^ ]*]] = shl i32 [[T2]], 30
+ ; CHECK: [[T5:%[^ ]*]] = or i32 [[T3]], [[T4]]
+ ; CHECK: [[T6:%[^ ]*]] = icmp ult i32 [[T5]], 66
+ ; CHECK: br i1 [[T6]]
+
+ ; CHECK: [[T8:%[^ ]*]] = lshr i32 [[T5]], 5
+ ; CHECK: [[T9:%[^ ]*]] = getelementptr i32* bitcast ([9 x i8]* @bitset3.bits to i32*), i32 [[T8]]
+ ; CHECK: [[T10:%[^ ]*]] = load i32* [[T9]]
+ ; CHECK: [[T11:%[^ ]*]] = and i32 [[T5]], 31
+ ; CHECK: [[T12:%[^ ]*]] = shl i32 1, [[T11]]
+ ; CHECK: [[T13:%[^ ]*]] = and i32 [[T10]], [[T12]]
+ ; CHECK: [[T14:%[^ ]*]] = icmp ne i32 [[T13]], 0
+
+ ; CHECK: [[T16:%[^ ]*]] = phi i1 [ false, {{%[^ ]*}} ], [ [[T14]], {{%[^ ]*}} ]
+ %x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset3")
+ ; CHECK: ret i1 [[T16]]
+ ret i1 %x
+}
+
+; CHECK-NOT: !llvm.bitsets
diff --git a/test/Transforms/LowerBitSets/single-offset.ll b/test/Transforms/LowerBitSets/single-offset.ll
new file mode 100644
index 0000000..57194f4
--- /dev/null
+++ b/test/Transforms/LowerBitSets/single-offset.ll
@@ -0,0 +1,40 @@
+; RUN: opt -S -lowerbitsets < %s | FileCheck %s
+
+target datalayout = "e-p:32:32"
+
+; CHECK: [[G:@[^ ]*]] = private constant { i32, [0 x i8], i32 }
+@a = constant i32 1
+@b = constant i32 2
+
+!0 = !{!"bitset1", i32* @a, i32 0}
+!1 = !{!"bitset1", i32* @b, i32 0}
+!2 = !{!"bitset2", i32* @a, i32 0}
+!3 = !{!"bitset3", i32* @b, i32 0}
+
+!llvm.bitsets = !{ !0, !1, !2, !3 }
+
+declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+; CHECK: @foo(i8* [[A0:%[^ ]*]])
+define i1 @foo(i8* %p) {
+ ; CHECK: [[R0:%[^ ]*]] = ptrtoint i8* [[A0]] to i32
+ ; CHECK: [[R1:%[^ ]*]] = icmp eq i32 [[R0]], ptrtoint ({ i32, [0 x i8], i32 }* [[G]] to i32)
+ %x = call i1 @llvm.bitset.test(i8* %p, metadata !"bitset2")
+ ; CHECK: ret i1 [[R1]]
+ ret i1 %x
+}
+
+; CHECK: @bar(i8* [[B0:%[^ ]*]])
+define i1 @bar(i8* %p) {
+ ; CHECK: [[S0:%[^ ]*]] = ptrtoint i8* [[B0]] to i32
+ ; CHECK: [[S1:%[^ ]*]] = icmp eq i32 [[S0]], add (i32 ptrtoint ({ i32, [0 x i8], i32 }* [[G]] to i32), i32 4)
+ %x = call i1 @llvm.bitset.test(i8* %p, metadata !"bitset3")
+ ; CHECK: ret i1 [[S1]]
+ ret i1 %x
+}
+
+; CHECK: @x(
+define i1 @x(i8* %p) {
+ %x = call i1 @llvm.bitset.test(i8* %p, metadata !"bitset1")
+ ret i1 %x
+}
diff --git a/test/Transforms/LowerExpectIntrinsic/basic.ll b/test/Transforms/LowerExpectIntrinsic/basic.ll
index e184cb0..f4326c8 100644
--- a/test/Transforms/LowerExpectIntrinsic/basic.ll
+++ b/test/Transforms/LowerExpectIntrinsic/basic.ll
@@ -1,4 +1,5 @@
; RUN: opt -lower-expect -strip-dead-prototypes -S -o - < %s | FileCheck %s
+; RUN: opt -S -passes=lower-expect < %s | opt -strip-dead-prototypes -S | FileCheck %s
; CHECK-LABEL: @test1(
define i32 @test1(i32 %x) nounwind uwtable ssp {
@@ -274,7 +275,7 @@ return: ; preds = %if.end, %if.then
declare i1 @llvm.expect.i1(i1, i1) nounwind readnone
-; CHECK: !0 = metadata !{metadata !"branch_weights", i32 64, i32 4}
-; CHECK: !1 = metadata !{metadata !"branch_weights", i32 4, i32 64}
-; CHECK: !2 = metadata !{metadata !"branch_weights", i32 4, i32 64, i32 4}
-; CHECK: !3 = metadata !{metadata !"branch_weights", i32 64, i32 4, i32 4}
+; CHECK: !0 = !{!"branch_weights", i32 64, i32 4}
+; CHECK: !1 = !{!"branch_weights", i32 4, i32 64}
+; CHECK: !2 = !{!"branch_weights", i32 4, i32 64, i32 4}
+; CHECK: !3 = !{!"branch_weights", i32 64, i32 4, i32 4}
diff --git a/test/Transforms/LowerSwitch/2014-06-11-SwitchDefaultUnreachableOpt.ll b/test/Transforms/LowerSwitch/2014-06-11-SwitchDefaultUnreachableOpt.ll
index 0f73721..ecdd767 100644
--- a/test/Transforms/LowerSwitch/2014-06-11-SwitchDefaultUnreachableOpt.ll
+++ b/test/Transforms/LowerSwitch/2014-06-11-SwitchDefaultUnreachableOpt.ll
@@ -1,5 +1,8 @@
; RUN: opt < %s -lowerswitch -S | FileCheck %s
-; CHECK-NOT: {{.*}}icmp eq{{.*}}
+;
+; The switch is lowered with a single icmp.
+; CHECK: icmp
+; CHECK-NOT: icmp
;
;int foo(int a) {
;
@@ -14,7 +17,7 @@
;
;}
-define i32 @foo(i32 %a) nounwind ssp uwtable {
+define i32 @foo(i32 %a) {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 %a, i32* %2, align 4
diff --git a/test/Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll b/test/Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll
new file mode 100644
index 0000000..54929c5
--- /dev/null
+++ b/test/Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll
@@ -0,0 +1,110 @@
+; RUN: opt %s -lowerswitch -S | FileCheck %s
+
+define void @foo(i32 %x, i32* %p) {
+; Cases 2 and 4 are removed and become the new default case.
+; It is now enough to use two icmps to lower the switch.
+;
+; CHECK-LABEL: @foo
+; CHECK: icmp slt i32 %x, 5
+; CHECK: icmp eq i32 %x, 1
+; CHECK-NOT: icmp
+;
+entry:
+ switch i32 %x, label %default [
+ i32 1, label %bb0
+ i32 2, label %popular
+ i32 4, label %popular
+ i32 5, label %bb1
+ ]
+bb0:
+ store i32 0, i32* %p
+ br label %exit
+bb1:
+ store i32 1, i32* %p
+ br label %exit
+popular:
+ store i32 2, i32* %p
+ br label %exit
+exit:
+ ret void
+default:
+ unreachable
+}
+
+define void @unreachable_gap(i64 %x, i32* %p) {
+; Cases 6 and INT64_MAX become the new default, but we still exploit the fact
+; that 3-4 is unreachable, so four icmps is enough.
+
+; CHECK-LABEL: @unreachable_gap
+; CHECK: icmp slt i64 %x, 2
+; CHECK: icmp slt i64 %x, 5
+; CHECK: icmp eq i64 %x, 5
+; CHECK: icmp slt i64 %x, 1
+; CHECK-NOT: icmp
+
+entry:
+ switch i64 %x, label %default [
+ i64 -9223372036854775808, label %bb0
+ i64 1, label %bb1
+ i64 2, label %bb2
+ i64 5, label %bb3
+ i64 6, label %bb4
+ i64 9223372036854775807, label %bb4
+ ]
+bb0:
+ store i32 0, i32* %p
+ br label %exit
+bb1:
+ store i32 1, i32* %p
+ br label %exit
+bb2:
+ store i32 2, i32* %p
+ br label %exit
+bb3:
+ store i32 3, i32* %p
+ br label %exit
+bb4:
+ store i32 4, i32* %p
+ br label %exit
+exit:
+ ret void
+default:
+ unreachable
+}
+
+
+
+define void @nocases(i32 %x, i32* %p) {
+; Don't fall over when there are no cases.
+;
+; CHECK-LABEL: @nocases
+; CHECK-LABEL: entry
+; CHECK-NEXT: br label %default
+;
+entry:
+ switch i32 %x, label %default [
+ ]
+default:
+ unreachable
+}
+
+define void @nocasesleft(i32 %x, i32* %p) {
+; Cases 2 and 4 are removed and we are left with no cases.
+;
+; CHECK-LABEL: @nocasesleft
+; CHECK-LABEL: entry
+; CHECK-NEXT: br label %popular
+;
+entry:
+ switch i32 %x, label %default [
+ i32 2, label %popular
+ i32 4, label %popular
+ ]
+popular:
+ store i32 2, i32* %p
+ br label %exit
+exit:
+ ret void
+default:
+ unreachable
+}
diff --git a/test/Transforms/Mem2Reg/ConvertDebugInfo.ll b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
index b2d094f..a7369c0 100644
--- a/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
+++ b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
@@ -7,13 +7,13 @@ entry:
%retval = alloca double ; <double*> [#uses=2]
%0 = alloca double ; <double*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.declare(metadata !{i32* %i_addr}, metadata !0, metadata !{}), !dbg !8
-; CHECK: call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata ![[IVAR:[0-9]*]], metadata {{.*}})
-; CHECK: call void @llvm.dbg.value(metadata !{double %j}, i64 0, metadata ![[JVAR:[0-9]*]], metadata {{.*}})
+ call void @llvm.dbg.declare(metadata i32* %i_addr, metadata !0, metadata !{}), !dbg !8
+; CHECK: call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata ![[IVAR:[0-9]*]], metadata {{.*}})
+; CHECK: call void @llvm.dbg.value(metadata double %j, i64 0, metadata ![[JVAR:[0-9]*]], metadata {{.*}})
; CHECK: ![[IVAR]] = {{.*}} ; [ DW_TAG_arg_variable ] [i]
; CHECK: ![[JVAR]] = {{.*}} ; [ DW_TAG_arg_variable ] [j]
store i32 %i, i32* %i_addr
- call void @llvm.dbg.declare(metadata !{double* %j_addr}, metadata !9, metadata !{}), !dbg !8
+ call void @llvm.dbg.declare(metadata double* %j_addr, metadata !9, metadata !{}), !dbg !8
store double %j, double* %j_addr
%1 = load i32* %i_addr, align 4, !dbg !10 ; <i32> [#uses=1]
%2 = add nsw i32 %1, 1, !dbg !10 ; <i32> [#uses=1]
@@ -35,18 +35,18 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
!llvm.dbg.cu = !{!3}
!llvm.module.flags = !{!14}
-!0 = metadata !{metadata !"0x101\00i\002\000", metadata !1, metadata !2, metadata !7} ; [ DW_TAG_arg_variable ]
-!1 = metadata !{metadata !"0x2e\00testfunc\00testfunc\00testfunc\002\000\001\000\006\000\000\002", metadata !12, metadata !2, metadata !4, null, double (i32, double)* @testfunc, null, null, null} ; [ DW_TAG_subprogram ]
-!2 = metadata !{metadata !"0x29", metadata !12} ; [ DW_TAG_file_type ]
-!3 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", metadata !12, metadata !13, metadata !13, null, null, null} ; [ DW_TAG_compile_unit ]
-!4 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !12, metadata !2, null, metadata !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!5 = metadata !{metadata !6, metadata !7, metadata !6}
-!6 = metadata !{metadata !"0x24\00double\000\0064\0064\000\000\004", metadata !12, metadata !2} ; [ DW_TAG_base_type ]
-!7 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", metadata !12, metadata !2} ; [ DW_TAG_base_type ]
-!8 = metadata !{i32 2, i32 0, metadata !1, null}
-!9 = metadata !{metadata !"0x101\00j\002\000", metadata !1, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ]
-!10 = metadata !{i32 3, i32 0, metadata !11, null}
-!11 = metadata !{metadata !"0xb\002\000\000", metadata !12, metadata !1} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{metadata !"testfunc.c", metadata !"/tmp"}
-!13 = metadata !{i32 0}
-!14 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x101\00i\002\000", !1, !2, !7} ; [ DW_TAG_arg_variable ]
+!1 = !{!"0x2e\00testfunc\00testfunc\00testfunc\002\000\001\000\006\000\000\002", !12, !2, !4, null, double (i32, double)* @testfunc, null, null, null} ; [ DW_TAG_subprogram ]
+!2 = !{!"0x29", !12} ; [ DW_TAG_file_type ]
+!3 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", !12, !13, !13, null, null, null} ; [ DW_TAG_compile_unit ]
+!4 = !{!"0x15\00\000\000\000\000\000\000", !12, !2, null, !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!5 = !{!6, !7, !6}
+!6 = !{!"0x24\00double\000\0064\0064\000\000\004", !12, !2} ; [ DW_TAG_base_type ]
+!7 = !{!"0x24\00int\000\0032\0032\000\000\005", !12, !2} ; [ DW_TAG_base_type ]
+!8 = !MDLocation(line: 2, scope: !1)
+!9 = !{!"0x101\00j\002\000", !1, !2, !6} ; [ DW_TAG_arg_variable ]
+!10 = !MDLocation(line: 3, scope: !11)
+!11 = !{!"0xb\002\000\000", !12, !1} ; [ DW_TAG_lexical_block ]
+!12 = !{!"testfunc.c", !"/tmp"}
+!13 = !{i32 0}
+!14 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll b/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll
index b7b9dc7..76d2a1a 100644
--- a/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll
+++ b/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll
@@ -11,14 +11,14 @@ entry:
%z_addr.i = alloca i8* ; <i8**> [#uses=2]
%a_addr = alloca i32 ; <i32*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.declare(metadata !{i32* %a_addr}, metadata !0, metadata !{}), !dbg !7
+ call void @llvm.dbg.declare(metadata i32* %a_addr, metadata !0, metadata !{}), !dbg !7
store i32 %a, i32* %a_addr
%0 = load i32* %a_addr, align 4, !dbg !8 ; <i32> [#uses=1]
- call void @llvm.dbg.declare(metadata !{i32* %x_addr.i}, metadata !9, metadata !{}) nounwind, !dbg !15
+ call void @llvm.dbg.declare(metadata i32* %x_addr.i, metadata !9, metadata !{}) nounwind, !dbg !15
store i32 %0, i32* %x_addr.i
- call void @llvm.dbg.declare(metadata !{i64* %y_addr.i}, metadata !16, metadata !{}) nounwind, !dbg !15
+ call void @llvm.dbg.declare(metadata i64* %y_addr.i, metadata !16, metadata !{}) nounwind, !dbg !15
store i64 55, i64* %y_addr.i
- call void @llvm.dbg.declare(metadata !{i8** %z_addr.i}, metadata !17, metadata !{}) nounwind, !dbg !15
+ call void @llvm.dbg.declare(metadata i8** %z_addr.i, metadata !17, metadata !{}) nounwind, !dbg !15
store i8* bitcast (void (i32)* @baz to i8*), i8** %z_addr.i
%1 = load i32* %x_addr.i, align 4, !dbg !18 ; <i32> [#uses=1]
%2 = load i64* %y_addr.i, align 8, !dbg !18 ; <i64> [#uses=1]
@@ -32,26 +32,26 @@ return: ; preds = %entry
!llvm.dbg.cu = !{!3}
!llvm.module.flags = !{!22}
-!0 = metadata !{metadata !"0x101\00a\008\000", metadata !1, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ]
-!1 = metadata !{metadata !"0x2e\00baz\00baz\00baz\008\000\001\000\006\000\000\008", metadata !20, metadata !2, metadata !4, null, void (i32)* @baz, null, null, null} ; [ DW_TAG_subprogram ]
-!2 = metadata !{metadata !"0x29", metadata !20} ; [ DW_TAG_file_type ]
-!3 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", metadata !20, metadata !21, metadata !21, null, null, null} ; [ DW_TAG_compile_unit ]
-!4 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !20, metadata !2, null, metadata !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!5 = metadata !{null, metadata !6}
-!6 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", metadata !20, metadata !2} ; [ DW_TAG_base_type ]
-!7 = metadata !{i32 8, i32 0, metadata !1, null}
-!8 = metadata !{i32 9, i32 0, metadata !1, null}
-!9 = metadata !{metadata !"0x101\00x\004\000", metadata !10, metadata !2, metadata !6} ; [ DW_TAG_arg_variable ]
-!10 = metadata !{metadata !"0x2e\00bar\00bar\00bar\004\001\001\000\006\000\000\004", metadata !20, metadata !2, metadata !11, null, null, null, null, null} ; [ DW_TAG_subprogram ]
-!11 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !20, metadata !2, null, metadata !12, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!12 = metadata !{null, metadata !6, metadata !13, metadata !14}
-!13 = metadata !{metadata !"0x24\00long int\000\0064\0064\000\000\005", metadata !20, metadata !2} ; [ DW_TAG_base_type ]
-!14 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", metadata !20, metadata !2, null} ; [ DW_TAG_pointer_type ]
-!15 = metadata !{i32 4, i32 0, metadata !10, metadata !8}
-!16 = metadata !{metadata !"0x101\00y\004\000", metadata !10, metadata !2, metadata !13} ; [ DW_TAG_arg_variable ]
-!17 = metadata !{metadata !"0x101\00z\004\000", metadata !10, metadata !2, metadata !14} ; [ DW_TAG_arg_variable ]
-!18 = metadata !{i32 5, i32 0, metadata !10, metadata !8}
-!19 = metadata !{i32 10, i32 0, metadata !1, null}
-!20 = metadata !{metadata !"bar.c", metadata !"/tmp/"}
-!21 = metadata !{i32 0}
-!22 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x101\00a\008\000", !1, !2, !6} ; [ DW_TAG_arg_variable ]
+!1 = !{!"0x2e\00baz\00baz\00baz\008\000\001\000\006\000\000\008", !20, !2, !4, null, void (i32)* @baz, null, null, null} ; [ DW_TAG_subprogram ]
+!2 = !{!"0x29", !20} ; [ DW_TAG_file_type ]
+!3 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", !20, !21, !21, null, null, null} ; [ DW_TAG_compile_unit ]
+!4 = !{!"0x15\00\000\000\000\000\000\000", !20, !2, null, !5, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!5 = !{null, !6}
+!6 = !{!"0x24\00int\000\0032\0032\000\000\005", !20, !2} ; [ DW_TAG_base_type ]
+!7 = !MDLocation(line: 8, scope: !1)
+!8 = !MDLocation(line: 9, scope: !1)
+!9 = !{!"0x101\00x\004\000", !10, !2, !6} ; [ DW_TAG_arg_variable ]
+!10 = !{!"0x2e\00bar\00bar\00bar\004\001\001\000\006\000\000\004", !20, !2, !11, null, null, null, null, null} ; [ DW_TAG_subprogram ]
+!11 = !{!"0x15\00\000\000\000\000\000\000", !20, !2, null, !12, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!12 = !{null, !6, !13, !14}
+!13 = !{!"0x24\00long int\000\0064\0064\000\000\005", !20, !2} ; [ DW_TAG_base_type ]
+!14 = !{!"0xf\00\000\0064\0064\000\000", !20, !2, null} ; [ DW_TAG_pointer_type ]
+!15 = !MDLocation(line: 4, scope: !10, inlinedAt: !8)
+!16 = !{!"0x101\00y\004\000", !10, !2, !13} ; [ DW_TAG_arg_variable ]
+!17 = !{!"0x101\00z\004\000", !10, !2, !14} ; [ DW_TAG_arg_variable ]
+!18 = !MDLocation(line: 5, scope: !10, inlinedAt: !8)
+!19 = !MDLocation(line: 10, scope: !1)
+!20 = !{!"bar.c", !"/tmp/"}
+!21 = !{i32 0}
+!22 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/MemCpyOpt/callslot_aa.ll b/test/Transforms/MemCpyOpt/callslot_aa.ll
new file mode 100644
index 0000000..b6ea129
--- /dev/null
+++ b/test/Transforms/MemCpyOpt/callslot_aa.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -S -basicaa -memcpyopt | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%T = type { i64, i64 }
+
+define void @test(i8* %src) {
+ %tmp = alloca i8
+ %dst = alloca i8
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i32 8, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %src, i64 1, i32 8, i1 false), !noalias !2
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %tmp, i64 1, i32 8, i1 false)
+
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1)
+
+; Check that the noalias for "dst" was removed by checking that the metadata is gone
+; CHECK-NOT: "dst"
+!0 = !{!0}
+!1 = distinct !{!1, !0, !"dst"}
+!2 = distinct !{!1}
diff --git a/test/Transforms/MemCpyOpt/form-memset.ll b/test/Transforms/MemCpyOpt/form-memset.ll
index d980b7f..0a40943 100644
--- a/test/Transforms/MemCpyOpt/form-memset.ll
+++ b/test/Transforms/MemCpyOpt/form-memset.ll
@@ -284,3 +284,18 @@ define void @test10(i8* nocapture %P) nounwind {
; CHECK-NOT: memset
; CHECK: ret void
}
+
+; Memset followed by odd store.
+define void @test11(i32* nocapture %P) nounwind ssp {
+entry:
+ %add.ptr = getelementptr inbounds i32* %P, i64 3
+ %0 = bitcast i32* %add.ptr to i8*
+ tail call void @llvm.memset.p0i8.i64(i8* %0, i8 1, i64 11, i32 1, i1 false)
+ %arrayidx = getelementptr inbounds i32* %P, i64 0
+ %arrayidx.cast = bitcast i32* %arrayidx to i96*
+ store i96 310698676526526814092329217, i96* %arrayidx.cast, align 4
+ ret void
+; CHECK-LABEL: @test11(
+; CHECK-NOT: store
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %1, i8 1, i64 23, i32 4, i1 false)
+}
diff --git a/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll b/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
index 9878b47..b2083cb 100644
--- a/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
+++ b/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
@@ -87,5 +87,5 @@ lpad:
declare i8 @dummy();
declare i32 @__gxx_personality_v0(...)
-!0 = metadata !{i8 0, i8 2}
-!1 = metadata !{i8 5, i8 7} \ No newline at end of file
+!0 = !{i8 0, i8 2}
+!1 = !{i8 5, i8 7}
diff --git a/test/Transforms/MergeFunc/ranges.ll b/test/Transforms/MergeFunc/ranges.ll
index e25ff1d..d3e4d94 100644
--- a/test/Transforms/MergeFunc/ranges.ll
+++ b/test/Transforms/MergeFunc/ranges.ll
@@ -39,5 +39,5 @@ define i1 @cmp_with_same_range(i8*, i8*) {
ret i1 %out
}
-!0 = metadata !{i8 0, i8 2}
-!1 = metadata !{i8 5, i8 7}
+!0 = !{i8 0, i8 2}
+!1 = !{i8 5, i8 7}
diff --git a/test/Transforms/ObjCARC/allocas.ll b/test/Transforms/ObjCARC/allocas.ll
index d2e7841..7b671df 100644
--- a/test/Transforms/ObjCARC/allocas.ll
+++ b/test/Transforms/ObjCARC/allocas.ll
@@ -495,6 +495,6 @@ arraydestroy.done1:
ret void
}
-!0 = metadata !{}
+!0 = !{}
declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/ObjCARC/arc-annotations.ll b/test/Transforms/ObjCARC/arc-annotations.ll
index f76ba3b..c0ce44f 100644
--- a/test/Transforms/ObjCARC/arc-annotations.ll
+++ b/test/Transforms/ObjCARC/arc-annotations.ll
@@ -73,11 +73,11 @@ return:
ret void
}
-!0 = metadata !{}
+!0 = !{}
-; CHECK: ![[ANN0]] = metadata !{metadata !"(test0,%x)", metadata !"S_Use", metadata !"S_None"}
-; CHECK: ![[ANN1]] = metadata !{metadata !"(test0,%x)", metadata !"S_None", metadata !"S_Retain"}
-; CHECK: ![[ANN2]] = metadata !{metadata !"(test0,%x)", metadata !"S_Release", metadata !"S_Use"}
-; CHECK: ![[ANN3]] = metadata !{metadata !"(test0,%x)", metadata !"S_None", metadata !"S_Release"}
-; CHECK: ![[ANN4]] = metadata !{metadata !"(test0,%x)", metadata !"S_Retain", metadata !"S_None"}
+; CHECK: ![[ANN0]] = !{!"(test0,%x)", !"S_Use", !"S_None"}
+; CHECK: ![[ANN1]] = !{!"(test0,%x)", !"S_None", !"S_Retain"}
+; CHECK: ![[ANN2]] = !{!"(test0,%x)", !"S_Release", !"S_Use"}
+; CHECK: ![[ANN3]] = !{!"(test0,%x)", !"S_None", !"S_Release"}
+; CHECK: ![[ANN4]] = !{!"(test0,%x)", !"S_Retain", !"S_None"}
diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll
index a1ee956..7bc58c4 100644
--- a/test/Transforms/ObjCARC/basic.ll
+++ b/test/Transforms/ObjCARC/basic.ll
@@ -2679,8 +2679,8 @@ define {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) n
invoke.cont:
%0 = bitcast {}* %self to i8*
%1 = tail call i8* @objc_retain(i8* %0) nounwind
- tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0, metadata !{})
- tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0, metadata !{})
+ tail call void @llvm.dbg.value(metadata {}* %self, i64 0, metadata !0, metadata !{})
+ tail call void @llvm.dbg.value(metadata {}* %self, i64 0, metadata !0, metadata !{})
%ivar = load i64* @"OBJC_IVAR_$_A.myZ", align 8
%add.ptr = getelementptr i8* %0, i64 %ivar
%tmp1 = bitcast i8* %add.ptr to float*
@@ -3011,9 +3011,9 @@ define void @test67(i8* %x) {
!llvm.module.flags = !{!1}
-!0 = metadata !{}
-!1 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{}
+!1 = !{i32 1, !"Debug Info Version", i32 2}
; CHECK: attributes #0 = { nounwind readnone }
; CHECK: attributes [[NUW]] = { nounwind }
-; CHECK: ![[RELEASE]] = metadata !{}
+; CHECK: ![[RELEASE]] = !{}
diff --git a/test/Transforms/ObjCARC/cfg-hazards.ll b/test/Transforms/ObjCARC/cfg-hazards.ll
index 61e5a3b..746d56d 100644
--- a/test/Transforms/ObjCARC/cfg-hazards.ll
+++ b/test/Transforms/ObjCARC/cfg-hazards.ll
@@ -432,4 +432,4 @@ exit:
; CHECK: attributes [[NUW]] = { nounwind }
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/ObjCARC/contract-marker.ll b/test/Transforms/ObjCARC/contract-marker.ll
index 55a1b28..a828260 100644
--- a/test/Transforms/ObjCARC/contract-marker.ll
+++ b/test/Transforms/ObjCARC/contract-marker.ll
@@ -22,6 +22,6 @@ declare void @bar(i8*)
!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
-!0 = metadata !{metadata !"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
+!0 = !{!"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/ObjCARC/contract-storestrong.ll b/test/Transforms/ObjCARC/contract-storestrong.ll
index 50a2d97..c218e33 100644
--- a/test/Transforms/ObjCARC/contract-storestrong.ll
+++ b/test/Transforms/ObjCARC/contract-storestrong.ll
@@ -24,7 +24,7 @@ entry:
; Don't do this if the load is volatile.
-; CHECK: define void @test1(i8* %p) {
+; CHECK-LABEL: define void @test1(i8* %p) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) [[NUW]]
; CHECK-NEXT: %tmp = load volatile i8** @x, align 8
@@ -43,7 +43,7 @@ entry:
; Don't do this if the store is volatile.
-; CHECK: define void @test2(i8* %p) {
+; CHECK-LABEL: define void @test2(i8* %p) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) [[NUW]]
; CHECK-NEXT: %tmp = load i8** @x, align 8
@@ -63,15 +63,15 @@ entry:
; Don't do this if there's a use of the old pointer value between the store
; and the release.
-; CHECK: define void @test3(i8* %newValue) {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) [[NUW]]
-; CHECK-NEXT: %x1 = load i8** @x, align 8
-; CHECK-NEXT: store i8* %x0, i8** @x, align 8
-; CHECK-NEXT: tail call void @use_pointer(i8* %x1), !clang.arc.no_objc_arc_exceptions !0
-; CHECK-NEXT: tail call void @objc_release(i8* %x1) [[NUW]], !clang.imprecise_release !0
-; CHECK-NEXT: ret void
-; CHECK-NEXT: }
+; CHECK-LABEL: define void @test3(i8* %newValue) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) [[NUW]]
+; CHECK-NEXT: %x1 = load i8** @x, align 8
+; CHECK-NEXT: store i8* %x0, i8** @x, align 8
+; CHECK-NEXT: tail call void @use_pointer(i8* %x1), !clang.arc.no_objc_arc_exceptions !0
+; CHECK-NEXT: tail call void @objc_release(i8* %x1) [[NUW]], !clang.imprecise_release !0
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
define void @test3(i8* %newValue) {
entry:
%x0 = tail call i8* @objc_retain(i8* %newValue) nounwind
@@ -84,15 +84,15 @@ entry:
; Like test3, but with an icmp use instead of a call, for good measure.
-; CHECK: define i1 @test4(i8* %newValue, i8* %foo) {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) [[NUW]]
-; CHECK-NEXT: %x1 = load i8** @x, align 8
-; CHECK-NEXT: store i8* %x0, i8** @x, align 8
-; CHECK-NEXT: %t = icmp eq i8* %x1, %foo
-; CHECK-NEXT: tail call void @objc_release(i8* %x1) [[NUW]], !clang.imprecise_release !0
-; CHECK-NEXT: ret i1 %t
-; CHECK-NEXT: }
+; CHECK-LABEL: define i1 @test4(i8* %newValue, i8* %foo) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %x0 = tail call i8* @objc_retain(i8* %newValue) [[NUW]]
+; CHECK-NEXT: %x1 = load i8** @x, align 8
+; CHECK-NEXT: store i8* %x0, i8** @x, align 8
+; CHECK-NEXT: %t = icmp eq i8* %x1, %foo
+; CHECK-NEXT: tail call void @objc_release(i8* %x1) [[NUW]], !clang.imprecise_release !0
+; CHECK-NEXT: ret i1 %t
+; CHECK-NEXT: }
define i1 @test4(i8* %newValue, i8* %foo) {
entry:
%x0 = tail call i8* @objc_retain(i8* %newValue) nounwind
@@ -105,7 +105,7 @@ entry:
; Do form an objc_storeStrong here, because the use is before the store.
-; CHECK: define i1 @test5(i8* %newValue, i8* %foo) {
+; CHECK-LABEL: define i1 @test5(i8* %newValue, i8* %foo) {
; CHECK: %t = icmp eq i8* %x1, %foo
; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) [[NUW]]
; CHECK: }
@@ -121,7 +121,7 @@ entry:
; Like test5, but the release is before the store.
-; CHECK: define i1 @test6(i8* %newValue, i8* %foo) {
+; CHECK-LABEL: define i1 @test6(i8* %newValue, i8* %foo) {
; CHECK: %t = icmp eq i8* %x1, %foo
; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) [[NUW]]
; CHECK: }
@@ -137,7 +137,7 @@ entry:
; Like test0, but there's no store, so don't form an objc_storeStrong.
-; CHECK-LABEL: define void @test7(
+; CHECK-LABEL: define void @test7(
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %p) [[NUW]]
; CHECK-NEXT: %tmp = load i8** @x, align 8
@@ -154,7 +154,7 @@ entry:
; Like test0, but there's no retain, so don't form an objc_storeStrong.
-; CHECK-LABEL: define void @test8(
+; CHECK-LABEL: define void @test8(
; CHECK-NEXT: entry:
; CHECK-NEXT: %tmp = load i8** @x, align 8
; CHECK-NEXT: store i8* %p, i8** @x, align 8
@@ -169,6 +169,54 @@ entry:
ret void
}
-!0 = metadata !{}
+; Make sure that we properly handle release that *may* release our new
+; value in between the retain and the store. We need to be sure that
+; this we can safely move the retain to the store. This specific test
+; makes sure that we properly handled a release of an unrelated
+; pointer.
+;
+; CHECK-LABEL: define i1 @test9(i8* %newValue, i8* %foo, i8* %unrelated_ptr) {
+; CHECK-NOT: objc_storeStrong
+define i1 @test9(i8* %newValue, i8* %foo, i8* %unrelated_ptr) {
+entry:
+ %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind
+ tail call void @objc_release(i8* %unrelated_ptr) nounwind, !clang.imprecise_release !0
+ %x1 = load i8** @x, align 8
+ tail call void @objc_release(i8* %x1) nounwind, !clang.imprecise_release !0
+ %t = icmp eq i8* %x1, %foo
+ store i8* %newValue, i8** @x, align 8
+ ret i1 %t
+}
+
+; Make sure that we don't perform the optimization when we just have a call.
+;
+; CHECK-LABEL: define i1 @test10(i8* %newValue, i8* %foo, i8* %unrelated_ptr) {
+; CHECK-NOT: objc_storeStrong
+define i1 @test10(i8* %newValue, i8* %foo, i8* %unrelated_ptr) {
+entry:
+ %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind
+ call void @use_pointer(i8* %unrelated_ptr)
+ %x1 = load i8** @x, align 8
+ tail call void @objc_release(i8* %x1) nounwind, !clang.imprecise_release !0
+ %t = icmp eq i8* %x1, %foo
+ store i8* %newValue, i8** @x, align 8
+ ret i1 %t
+}
+
+; Make sure we form the store strong if the use in between the retain
+; and the store does not touch reference counts.
+; CHECK-LABEL: define i1 @test11(i8* %newValue, i8* %foo, i8* %unrelated_ptr) {
+; CHECK: objc_storeStrong
+define i1 @test11(i8* %newValue, i8* %foo, i8* %unrelated_ptr) {
+entry:
+ %x0 = tail call i8* @objc_retain(i8* %newValue) nounwind
+ %t = icmp eq i8* %newValue, %foo
+ %x1 = load i8** @x, align 8
+ tail call void @objc_release(i8* %x1) nounwind, !clang.imprecise_release !0
+ store i8* %newValue, i8** @x, align 8
+ ret i1 %t
+}
+
+!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/ObjCARC/contract-testcases.ll b/test/Transforms/ObjCARC/contract-testcases.ll
index 0bf63a6..74a4a7f 100644
--- a/test/Transforms/ObjCARC/contract-testcases.ll
+++ b/test/Transforms/ObjCARC/contract-testcases.ll
@@ -89,7 +89,7 @@ lpad: ; preds = %entry
!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
-!0 = metadata !{metadata !"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
+!0 = !{!"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
; CHECK: attributes #0 = { optsize }
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/ObjCARC/empty-block.ll b/test/Transforms/ObjCARC/empty-block.ll
index 0440ab8..cc82d10 100644
--- a/test/Transforms/ObjCARC/empty-block.ll
+++ b/test/Transforms/ObjCARC/empty-block.ll
@@ -56,4 +56,4 @@ define %0* @test1() nounwind {
declare %0* @foo()
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll b/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll
index 03af93e..c72566c 100644
--- a/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll
+++ b/test/Transforms/ObjCARC/ensure-that-exception-unwind-path-is-visited.ll
@@ -41,10 +41,10 @@ entry:
%tmp2 = bitcast %struct._class_t* %tmp to i8*, !dbg !37
; CHECK: call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp2, i8* %tmp1)
%call = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp2, i8* %tmp1), !dbg !37, !clang.arc.no_objc_arc_exceptions !38
- call void @llvm.dbg.value(metadata !{i8* %call}, i64 0, metadata !12, metadata !{}), !dbg !37
+ call void @llvm.dbg.value(metadata i8* %call, i64 0, metadata i32 02, metadata !{}), !dbg !37
; CHECK: call i8* @objc_retain(i8* %call) [[NUW:#[0-9]+]]
%tmp3 = call i8* @objc_retain(i8* %call) nounwind, !dbg !39
- call void @llvm.dbg.value(metadata !{i8* %call}, i64 0, metadata !25, metadata !{}), !dbg !39
+ call void @llvm.dbg.value(metadata i8* %call, i64 0, metadata !25, metadata !{}), !dbg !39
invoke fastcc void @ThrowFunc(i8* %call)
to label %eh.cont unwind label %lpad, !dbg !40, !clang.arc.no_objc_arc_exceptions !38
@@ -58,7 +58,7 @@ lpad: ; preds = %entry
catch i8* null, !dbg !40
%tmp5 = extractvalue { i8*, i32 } %tmp4, 0, !dbg !40
%exn.adjusted = call i8* @objc_begin_catch(i8* %tmp5) nounwind, !dbg !44
- call void @llvm.dbg.value(metadata !45, i64 0, metadata !21, metadata !{}), !dbg !46
+ call void @llvm.dbg.value(metadata i8 0, i64 0, metadata !21, metadata !{}), !dbg !46
call void @objc_end_catch(), !dbg !49, !clang.arc.no_objc_arc_exceptions !38
; CHECK: call void @objc_release(i8* %call)
call void @objc_release(i8* %call) nounwind, !dbg !42, !clang.imprecise_release !38
@@ -87,7 +87,7 @@ declare void @objc_exception_rethrow()
define internal fastcc void @ThrowFunc(i8* %obj) uwtable noinline ssp {
entry:
%tmp = call i8* @objc_retain(i8* %obj) nounwind
- call void @llvm.dbg.value(metadata !{i8* %obj}, i64 0, metadata !32, metadata !{}), !dbg !55
+ call void @llvm.dbg.value(metadata i8* %obj, i64 0, metadata !32, metadata !{}), !dbg !55
%tmp1 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_1", align 8, !dbg !56
%tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", align 8, !dbg !56, !invariant.load !38
%tmp3 = bitcast %struct._class_t* %tmp1 to i8*, !dbg !56
@@ -113,62 +113,62 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!33, !34, !35, !36, !61}
-!0 = metadata !{metadata !"0x11\0016\00clang version 3.3 \001\00\002\00\000", metadata !60, metadata !1, metadata !1, metadata !3, metadata !1, null} ; [ DW_TAG_compile_unit ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m] [DW_LANG_ObjC]
-!1 = metadata !{i32 0}
-!3 = metadata !{metadata !5, metadata !27}
-!5 = metadata !{metadata !"0x2e\00main\00main\00\009\000\001\000\006\000\001\0010", metadata !60, metadata !6, metadata !7, null, i32 ()* @main, null, null, metadata !10} ; [ DW_TAG_subprogram ] [line 9] [def] [scope 10] [main]
-!6 = metadata !{metadata !"0x29", metadata !60} ; [ DW_TAG_file_type ]
-!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!8 = metadata !{metadata !9}
-!9 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!10 = metadata !{metadata !11}
-!11 = metadata !{metadata !12, metadata !21, metadata !25}
-!12 = metadata !{metadata !"0x100\00obj\0011\000", metadata !13, metadata !6, metadata !14} ; [ DW_TAG_auto_variable ] [obj] [line 11]
-!13 = metadata !{metadata !"0xb\0010\000\000", metadata !60, metadata !5} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!14 = metadata !{metadata !"0x16\00id\0011\000\000\000\000", metadata !60, null, metadata !15} ; [ DW_TAG_typedef ] [id] [line 11, size 0, align 0, offset 0] [from ]
-!15 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", metadata !60, null, metadata !16} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from objc_object]
-!16 = metadata !{metadata !"0x13\00objc_object\000\000\000\000\000\000", metadata !60, null, null, metadata !17, null, i32 0, null} ; [ DW_TAG_structure_type ] [objc_object] [line 0, size 0, align 0, offset 0] [def] [from ]
-!17 = metadata !{metadata !18}
-!18 = metadata !{metadata !"0xd\00isa\000\0064\000\000\000", metadata !60, metadata !16, metadata !19} ; [ DW_TAG_member ] [isa] [line 0, size 64, align 0, offset 0] [from ]
-!19 = metadata !{metadata !"0xf\00\000\0064\000\000\000", null, null, metadata !20} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 0, offset 0] [from objc_class]
-!20 = metadata !{metadata !"0x13\00objc_class\000\000\000\000\004\000", metadata !60, null, null, null, null, null, null} ; [ DW_TAG_structure_type ] [objc_class] [line 0, size 0, align 0, offset 0] [decl] [from ]
-!21 = metadata !{metadata !"0x100\00ok\0013\000", metadata !22, metadata !6, metadata !23} ; [ DW_TAG_auto_variable ] [ok] [line 13]
-!22 = metadata !{metadata !"0xb\0012\000\001", metadata !60, metadata !13} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!23 = metadata !{metadata !"0x16\00BOOL\0062\000\000\000\000", metadata !60, null, metadata !24} ; [ DW_TAG_typedef ] [BOOL] [line 62, size 0, align 0, offset 0] [from signed char]
-!24 = metadata !{metadata !"0x24\00signed char\000\008\008\000\000\006", null, null} ; [ DW_TAG_base_type ] [signed char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
-!25 = metadata !{metadata !"0x100\00obj2\0015\000", metadata !26, metadata !6, metadata !14} ; [ DW_TAG_auto_variable ] [obj2] [line 15]
-!26 = metadata !{metadata !"0xb\0014\000\002", metadata !60, metadata !22} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!27 = metadata !{metadata !"0x2e\00ThrowFunc\00ThrowFunc\00\004\001\001\000\006\00256\001\005", metadata !60, metadata !6, metadata !28, null, void (i8*)* @ThrowFunc, null, null, metadata !30} ; [ DW_TAG_subprogram ] [line 4] [local] [def] [scope 5] [ThrowFunc]
-!28 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !29, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!29 = metadata !{null, metadata !14}
-!30 = metadata !{metadata !31}
-!31 = metadata !{metadata !32}
-!32 = metadata !{metadata !"0x101\00obj\0016777220\000", metadata !27, metadata !6, metadata !14} ; [ DW_TAG_arg_variable ] [obj] [line 4]
-!33 = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
-!34 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
-!35 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
-!36 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
-!37 = metadata !{i32 11, i32 0, metadata !13, null}
-!38 = metadata !{}
-!39 = metadata !{i32 15, i32 0, metadata !26, null}
-!40 = metadata !{i32 17, i32 0, metadata !41, null}
-!41 = metadata !{metadata !"0xb\0016\000\003", metadata !60, metadata !26} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!42 = metadata !{i32 22, i32 0, metadata !26, null}
-!43 = metadata !{i32 23, i32 0, metadata !22, null}
-!44 = metadata !{i32 19, i32 0, metadata !41, null}
-!45 = metadata !{i8 0}
-!46 = metadata !{i32 20, i32 0, metadata !47, null}
-!47 = metadata !{metadata !"0xb\0019\000\005", metadata !60, metadata !48} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!48 = metadata !{metadata !"0xb\0019\000\004", metadata !60, metadata !26} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!49 = metadata !{i32 21, i32 0, metadata !47, null}
-!50 = metadata !{i32 24, i32 0, metadata !51, null}
-!51 = metadata !{metadata !"0xb\0023\000\006", metadata !60, metadata !22} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!52 = metadata !{i32 25, i32 0, metadata !51, null}
-!53 = metadata !{i32 27, i32 0, metadata !13, null}
-!54 = metadata !{i32 28, i32 0, metadata !13, null}
-!55 = metadata !{i32 4, i32 0, metadata !27, null}
-!56 = metadata !{i32 6, i32 0, metadata !57, null}
-!57 = metadata !{metadata !"0xb\005\000\007", metadata !60, metadata !27} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
-!58 = metadata !{i32 7, i32 0, metadata !57, null}
-!60 = metadata !{metadata !"test.m", metadata !"/Volumes/Files/gottesmmcab/Radar/12906997"}
-!61 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\0016\00clang version 3.3 \001\00\002\00\000", !60, !1, !1, !3, !1, null} ; [ DW_TAG_compile_unit ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m] [DW_LANG_ObjC]
+!1 = !{i32 0}
+!3 = !{!5, !27}
+!5 = !{!"0x2e\00main\00main\00\009\000\001\000\006\000\001\0010", !60, !6, !7, null, i32 ()* @main, null, null, !10} ; [ DW_TAG_subprogram ] [line 9] [def] [scope 10] [main]
+!6 = !{!"0x29", !60} ; [ DW_TAG_file_type ]
+!7 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = !{!9}
+!9 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!10 = !{!11}
+!11 = !{!12, !21, !25}
+!12 = !{!"0x100\00obj\0011\000", !13, !6, !14} ; [ DW_TAG_auto_variable ] [obj] [line 11]
+!13 = !{!"0xb\0010\000\000", !60, !5} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!14 = !{!"0x16\00id\0011\000\000\000\000", !60, null, !15} ; [ DW_TAG_typedef ] [id] [line 11, size 0, align 0, offset 0] [from ]
+!15 = !{!"0xf\00\000\0064\0064\000\000", !60, null, !16} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from objc_object]
+!16 = !{!"0x13\00objc_object\000\000\000\000\000\000", !60, null, null, !17, null, i32 0, null} ; [ DW_TAG_structure_type ] [objc_object] [line 0, size 0, align 0, offset 0] [def] [from ]
+!17 = !{!18}
+!18 = !{!"0xd\00isa\000\0064\000\000\000", !60, !16, !19} ; [ DW_TAG_member ] [isa] [line 0, size 64, align 0, offset 0] [from ]
+!19 = !{!"0xf\00\000\0064\000\000\000", null, null, !20} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 0, offset 0] [from objc_class]
+!20 = !{!"0x13\00objc_class\000\000\000\000\004\000", !60, null, null, null, null, null, null} ; [ DW_TAG_structure_type ] [objc_class] [line 0, size 0, align 0, offset 0] [decl] [from ]
+!21 = !{!"0x100\00ok\0013\000", !22, !6, !23} ; [ DW_TAG_auto_variable ] [ok] [line 13]
+!22 = !{!"0xb\0012\000\001", !60, !13} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!23 = !{!"0x16\00BOOL\0062\000\000\000\000", !60, null, !24} ; [ DW_TAG_typedef ] [BOOL] [line 62, size 0, align 0, offset 0] [from signed char]
+!24 = !{!"0x24\00signed char\000\008\008\000\000\006", null, null} ; [ DW_TAG_base_type ] [signed char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
+!25 = !{!"0x100\00obj2\0015\000", !26, !6, !14} ; [ DW_TAG_auto_variable ] [obj2] [line 15]
+!26 = !{!"0xb\0014\000\002", !60, !22} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!27 = !{!"0x2e\00ThrowFunc\00ThrowFunc\00\004\001\001\000\006\00256\001\005", !60, !6, !28, null, void (i8*)* @ThrowFunc, null, null, !30} ; [ DW_TAG_subprogram ] [line 4] [local] [def] [scope 5] [ThrowFunc]
+!28 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !29, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!29 = !{null, !14}
+!30 = !{!31}
+!31 = !{!32}
+!32 = !{!"0x101\00obj\0016777220\000", !27, !6, !14} ; [ DW_TAG_arg_variable ] [obj] [line 4]
+!33 = !{i32 1, !"Objective-C Version", i32 2}
+!34 = !{i32 1, !"Objective-C Image Info Version", i32 0}
+!35 = !{i32 1, !"Objective-C Image Info Section", !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
+!36 = !{i32 4, !"Objective-C Garbage Collection", i32 0}
+!37 = !MDLocation(line: 11, scope: !13)
+!38 = !{}
+!39 = !MDLocation(line: 15, scope: !26)
+!40 = !MDLocation(line: 17, scope: !41)
+!41 = !{!"0xb\0016\000\003", !60, !26} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!42 = !MDLocation(line: 22, scope: !26)
+!43 = !MDLocation(line: 23, scope: !22)
+!44 = !MDLocation(line: 19, scope: !41)
+!45 = !{i8 0}
+!46 = !MDLocation(line: 20, scope: !47)
+!47 = !{!"0xb\0019\000\005", !60, !48} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!48 = !{!"0xb\0019\000\004", !60, !26} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!49 = !MDLocation(line: 21, scope: !47)
+!50 = !MDLocation(line: 24, scope: !51)
+!51 = !{!"0xb\0023\000\006", !60, !22} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!52 = !MDLocation(line: 25, scope: !51)
+!53 = !MDLocation(line: 27, scope: !13)
+!54 = !MDLocation(line: 28, scope: !13)
+!55 = !MDLocation(line: 4, scope: !27)
+!56 = !MDLocation(line: 6, scope: !57)
+!57 = !{!"0xb\005\000\007", !60, !27} ; [ DW_TAG_lexical_block ] [/Volumes/Files/gottesmmcab/Radar/12906997/test.m]
+!58 = !MDLocation(line: 7, scope: !57)
+!60 = !{!"test.m", !"/Volumes/Files/gottesmmcab/Radar/12906997"}
+!61 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/ObjCARC/escape.ll b/test/Transforms/ObjCARC/escape.ll
index 28f2e80..357f759 100644
--- a/test/Transforms/ObjCARC/escape.ll
+++ b/test/Transforms/ObjCARC/escape.ll
@@ -128,7 +128,7 @@ declare i8* @objc_storeWeak(i8**, i8*)
declare i8* @not_really_objc_storeWeak(i8**, i8*)
declare void @objc_release(i8*)
-!0 = metadata !{}
+!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }
; CHECK: attributes #1 = { nounwind ssp }
diff --git a/test/Transforms/ObjCARC/intrinsic-use.ll b/test/Transforms/ObjCARC/intrinsic-use.ll
index f3833cb..b1e56c8 100644
--- a/test/Transforms/ObjCARC/intrinsic-use.ll
+++ b/test/Transforms/ObjCARC/intrinsic-use.ll
@@ -112,5 +112,5 @@ entry:
}
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/ObjCARC/invoke.ll b/test/Transforms/ObjCARC/invoke.ll
index 04d057b..5ef5184 100644
--- a/test/Transforms/ObjCARC/invoke.ll
+++ b/test/Transforms/ObjCARC/invoke.ll
@@ -221,4 +221,4 @@ declare i32 @__objc_personality_v0(...)
; CHECK: attributes [[NUW]] = { nounwind }
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/ObjCARC/nested.ll b/test/Transforms/ObjCARC/nested.ll
index 2eeb4fc..7d72e37 100644
--- a/test/Transforms/ObjCARC/nested.ll
+++ b/test/Transforms/ObjCARC/nested.ll
@@ -21,7 +21,7 @@ declare void @__crasher_block_invoke(i8* nocapture)
declare i8* @objc_retainBlock(i8*)
declare void @__crasher_block_invoke1(i8* nocapture)
-!0 = metadata !{}
+!0 = !{}
; Delete a nested retain+release pair.
diff --git a/test/Transforms/ObjCARC/path-overflow.ll b/test/Transforms/ObjCARC/path-overflow.ll
index 3c14353..d239653 100644
--- a/test/Transforms/ObjCARC/path-overflow.ll
+++ b/test/Transforms/ObjCARC/path-overflow.ll
@@ -2190,4 +2190,4 @@ return: ; No predecessors!
}
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/ObjCARC/retain-not-declared.ll b/test/Transforms/ObjCARC/retain-not-declared.ll
index 3a2bd03..4162022 100644
--- a/test/Transforms/ObjCARC/retain-not-declared.ll
+++ b/test/Transforms/ObjCARC/retain-not-declared.ll
@@ -64,6 +64,6 @@ lpad100: ; preds = %invoke.cont93
declare i32 @__gxx_personality_v0(...)
-!0 = metadata !{}
+!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/ObjCARC/split-backedge.ll b/test/Transforms/ObjCARC/split-backedge.ll
index 1b7cf44..2507173 100644
--- a/test/Transforms/ObjCARC/split-backedge.ll
+++ b/test/Transforms/ObjCARC/split-backedge.ll
@@ -45,6 +45,6 @@ declare void @objc_release(i8*)
declare i8* @objc_retain(i8*)
declare void @use_pointer(i8*)
-!0 = metadata !{}
+!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/Transforms/ObjCARC/weak-copies.ll b/test/Transforms/ObjCARC/weak-copies.ll
index 5dab4e0..13d0b0a 100644
--- a/test/Transforms/ObjCARC/weak-copies.ll
+++ b/test/Transforms/ObjCARC/weak-copies.ll
@@ -86,4 +86,4 @@ declare void @objc_destroyWeak(i8**)
; CHECK: attributes [[NUW]] = { nounwind }
-!0 = metadata !{}
+!0 = !{}
diff --git a/test/Transforms/PlaceSafepoints/basic.ll b/test/Transforms/PlaceSafepoints/basic.ll
new file mode 100644
index 0000000..ca63da4
--- /dev/null
+++ b/test/Transforms/PlaceSafepoints/basic.ll
@@ -0,0 +1,94 @@
+; RUN: opt %s -S -place-safepoints | FileCheck %s
+
+
+; Do we insert a simple entry safepoint?
+define void @test_entry() gc "statepoint-example" {
+; CHECK-LABEL: @test_entry
+entry:
+; CHECK-LABEL: entry
+; CHECK: statepoint
+ ret void
+}
+
+; On a non-gc function, we should NOT get an entry safepoint
+define void @test_negative() {
+; CHECK-LABEL: @test_negative
+entry:
+; CHECK-NOT: statepoint
+ ret void
+}
+
+; Do we insert a backedge safepoint in a statically
+; infinite loop?
+define void @test_backedge() gc "statepoint-example" {
+; CHECK-LABEL: test_backedge
+entry:
+; CHECK-LABEL: entry
+; This statepoint is technically not required, but we don't exploit that yet.
+; CHECK: statepoint
+ br label %other
+
+; CHECK-LABEL: other
+; CHECK: statepoint
+other:
+ call void undef()
+ br label %other
+}
+
+; Check that we remove an unreachable block rather than trying
+; to insert a backedge safepoint
+define void @test_unreachable() gc "statepoint-example" {
+; CHECK-LABEL: test_unreachable
+entry:
+; CHECK-LABEL: entry
+; CHECK: statepoint
+ ret void
+
+; CHECK-NOT: other
+; CHECK-NOT: statepoint
+other:
+ br label %other
+}
+
+declare void @foo()
+
+; Do we turn a call into it's own statepoint
+define void @test_simple_call() gc "statepoint-example" {
+; CHECK-LABEL: test_simple_call
+entry:
+ br label %other
+other:
+; CHECK-LABEL: other
+; CHECK: statepoint
+; CHECK-NOT: gc.result
+ call void @foo()
+ ret void
+}
+
+declare zeroext i1 @i1_return_i1(i1)
+
+define i1 @test_call_with_result() gc "statepoint-example" {
+; CHECK-LABEL: test_call_with_result
+; This is checking that a statepoint_poll + statepoint + result is
+; inserted for a function that takes 1 argument.
+; CHECK: gc.statepoint.p0f_isVoidf
+; CHECK: gc.statepoint.p0f_i1i1f
+; CHECK: (i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0)
+; CHECK: %call12 = call i1 @llvm.experimental.gc.result.i1
+entry:
+ %call1 = tail call i1 (i1)* @i1_return_i1(i1 false)
+ ret i1 %call1
+}
+
+; This function is inlined when inserting a poll. To avoid recursive
+; issues, make sure we don't place safepoints in it.
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+; CHECK-LABEL: gc.safepoint_poll
+; CHECK-LABEL: entry
+; CHECK-NEXT: do_safepoint
+; CHECK-NEXT: ret void
+entry:
+ call void @do_safepoint()
+ ret void
+}
diff --git a/test/Transforms/PlaceSafepoints/call-in-loop.ll b/test/Transforms/PlaceSafepoints/call-in-loop.ll
new file mode 100644
index 0000000..a220fc9
--- /dev/null
+++ b/test/Transforms/PlaceSafepoints/call-in-loop.ll
@@ -0,0 +1,31 @@
+; If there's a call in the loop which dominates the backedge, we
+; don't need a safepoint poll (since the callee must contain a
+; poll test).
+;; RUN: opt %s -place-safepoints -S | FileCheck %s
+
+declare void @foo()
+
+define void @test1() gc "statepoint-example" {
+; CHECK-LABEL: test1
+
+entry:
+; CHECK-LABEL: entry
+; CHECK: statepoint
+ br label %loop
+
+loop:
+; CHECK-LABEL: loop
+; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo
+; CHECK-NOT: statepoint
+ call void @foo()
+ br label %loop
+}
+
+; This function is inlined when inserting a poll.
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+; CHECK-LABEL: gc.safepoint_poll
+entry:
+ call void @do_safepoint()
+ ret void
+}
diff --git a/test/Transforms/PlaceSafepoints/finite-loops.ll b/test/Transforms/PlaceSafepoints/finite-loops.ll
new file mode 100644
index 0000000..8b64d24
--- /dev/null
+++ b/test/Transforms/PlaceSafepoints/finite-loops.ll
@@ -0,0 +1,80 @@
+; Tests to ensure that we are not placing backedge safepoints in
+; loops which are clearly finite.
+;; RUN: opt %s -place-safepoints -S | FileCheck %s
+
+
+; A simple counted loop with trivially known range
+define void @test1(i32) gc "statepoint-example" {
+; CHECK-LABEL: test1
+; CHECK-LABEL: entry
+; CHECK: statepoint
+; CHECK-LABEL: loop
+; CHECK-NOT: statepoint
+
+entry:
+ br label %loop
+
+loop:
+ %counter = phi i32 [ 0 , %entry ], [ %counter.inc , %loop ]
+ %counter.inc = add i32 %counter, 1
+ %counter.cmp = icmp slt i32 %counter.inc, 16
+ br i1 %counter.cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+; The same counted loop, but with an unknown early exit
+define void @test2(i32) gc "statepoint-example" {
+; CHECK-LABEL: test2
+; CHECK-LABEL: entry
+; CHECK: statepoint
+; CHECK-LABEL: loop
+; CHECK-NOT: statepoint
+
+entry:
+ br label %loop
+
+loop:
+ %counter = phi i32 [ 0 , %entry ], [ %counter.inc , %continue ]
+ %counter.inc = add i32 %counter, 1
+ %counter.cmp = icmp slt i32 %counter.inc, 16
+ br i1 undef, label %continue, label %exit
+
+continue:
+ br i1 %counter.cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+; The range is a 8 bit value and we can't overflow
+define void @test3(i8 %upper) gc "statepoint-example" {
+; CHECK-LABEL: test3
+; CHECK-LABEL: entry
+; CHECK: statepoint
+; CHECK-LABEL: loop
+; CHECK-NOT: statepoint
+
+entry:
+ br label %loop
+
+loop:
+ %counter = phi i8 [ 0 , %entry ], [ %counter.inc , %loop ]
+ %counter.inc = add nsw i8 %counter, 1
+ %counter.cmp = icmp slt i8 %counter.inc, %upper
+ br i1 %counter.cmp, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+
+; This function is inlined when inserting a poll.
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+; CHECK-LABEL: gc.safepoint_poll
+entry:
+ call void @do_safepoint()
+ ret void
+}
diff --git a/test/Transforms/PlaceSafepoints/invokes.ll b/test/Transforms/PlaceSafepoints/invokes.ll
new file mode 100644
index 0000000..5fd5bea
--- /dev/null
+++ b/test/Transforms/PlaceSafepoints/invokes.ll
@@ -0,0 +1,110 @@
+; RUN: opt %s -S -place-safepoints | FileCheck %s
+
+declare i64 addrspace(1)* @"some_call"(i64 addrspace(1)*)
+declare i32 @"personality_function"()
+
+define i64 addrspace(1)* @test_basic(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
+; CHECK-LABEL: entry:
+entry:
+ ; CHECK: invoke
+ ; CHECK: statepoint
+ ; CHECK: some_call
+ %ret_val = invoke i64 addrspace(1)* @"some_call"(i64 addrspace(1)* %obj)
+ to label %normal_return unwind label %exceptional_return
+
+; CHECK-LABEL: normal_return:
+; CHECK: gc.result
+; CHECK: ret i64
+
+normal_return:
+ ret i64 addrspace(1)* %ret_val
+
+; CHECK-LABEL: exceptional_return:
+; CHECK: landingpad
+; CHECK: ret i64
+
+exceptional_return:
+ %landing_pad4 = landingpad {i8*, i32} personality i32 ()* @"personality_function"
+ cleanup
+ ret i64 addrspace(1)* %obj1
+}
+
+define i64 addrspace(1)* @test_two_invokes(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
+; CHECK-LABEL: entry:
+entry:
+ ; CHECK: invoke
+ ; CHECK: statepoint
+ ; CHECK: some_call
+ %ret_val1 = invoke i64 addrspace(1)* @"some_call"(i64 addrspace(1)* %obj)
+ to label %second_invoke unwind label %exceptional_return
+
+; CHECK-LABEL: second_invoke:
+second_invoke:
+ ; CHECK: invoke
+ ; CHECK: statepoint
+ ; CHECK: some_call
+ %ret_val2 = invoke i64 addrspace(1)* @"some_call"(i64 addrspace(1)* %ret_val1)
+ to label %normal_return unwind label %exceptional_return
+
+; CHECK-LABEL: normal_return:
+normal_return:
+ ; CHECK: gc.result
+ ; CHECK: ret i64
+ ret i64 addrspace(1)* %ret_val2
+
+; CHECK: exceptional_return:
+; CHECK: ret i64
+
+exceptional_return:
+ %landing_pad4 = landingpad {i8*, i32} personality i32 ()* @"personality_function"
+ cleanup
+ ret i64 addrspace(1)* %obj1
+}
+
+define i64 addrspace(1)* @test_phi_node(i1 %cond, i64 addrspace(1)* %obj) gc "statepoint-example" {
+; CHECK-LABEL: entry:
+entry:
+ br i1 %cond, label %left, label %right
+
+left:
+ %ret_val_left = invoke i64 addrspace(1)* @"some_call"(i64 addrspace(1)* %obj)
+ to label %merge unwind label %exceptional_return
+
+right:
+ %ret_val_right = invoke i64 addrspace(1)* @"some_call"(i64 addrspace(1)* %obj)
+ to label %merge unwind label %exceptional_return
+
+; CHECK-LABEL: merge1:
+; CHECK: gc.result
+; CHECK: br label %merge
+
+; CHECK-LABEL: merge3:
+; CHECK: gc.result
+; CHECK: br label %merge
+
+; CHECK-LABEL: merge:
+; CHECK: phi
+; CHECK: ret i64 addrspace(1)* %ret_val
+merge:
+ %ret_val = phi i64 addrspace(1)* [%ret_val_left, %left], [%ret_val_right, %right]
+ ret i64 addrspace(1)* %ret_val
+
+; CHECK-LABEL: exceptional_return:
+; CHECK: ret i64 addrspace(1)*
+
+exceptional_return:
+ %landing_pad4 = landingpad {i8*, i32} personality i32 ()* @"personality_function"
+ cleanup
+ ret i64 addrspace(1)* %obj
+}
+
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+; CHECK-LABEL: gc.safepoint_poll
+; CHECK-LABEL: entry
+; CHECK-NEXT: do_safepoint
+; CHECK-NEXT: ret void
+entry:
+ call void @do_safepoint()
+ ret void
+}
diff --git a/test/Transforms/PlaceSafepoints/split-backedge.ll b/test/Transforms/PlaceSafepoints/split-backedge.ll
new file mode 100644
index 0000000..176b54f
--- /dev/null
+++ b/test/Transforms/PlaceSafepoints/split-backedge.ll
@@ -0,0 +1,46 @@
+;; A very basic test to make sure that splitting the backedge keeps working
+;; RUN: opt -place-safepoints -spp-split-backedge=1 -S %s | FileCheck %s
+
+define void @test(i32, i1 %cond) gc "statepoint-example" {
+; CHECK-LABEL: @test
+; CHECK-LABEL: loop.loop_crit_edge
+; CHECK: gc.statepoint
+; CHECK-NEXT: br label %loop
+entry:
+ br label %loop
+
+loop:
+ br i1 %cond, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+; Test for the case where a single conditional branch jumps to two
+; different loop header blocks. Since we're currently using LoopSimplfy
+; this doesn't hit the interesting case, but once we remove that, we need
+; to be sure this keeps working.
+define void @test2(i32, i1 %cond) gc "statepoint-example" {
+; CHECK-LABEL: @test2
+; CHECK-LABE: loop.loopexit.split
+; CHECK: gc.statepoint
+; CHECK-NEXT: br label %loop
+; CHECK-LABEL: loop2.loop2_crit_edge
+; CHECK: gc.statepoint
+; CHECK-NEXT: br label %loop2
+entry:
+ br label %loop
+
+loop:
+ br label %loop2
+
+loop2:
+ br i1 %cond, label %loop, label %loop2
+}
+
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+entry:
+ call void @do_safepoint()
+ ret void
+}
diff --git a/test/Transforms/PruneEH/2003-11-21-PHIUpdate.ll b/test/Transforms/PruneEH/2003-11-21-PHIUpdate.ll
deleted file mode 100644
index a010703..0000000
--- a/test/Transforms/PruneEH/2003-11-21-PHIUpdate.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt < %s -prune-eh -disable-output
-
-define internal void @callee() {
- ret void
-}
-
-define i32 @caller() {
-; <label>:0
- invoke void @callee( )
- to label %E unwind label %E
-E: ; preds = %0, %0
- %X = phi i32 [ 0, %0 ], [ 0, %0 ] ; <i32> [#uses=1]
- ret i32 %X
-}
-
diff --git a/test/Transforms/PruneEH/recursivetest.ll b/test/Transforms/PruneEH/recursivetest.ll
index 724c7cf..bc002ae 100644
--- a/test/Transforms/PruneEH/recursivetest.ll
+++ b/test/Transforms/PruneEH/recursivetest.ll
@@ -6,6 +6,8 @@ define internal i32 @foo() {
Normal: ; preds = %0
ret i32 12
Except: ; preds = %0
+ landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
ret i32 123
}
@@ -15,6 +17,9 @@ define i32 @caller() {
Normal: ; preds = %0
ret i32 0
Except: ; preds = %0
+ landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
ret i32 1
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/PruneEH/seh-nounwind.ll b/test/Transforms/PruneEH/seh-nounwind.ll
new file mode 100644
index 0000000..4b69ae4
--- /dev/null
+++ b/test/Transforms/PruneEH/seh-nounwind.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -prune-eh < %s | FileCheck %s
+
+; Don't remove invokes of nounwind functions if the personality handles async
+; exceptions. The @div function in this test can fault, even though it can't
+; throw a synchronous exception.
+
+define i32 @div(i32 %n, i32 %d) nounwind {
+entry:
+ %div = sdiv i32 %n, %d
+ ret i32 %div
+}
+
+define i32 @main() nounwind {
+entry:
+ %call = invoke i32 @div(i32 10, i32 0)
+ to label %__try.cont unwind label %lpad
+
+lpad:
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+ catch i8* null
+ br label %__try.cont
+
+__try.cont:
+ %retval.0 = phi i32 [ %call, %entry ], [ 0, %lpad ]
+ ret i32 %retval.0
+}
+
+; CHECK-LABEL: define i32 @main()
+; CHECK: invoke i32 @div(i32 10, i32 0)
+
+declare i32 @__C_specific_handler(...)
diff --git a/test/Transforms/PruneEH/simpletest.ll b/test/Transforms/PruneEH/simpletest.ll
index 77c429d..6154a80 100644
--- a/test/Transforms/PruneEH/simpletest.ll
+++ b/test/Transforms/PruneEH/simpletest.ll
@@ -15,5 +15,9 @@ Normal: ; preds = %0
ret i32 0
Except: ; preds = %0
+ landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
ret i32 1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Reassociate/crash2.ll b/test/Transforms/Reassociate/crash2.ll
new file mode 100644
index 0000000..b51a88c
--- /dev/null
+++ b/test/Transforms/Reassociate/crash2.ll
@@ -0,0 +1,25 @@
+; RUN: opt -reassociate %s -S -o - | FileCheck %s
+
+; Reassociate pass used to crash on these example
+
+
+define float @undef1() {
+wrapper_entry:
+; CHECK-LABEL: @undef1
+; CHECK: ret float fadd (float undef, float fadd (float undef, float fadd (float fsub (float -0.000000e+00, float undef), float fsub (float -0.000000e+00, float undef))))
+ %0 = fadd fast float undef, undef
+ %1 = fsub fast float undef, %0
+ %2 = fadd fast float undef, %1
+ ret float %2
+}
+
+define void @undef2() {
+wrapper_entry:
+; CHECK-LABEL: @undef2
+; CHECK: unreachable
+ %0 = fadd fast float undef, undef
+ %1 = fadd fast float %0, 1.000000e+00
+ %2 = fsub fast float %0, %1
+ %3 = fmul fast float %2, 2.000000e+00
+ unreachable
+}
diff --git a/test/Transforms/Reassociate/min_int.ll b/test/Transforms/Reassociate/min_int.ll
new file mode 100644
index 0000000..52dab3a
--- /dev/null
+++ b/test/Transforms/Reassociate/min_int.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -reassociate -dce -S | FileCheck %s
+
+; MIN_INT cannot be negated during reassociation
+
+define i32 @minint(i32 %i) {
+; CHECK: %mul = mul i32 %i, -2147483648
+; CHECK-NEXT: %add = add i32 %mul, 1
+; CHECK-NEXT: ret i32 %add
+ %mul = mul i32 %i, -2147483648
+ %add = add i32 %mul, 1
+ ret i32 %add
+}
+
diff --git a/test/Transforms/RewriteStatepointsForGC/basics.ll b/test/Transforms/RewriteStatepointsForGC/basics.ll
new file mode 100644
index 0000000..ec522ab
--- /dev/null
+++ b/test/Transforms/RewriteStatepointsForGC/basics.ll
@@ -0,0 +1,88 @@
+; This is a collection of really basic tests for gc.statepoint rewriting.
+; RUN: opt %s -rewrite-statepoints-for-gc -S | FileCheck %s
+
+declare void @foo()
+
+; Trivial relocation over a single call
+define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj) gc "statepoint-example" {
+; CHECK-LABEL: @test1
+; CHECK-LABEL: entry:
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+entry:
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+ ret i8 addrspace(1)* %obj
+}
+
+; Two safepoints in a row (i.e. consistent liveness)
+define i8 addrspace(1)* @test2(i8 addrspace(1)* %obj) gc "statepoint-example" {
+; CHECK-LABEL: @test2
+; CHECK-LABEL: entry:
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
+entry:
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+ ret i8 addrspace(1)* %obj
+}
+
+; A simple derived pointer
+define i8 @test3(i8 addrspace(1)* %obj) gc "statepoint-example" {
+; CHECK-LABEL: entry:
+; CHECK-NEXT: getelementptr
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: %derived.relocated = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: load i8 addrspace(1)* %derived.relocated
+; CHECK-NEXT: load i8 addrspace(1)* %obj.relocated
+entry:
+ %derived = getelementptr i8 addrspace(1)* %obj, i64 10
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+
+ %a = load i8 addrspace(1)* %derived
+ %b = load i8 addrspace(1)* %obj
+ %c = sub i8 %a, %b
+ ret i8 %c
+}
+
+; Tests to make sure we visit both the taken and untaken predeccessor
+; of merge. This was a bug in the dataflow liveness at one point.
+define i8 addrspace(1)* @test4(i1 %cmp, i8 addrspace(1)* %obj) gc "statepoint-example" {
+entry:
+ br i1 %cmp, label %taken, label %untaken
+
+taken:
+; CHECK-LABEL: taken:
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+ br label %merge
+
+untaken:
+; CHECK-LABEL: untaken:
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+ br label %merge
+
+merge:
+; CHECK-LABEL: merge:
+; CHECK-NEXT: %.0 = phi i8 addrspace(1)* [ %obj.relocated, %taken ], [ %obj.relocated1, %untaken ]
+; CHECK-NEXT: ret i8 addrspace(1)* %.0
+ ret i8 addrspace(1)* %obj
+}
+
+; When run over a function which doesn't opt in, should do nothing!
+define i8 addrspace(1)* @test5(i8 addrspace(1)* %obj) {
+; CHECK-LABEL: @test5
+; CHECK-LABEL: entry:
+; CHECK-NEXT: gc.statepoint
+; CHECK-NOT: %obj.relocated = call coldcc i8 addrspace(1)*
+entry:
+ call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
+ ret i8 addrspace(1)* %obj
+}
+
+declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
diff --git a/test/Transforms/SLPVectorizer/X86/addsub.ll b/test/Transforms/SLPVectorizer/X86/addsub.ll
index 174d400..d082b07 100644
--- a/test/Transforms/SLPVectorizer/X86/addsub.ll
+++ b/test/Transforms/SLPVectorizer/X86/addsub.ll
@@ -10,6 +10,7 @@ target triple = "x86_64-unknown-linux-gnu"
@fb = common global [4 x float] zeroinitializer, align 16
@fc = common global [4 x float] zeroinitializer, align 16
@fa = common global [4 x float] zeroinitializer, align 16
+@fd = common global [4 x float] zeroinitializer, align 16
; CHECK-LABEL: @addsub
; CHECK: %5 = add nsw <4 x i32> %3, %4
@@ -177,5 +178,137 @@ entry:
ret void
}
+; Check vectorization of following code for float data type-
+; fc[0] = fb[0]+fa[0]; //swapped fb and fa
+; fc[1] = fa[1]-fb[1];
+; fc[2] = fa[2]+fb[2];
+; fc[3] = fa[3]-fb[3];
+
+; CHECK-LABEL: @reorder_alt
+; CHECK: %3 = fadd <4 x float> %1, %2
+; CHECK: %4 = fsub <4 x float> %1, %2
+; CHECK: %5 = shufflevector <4 x float> %3, <4 x float> %4, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
+define void @reorder_alt() #0 {
+ %1 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 0), align 4
+ %2 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 0), align 4
+ %3 = fadd float %1, %2
+ store float %3, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 0), align 4
+ %4 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 1), align 4
+ %5 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 1), align 4
+ %6 = fsub float %4, %5
+ store float %6, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 1), align 4
+ %7 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 2), align 4
+ %8 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 2), align 4
+ %9 = fadd float %7, %8
+ store float %9, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 2), align 4
+ %10 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 3), align 4
+ %11 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 3), align 4
+ %12 = fsub float %10, %11
+ store float %12, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 3), align 4
+ ret void
+}
+
+; Check vectorization of following code for float data type-
+; fc[0] = fa[0]+(fb[0]-fd[0]);
+; fc[1] = fa[1]-(fb[1]+fd[1]);
+; fc[2] = fa[2]+(fb[2]-fd[2]);
+; fc[3] = fa[3]-(fd[3]+fb[3]); //swapped fd and fb
+
+; CHECK-LABEL: @reorder_alt_subTree
+; CHECK: %4 = fsub <4 x float> %3, %2
+; CHECK: %5 = fadd <4 x float> %3, %2
+; CHECK: %6 = shufflevector <4 x float> %4, <4 x float> %5, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
+; CHECK: %7 = fadd <4 x float> %1, %6
+; CHECK: %8 = fsub <4 x float> %1, %6
+; CHECK: %9 = shufflevector <4 x float> %7, <4 x float> %8, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
+define void @reorder_alt_subTree() #0 {
+ %1 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 0), align 4
+ %2 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 0), align 4
+ %3 = load float* getelementptr inbounds ([4 x float]* @fd, i32 0, i64 0), align 4
+ %4 = fsub float %2, %3
+ %5 = fadd float %1, %4
+ store float %5, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 0), align 4
+ %6 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 1), align 4
+ %7 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 1), align 4
+ %8 = load float* getelementptr inbounds ([4 x float]* @fd, i32 0, i64 1), align 4
+ %9 = fadd float %7, %8
+ %10 = fsub float %6, %9
+ store float %10, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 1), align 4
+ %11 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 2), align 4
+ %12 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 2), align 4
+ %13 = load float* getelementptr inbounds ([4 x float]* @fd, i32 0, i64 2), align 4
+ %14 = fsub float %12, %13
+ %15 = fadd float %11, %14
+ store float %15, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 2), align 4
+ %16 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 3), align 4
+ %17 = load float* getelementptr inbounds ([4 x float]* @fd, i32 0, i64 3), align 4
+ %18 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 3), align 4
+ %19 = fadd float %17, %18
+ %20 = fsub float %16, %19
+ store float %20, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 3), align 4
+ ret void
+}
+
+; Check vectorization of following code for double data type-
+; c[0] = (a[0]+b[0])-d[0];
+; c[1] = d[1]+(a[1]+b[1]); //swapped d[1] and (a[1]+b[1])
+
+; CHECK-LABEL: @reorder_alt_rightsubTree
+; CHECK: fadd <2 x double>
+; CHECK: fsub <2 x double>
+; CHECK: shufflevector <2 x double>
+define void @reorder_alt_rightsubTree(double* nocapture %c, double* noalias nocapture readonly %a, double* noalias nocapture readonly %b, double* noalias nocapture readonly %d) {
+ %1 = load double* %a
+ %2 = load double* %b
+ %3 = fadd double %1, %2
+ %4 = load double* %d
+ %5 = fsub double %3, %4
+ store double %5, double* %c
+ %6 = getelementptr inbounds double* %d, i64 1
+ %7 = load double* %6
+ %8 = getelementptr inbounds double* %a, i64 1
+ %9 = load double* %8
+ %10 = getelementptr inbounds double* %b, i64 1
+ %11 = load double* %10
+ %12 = fadd double %9, %11
+ %13 = fadd double %7, %12
+ %14 = getelementptr inbounds double* %c, i64 1
+ store double %13, double* %14
+ ret void
+}
+
+; Dont vectorization of following code for float data type as sub is not commutative-
+; fc[0] = fb[0]+fa[0];
+; fc[1] = fa[1]-fb[1];
+; fc[2] = fa[2]+fb[2];
+; fc[3] = fb[3]-fa[3];
+; In the above code we can swap the 1st and 2nd operation as fadd is commutative
+; but not 2nd or 4th as fsub is not commutative.
+
+; CHECK-LABEL: @no_vec_shuff_reorder
+; CHECK-NOT: fadd <4 x float>
+; CHECK-NOT: fsub <4 x float>
+; CHECK-NOT: shufflevector
+define void @no_vec_shuff_reorder() #0 {
+ %1 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 0), align 4
+ %2 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 0), align 4
+ %3 = fadd float %1, %2
+ store float %3, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 0), align 4
+ %4 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 1), align 4
+ %5 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 1), align 4
+ %6 = fsub float %4, %5
+ store float %6, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 1), align 4
+ %7 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 2), align 4
+ %8 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 2), align 4
+ %9 = fadd float %7, %8
+ store float %9, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 2), align 4
+ %10 = load float* getelementptr inbounds ([4 x float]* @fb, i32 0, i64 3), align 4
+ %11 = load float* getelementptr inbounds ([4 x float]* @fa, i32 0, i64 3), align 4
+ %12 = fsub float %10, %11
+ store float %12, float* getelementptr inbounds ([4 x float]* @fc, i32 0, i64 3), align 4
+ ret void
+}
+
+
attributes #0 = { nounwind }
diff --git a/test/Transforms/SLPVectorizer/X86/atomics.ll b/test/Transforms/SLPVectorizer/X86/atomics.ll
new file mode 100644
index 0000000..6cb322e
--- /dev/null
+++ b/test/Transforms/SLPVectorizer/X86/atomics.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -basicaa -slp-vectorizer -S |FileCheck %s
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+@x = global [4 x i32] zeroinitializer, align 16
+@a = global [4 x i32] zeroinitializer, align 16
+
+; The SLPVectorizer should not vectorize atomic stores and it should not
+; schedule regular stores around atomic stores.
+
+; CHECK-LABEL: test
+; CHECK: store i32
+; CHECK: store atomic i32
+; CHECK: store i32
+; CHECK: store atomic i32
+; CHECK: store i32
+; CHECK: store atomic i32
+; CHECK: store i32
+; CHECK: store atomic i32
+define void @test() {
+entry:
+ store i32 0, i32* getelementptr inbounds ([4 x i32]* @a, i64 0, i64 0), align 16
+ store atomic i32 0, i32* getelementptr inbounds ([4 x i32]* @x, i64 0, i64 0) release, align 16
+ store i32 0, i32* getelementptr inbounds ([4 x i32]* @a, i64 0, i64 1), align 4
+ store atomic i32 1, i32* getelementptr inbounds ([4 x i32]* @x, i64 0, i64 1) release, align 4
+ store i32 0, i32* getelementptr inbounds ([4 x i32]* @a, i64 0, i64 2), align 8
+ store atomic i32 2, i32* getelementptr inbounds ([4 x i32]* @x, i64 0, i64 2) release, align 8
+ store i32 0, i32* getelementptr inbounds ([4 x i32]* @a, i64 0, i64 3), align 4
+ store atomic i32 3, i32* getelementptr inbounds ([4 x i32]* @x, i64 0, i64 3) release, align 4
+ ret void
+}
+
diff --git a/test/Transforms/SLPVectorizer/X86/bad_types.ll b/test/Transforms/SLPVectorizer/X86/bad_types.ll
new file mode 100644
index 0000000..38ed18d
--- /dev/null
+++ b/test/Transforms/SLPVectorizer/X86/bad_types.ll
@@ -0,0 +1,50 @@
+; RUN: opt < %s -basicaa -slp-vectorizer -S -mcpu=corei7-avx | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @test1(x86_mmx %a, x86_mmx %b, i64* %ptr) {
+; Ensure we can handle x86_mmx values which are primitive and can be bitcast
+; with integer types but can't be put into a vector.
+;
+; CHECK-LABEL: @test1
+; CHECK: store i64
+; CHECK: store i64
+; CHECK: ret void
+entry:
+ %a.cast = bitcast x86_mmx %a to i64
+ %b.cast = bitcast x86_mmx %b to i64
+ %a.and = and i64 %a.cast, 42
+ %b.and = and i64 %b.cast, 42
+ %gep = getelementptr i64* %ptr, i32 1
+ store i64 %a.and, i64* %ptr
+ store i64 %b.and, i64* %gep
+ ret void
+}
+
+define void @test2(x86_mmx %a, x86_mmx %b) {
+; Same as @test1 but using phi-input vectorization instead of store
+; vectorization.
+;
+; CHECK-LABEL: @test2
+; CHECK: and i64
+; CHECK: and i64
+; CHECK: ret void
+entry:
+ br i1 undef, label %if.then, label %exit
+
+if.then:
+ %a.cast = bitcast x86_mmx %a to i64
+ %b.cast = bitcast x86_mmx %b to i64
+ %a.and = and i64 %a.cast, 42
+ %b.and = and i64 %b.cast, 42
+ br label %exit
+
+exit:
+ %a.phi = phi i64 [ 0, %entry ], [ %a.and, %if.then ]
+ %b.phi = phi i64 [ 0, %entry ], [ %b.and, %if.then ]
+ tail call void @f(i64 %a.phi, i64 %b.phi)
+ ret void
+}
+
+declare void @f(i64, i64)
diff --git a/test/Transforms/SLPVectorizer/X86/consecutive-access.ll b/test/Transforms/SLPVectorizer/X86/consecutive-access.ll
index f4f112f..aa59429 100644
--- a/test/Transforms/SLPVectorizer/X86/consecutive-access.ll
+++ b/test/Transforms/SLPVectorizer/X86/consecutive-access.ll
@@ -172,4 +172,4 @@ attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-po
!llvm.ident = !{!0}
-!0 = metadata !{metadata !"clang version 3.5.0 "}
+!0 = !{!"clang version 3.5.0 "}
diff --git a/test/Transforms/SLPVectorizer/X86/crash_cmpop.ll b/test/Transforms/SLPVectorizer/X86/crash_cmpop.ll
new file mode 100644
index 0000000..18a96e5
--- /dev/null
+++ b/test/Transforms/SLPVectorizer/X86/crash_cmpop.ll
@@ -0,0 +1,56 @@
+; RUN: opt < %s -basicaa -slp-vectorizer -S
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+define void @testfunc(float* nocapture %dest, float* nocapture readonly %src) {
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %acc1.056 = phi float [ 0.000000e+00, %entry ], [ %add13, %for.body ]
+ %s1.055 = phi float [ 0.000000e+00, %entry ], [ %cond.i40, %for.body ]
+ %s0.054 = phi float [ 0.000000e+00, %entry ], [ %cond.i44, %for.body ]
+ %arrayidx = getelementptr inbounds float* %src, i64 %indvars.iv
+ %0 = load float* %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %arrayidx2 = getelementptr inbounds float* %dest, i64 %indvars.iv
+ store float %acc1.056, float* %arrayidx2, align 4
+ %add = fadd float %s0.054, %0
+ %add3 = fadd float %s1.055, %0
+ %mul = fmul float %s0.054, 0.000000e+00
+ %add4 = fadd float %mul, %add3
+ %mul5 = fmul float %s1.055, 0.000000e+00
+ %add6 = fadd float %mul5, %add
+ %cmp.i = fcmp olt float %add6, 1.000000e+00
+ %cond.i = select i1 %cmp.i, float %add6, float 1.000000e+00
+ %cmp.i51 = fcmp olt float %cond.i, -1.000000e+00
+ %cmp.i49 = fcmp olt float %add4, 1.000000e+00
+ %cond.i50 = select i1 %cmp.i49, float %add4, float 1.000000e+00
+ %cmp.i47 = fcmp olt float %cond.i50, -1.000000e+00
+ %cond.i.op = fmul float %cond.i, 0.000000e+00
+ %mul10 = select i1 %cmp.i51, float -0.000000e+00, float %cond.i.op
+ %cond.i50.op = fmul float %cond.i50, 0.000000e+00
+ %mul11 = select i1 %cmp.i47, float -0.000000e+00, float %cond.i50.op
+ %add13 = fadd float %mul10, %mul11
+
+ ; The SLPVectorizer crashed in vectorizeChainsInBlock() because it tried
+ ; to access the second operand of the following cmp after the cmp itself
+ ; was already vectorized and deleted.
+ %cmp.i45 = fcmp olt float %add13, 1.000000e+00
+
+ %cond.i46 = select i1 %cmp.i45, float %add13, float 1.000000e+00
+ %cmp.i43 = fcmp olt float %cond.i46, -1.000000e+00
+ %cond.i44 = select i1 %cmp.i43, float -1.000000e+00, float %cond.i46
+ %cmp.i41 = fcmp olt float %mul11, 1.000000e+00
+ %cond.i42 = select i1 %cmp.i41, float %mul11, float 1.000000e+00
+ %cmp.i39 = fcmp olt float %cond.i42, -1.000000e+00
+ %cond.i40 = select i1 %cmp.i39, float -1.000000e+00, float %cond.i42
+ %exitcond = icmp eq i64 %indvars.iv.next, 32
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
diff --git a/test/Transforms/SLPVectorizer/X86/crash_scheduling.ll b/test/Transforms/SLPVectorizer/X86/crash_scheduling.ll
index dddc1be..e6cc0f7 100644
--- a/test/Transforms/SLPVectorizer/X86/crash_scheduling.ll
+++ b/test/Transforms/SLPVectorizer/X86/crash_scheduling.ll
@@ -43,5 +43,5 @@ return:
declare i32 @_xfn(<2 x double>) #4
-!3 = metadata !{metadata !"int", metadata !4, i64 0}
-!4 = metadata !{metadata !3, metadata !3, i64 0}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!3, !3, i64 0}
diff --git a/test/Transforms/SLPVectorizer/X86/debug_info.ll b/test/Transforms/SLPVectorizer/X86/debug_info.ll
index 1046087..21f51d7 100644
--- a/test/Transforms/SLPVectorizer/X86/debug_info.ll
+++ b/test/Transforms/SLPVectorizer/X86/debug_info.ll
@@ -18,16 +18,16 @@ target triple = "x86_64-apple-macosx10.7.0"
;CHECK: load <2 x double>* {{.*}}, !dbg ![[LOC]]
;CHECK: store <2 x double> {{.*}}, !dbg ![[LOC2:[0-9]+]]
;CHECK: ret
-;CHECK: ![[LOC]] = metadata !{i32 4, i32 0,
-;CHECK: ![[LOC2]] = metadata !{i32 7, i32 0,
+;CHECK: ![[LOC]] = !MDLocation(line: 4, scope:
+;CHECK: ![[LOC2]] = !MDLocation(line: 7, scope:
define i32 @depth(double* nocapture %A, i32 %m) #0 {
entry:
- tail call void @llvm.dbg.value(metadata !{double* %A}, i64 0, metadata !12, metadata !{}), !dbg !19
- tail call void @llvm.dbg.value(metadata !{i32 %m}, i64 0, metadata !13, metadata !{}), !dbg !19
- tail call void @llvm.dbg.value(metadata !20, i64 0, metadata !14, metadata !{}), !dbg !21
- tail call void @llvm.dbg.value(metadata !22, i64 0, metadata !15, metadata !{}), !dbg !21
- tail call void @llvm.dbg.value(metadata !2, i64 0, metadata !16, metadata !{}), !dbg !23
+ tail call void @llvm.dbg.value(metadata double* %A, i64 0, metadata !12, metadata !{}), !dbg !19
+ tail call void @llvm.dbg.value(metadata i32 %m, i64 0, metadata !13, metadata !{}), !dbg !19
+ tail call void @llvm.dbg.value(metadata i32 00, i64 0, metadata !14, metadata !{}), !dbg !21
+ tail call void @llvm.dbg.value(metadata i32 02, i64 0, metadata !15, metadata !{}), !dbg !21
+ tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !16, metadata !{}), !dbg !23
%cmp8 = icmp sgt i32 %m, 0, !dbg !23
br i1 %cmp8, label %for.body.lr.ph, label %for.end, !dbg !23
@@ -57,33 +57,33 @@ attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!18, !32}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.4 (trunk 187335) (llvm/trunk 187335:187340M)\001\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/Users/nadav/file.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"file.c", metadata !"/Users/nadav"}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00depth\00depth\00\001\000\001\000\006\00256\001\001", metadata !1, metadata !5, metadata !6, null, i32 (double*, i32)* @depth, null, null, metadata !11} ; [ DW_TAG_subprogram ] [line 1] [def] [depth]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/Users/nadav/file.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !8, metadata !9, metadata !8}
-!8 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!9 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from double]
-!10 = metadata !{metadata !"0x24\00double\000\0064\0064\000\000\004", null, null} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
-!11 = metadata !{metadata !12, metadata !13, metadata !14, metadata !15, metadata !16}
-!12 = metadata !{metadata !"0x101\00A\0016777217\000", metadata !4, metadata !5, metadata !9} ; [ DW_TAG_arg_variable ] [A] [line 1]
-!13 = metadata !{metadata !"0x101\00m\0033554433\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [m] [line 1]
-!14 = metadata !{metadata !"0x100\00y0\002\000", metadata !4, metadata !5, metadata !10} ; [ DW_TAG_auto_variable ] [y0] [line 2]
-!15 = metadata !{metadata !"0x100\00y1\002\000", metadata !4, metadata !5, metadata !10} ; [ DW_TAG_auto_variable ] [y1] [line 2]
-!16 = metadata !{metadata !"0x100\00i\003\000", metadata !17, metadata !5, metadata !8} ; [ DW_TAG_auto_variable ] [i] [line 3]
-!17 = metadata !{metadata !"0xb\003\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [/Users/nadav/file.c]
-!18 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
-!19 = metadata !{i32 1, i32 0, metadata !4, null}
-!20 = metadata !{double 0.000000e+00}
-!21 = metadata !{i32 2, i32 0, metadata !4, null}
-!22 = metadata !{double 1.000000e+00}
-!23 = metadata !{i32 3, i32 0, metadata !17, null}
-!24 = metadata !{i32 4, i32 0, metadata !25, null}
-!25 = metadata !{metadata !"0xb\003\000\001", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ] [/Users/nadav/file.c]
-!29 = metadata !{i32 5, i32 0, metadata !25, null}
-!30 = metadata !{i32 7, i32 0, metadata !4, null}
-!31 = metadata !{i32 8, i32 0, metadata !4, null}
-!32 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\0012\00clang version 3.4 (trunk 187335) (llvm/trunk 187335:187340M)\001\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/Users/nadav/file.c] [DW_LANG_C99]
+!1 = !{!"file.c", !"/Users/nadav"}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00depth\00depth\00\001\000\001\000\006\00256\001\001", !1, !5, !6, null, i32 (double*, i32)* @depth, null, null, !11} ; [ DW_TAG_subprogram ] [line 1] [def] [depth]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/Users/nadav/file.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!8, !9, !8}
+!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!9 = !{!"0xf\00\000\0064\0064\000\000", null, null, !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from double]
+!10 = !{!"0x24\00double\000\0064\0064\000\000\004", null, null} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
+!11 = !{!12, !13, !14, !15, !16}
+!12 = !{!"0x101\00A\0016777217\000", !4, !5, !9} ; [ DW_TAG_arg_variable ] [A] [line 1]
+!13 = !{!"0x101\00m\0033554433\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [m] [line 1]
+!14 = !{!"0x100\00y0\002\000", !4, !5, !10} ; [ DW_TAG_auto_variable ] [y0] [line 2]
+!15 = !{!"0x100\00y1\002\000", !4, !5, !10} ; [ DW_TAG_auto_variable ] [y1] [line 2]
+!16 = !{!"0x100\00i\003\000", !17, !5, !8} ; [ DW_TAG_auto_variable ] [i] [line 3]
+!17 = !{!"0xb\003\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [/Users/nadav/file.c]
+!18 = !{i32 2, !"Dwarf Version", i32 2}
+!19 = !MDLocation(line: 1, scope: !4)
+!20 = !{double 0.000000e+00}
+!21 = !MDLocation(line: 2, scope: !4)
+!22 = !{double 1.000000e+00}
+!23 = !MDLocation(line: 3, scope: !17)
+!24 = !MDLocation(line: 4, scope: !25)
+!25 = !{!"0xb\003\000\001", !1, !17} ; [ DW_TAG_lexical_block ] [/Users/nadav/file.c]
+!29 = !MDLocation(line: 5, scope: !25)
+!30 = !MDLocation(line: 7, scope: !4)
+!31 = !MDLocation(line: 8, scope: !4)
+!32 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SLPVectorizer/X86/metadata.ll b/test/Transforms/SLPVectorizer/X86/metadata.ll
index 5bd2fa4..e021cca 100644
--- a/test/Transforms/SLPVectorizer/X86/metadata.ll
+++ b/test/Transforms/SLPVectorizer/X86/metadata.ll
@@ -51,11 +51,11 @@ entry:
ret void
}
-;CHECK-DAG: ![[TBAA]] = metadata !{metadata [[TYPEC:!.*]], metadata [[TYPEC]], i64 0}
-;CHECK-DAG: ![[FP1]] = metadata !{float 5.000000e+00}
-;CHECK-DAG: ![[FP2]] = metadata !{float 2.500000e+00}
-!0 = metadata !{ float 5.0 }
-!1 = metadata !{ float 2.5 }
-!2 = metadata !{metadata !"Simple C/C++ TBAA"}
-!3 = metadata !{metadata !"omnipotent char", metadata !2}
-!4 = metadata !{metadata !"double", metadata !3}
+;CHECK-DAG: ![[TBAA]] = !{[[TYPEC:!.*]], [[TYPEC]], i64 0}
+;CHECK-DAG: ![[FP1]] = !{float 5.000000e+00}
+;CHECK-DAG: ![[FP2]] = !{float 2.500000e+00}
+!0 = !{ float 5.0 }
+!1 = !{ float 2.5 }
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"omnipotent char", !2}
+!4 = !{!"double", !3}
diff --git a/test/Transforms/SLPVectorizer/X86/operandorder.ll b/test/Transforms/SLPVectorizer/X86/operandorder.ll
index c5322a8..cd446f0 100644
--- a/test/Transforms/SLPVectorizer/X86/operandorder.ll
+++ b/test/Transforms/SLPVectorizer/X86/operandorder.ll
@@ -232,3 +232,113 @@ for.body3:
for.end:
ret void
}
+
+; Check vectorization of following code for double data type-
+; c[0] = a[0]+b[0];
+; c[1] = b[1]+a[1]; // swapped b[1] and a[1]
+
+; CHECK-LABEL: load_reorder_double
+; CHECK: load <2 x double>*
+; CHECK: fadd <2 x double>
+define void @load_reorder_double(double* nocapture %c, double* noalias nocapture readonly %a, double* noalias nocapture readonly %b){
+ %1 = load double* %a
+ %2 = load double* %b
+ %3 = fadd double %1, %2
+ store double %3, double* %c
+ %4 = getelementptr inbounds double* %b, i64 1
+ %5 = load double* %4
+ %6 = getelementptr inbounds double* %a, i64 1
+ %7 = load double* %6
+ %8 = fadd double %5, %7
+ %9 = getelementptr inbounds double* %c, i64 1
+ store double %8, double* %9
+ ret void
+}
+
+; Check vectorization of following code for float data type-
+; c[0] = a[0]+b[0];
+; c[1] = b[1]+a[1]; // swapped b[1] and a[1]
+; c[2] = a[2]+b[2];
+; c[3] = a[3]+b[3];
+
+; CHECK-LABEL: load_reorder_float
+; CHECK: load <4 x float>*
+; CHECK: fadd <4 x float>
+define void @load_reorder_float(float* nocapture %c, float* noalias nocapture readonly %a, float* noalias nocapture readonly %b){
+ %1 = load float* %a
+ %2 = load float* %b
+ %3 = fadd float %1, %2
+ store float %3, float* %c
+ %4 = getelementptr inbounds float* %b, i64 1
+ %5 = load float* %4
+ %6 = getelementptr inbounds float* %a, i64 1
+ %7 = load float* %6
+ %8 = fadd float %5, %7
+ %9 = getelementptr inbounds float* %c, i64 1
+ store float %8, float* %9
+ %10 = getelementptr inbounds float* %a, i64 2
+ %11 = load float* %10
+ %12 = getelementptr inbounds float* %b, i64 2
+ %13 = load float* %12
+ %14 = fadd float %11, %13
+ %15 = getelementptr inbounds float* %c, i64 2
+ store float %14, float* %15
+ %16 = getelementptr inbounds float* %a, i64 3
+ %17 = load float* %16
+ %18 = getelementptr inbounds float* %b, i64 3
+ %19 = load float* %18
+ %20 = fadd float %17, %19
+ %21 = getelementptr inbounds float* %c, i64 3
+ store float %20, float* %21
+ ret void
+}
+
+; Check we properly reorder the below code so that it gets vectorized optimally-
+; a[0] = (b[0]+c[0])+d[0];
+; a[1] = d[1]+(b[1]+c[1]);
+; a[2] = (b[2]+c[2])+d[2];
+; a[3] = (b[3]+c[3])+d[3];
+
+; CHECK-LABEL: opcode_reorder
+; CHECK: load <4 x float>*
+; CHECK: fadd <4 x float>
+define void @opcode_reorder(float* noalias nocapture %a, float* noalias nocapture readonly %b,
+ float* noalias nocapture readonly %c,float* noalias nocapture readonly %d){
+ %1 = load float* %b
+ %2 = load float* %c
+ %3 = fadd float %1, %2
+ %4 = load float* %d
+ %5 = fadd float %3, %4
+ store float %5, float* %a
+ %6 = getelementptr inbounds float* %d, i64 1
+ %7 = load float* %6
+ %8 = getelementptr inbounds float* %b, i64 1
+ %9 = load float* %8
+ %10 = getelementptr inbounds float* %c, i64 1
+ %11 = load float* %10
+ %12 = fadd float %9, %11
+ %13 = fadd float %7, %12
+ %14 = getelementptr inbounds float* %a, i64 1
+ store float %13, float* %14
+ %15 = getelementptr inbounds float* %b, i64 2
+ %16 = load float* %15
+ %17 = getelementptr inbounds float* %c, i64 2
+ %18 = load float* %17
+ %19 = fadd float %16, %18
+ %20 = getelementptr inbounds float* %d, i64 2
+ %21 = load float* %20
+ %22 = fadd float %19, %21
+ %23 = getelementptr inbounds float* %a, i64 2
+ store float %22, float* %23
+ %24 = getelementptr inbounds float* %b, i64 3
+ %25 = load float* %24
+ %26 = getelementptr inbounds float* %c, i64 3
+ %27 = load float* %26
+ %28 = fadd float %25, %27
+ %29 = getelementptr inbounds float* %d, i64 3
+ %30 = load float* %29
+ %31 = fadd float %28, %30
+ %32 = getelementptr inbounds float* %a, i64 3
+ store float %31, float* %32
+ ret void
+}
diff --git a/test/Transforms/SLPVectorizer/X86/pr16899.ll b/test/Transforms/SLPVectorizer/X86/pr16899.ll
index 8631bc9..c642f3c 100644
--- a/test/Transforms/SLPVectorizer/X86/pr16899.ll
+++ b/test/Transforms/SLPVectorizer/X86/pr16899.ll
@@ -23,9 +23,9 @@ do.body: ; preds = %do.body, %entry
attributes #0 = { noreturn nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!0 = metadata !{metadata !"any pointer", metadata !1}
-!1 = metadata !{metadata !"omnipotent char", metadata !2}
-!2 = metadata !{metadata !"Simple C/C++ TBAA"}
-!3 = metadata !{metadata !"int", metadata !1}
-!4 = metadata !{metadata !0, metadata !0, i64 0}
-!5 = metadata !{metadata !3, metadata !3, i64 0}
+!0 = !{!"any pointer", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"int", !1}
+!4 = !{!0, !0, i64 0}
+!5 = !{!3, !3, i64 0}
diff --git a/test/Transforms/SROA/alignment.ll b/test/Transforms/SROA/alignment.ll
index 5fa78766..4f4e40c 100644
--- a/test/Transforms/SROA/alignment.ll
+++ b/test/Transforms/SROA/alignment.ll
@@ -85,15 +85,18 @@ entry:
}
define void @test5() {
-; Test that we preserve underaligned loads and stores when splitting.
+; Test that we preserve underaligned loads and stores when splitting. The use
+; of volatile in this test case is just to force the loads and stores to not be
+; split or promoted out of existence.
+;
; CHECK-LABEL: @test5(
; CHECK: alloca [9 x i8]
; CHECK: alloca [9 x i8]
; CHECK: store volatile double 0.0{{.*}}, double* %{{.*}}, align 1
-; CHECK: load i16* %{{.*}}, align 1
+; CHECK: load volatile i16* %{{.*}}, align 1
; CHECK: load double* %{{.*}}, align 1
; CHECK: store volatile double %{{.*}}, double* %{{.*}}, align 1
-; CHECK: load i16* %{{.*}}, align 1
+; CHECK: load volatile i16* %{{.*}}, align 1
; CHECK: ret void
entry:
@@ -103,7 +106,7 @@ entry:
store volatile double 0.0, double* %ptr1, align 1
%weird_gep1 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 7
%weird_cast1 = bitcast i8* %weird_gep1 to i16*
- %weird_load1 = load i16* %weird_cast1, align 1
+ %weird_load1 = load volatile i16* %weird_cast1, align 1
%raw2 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 9
%ptr2 = bitcast i8* %raw2 to double*
@@ -111,7 +114,7 @@ entry:
store volatile double %d1, double* %ptr2, align 1
%weird_gep2 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 16
%weird_cast2 = bitcast i8* %weird_gep2 to i16*
- %weird_load2 = load i16* %weird_cast2, align 1
+ %weird_load2 = load volatile i16* %weird_cast2, align 1
ret void
}
diff --git a/test/Transforms/SROA/basictest.ll b/test/Transforms/SROA/basictest.ll
index dc2b165..e3f762a 100644
--- a/test/Transforms/SROA/basictest.ll
+++ b/test/Transforms/SROA/basictest.ll
@@ -1440,3 +1440,158 @@ entry:
ret void
}
+define float @test25() {
+; Check that we split up stores in order to promote the smaller SSA values.. These types
+; of patterns can arise because LLVM maps small memcpy's to integer load and
+; stores. If we get a memcpy of an aggregate (such as C and C++ frontends would
+; produce, but so might any language frontend), this will in many cases turn into
+; an integer load and store. SROA needs to be extremely powerful to correctly
+; handle these cases and form splitable and promotable SSA values.
+;
+; CHECK-LABEL: @test25(
+; CHECK-NOT: alloca
+; CHECK: %[[F1:.*]] = bitcast i32 0 to float
+; CHECK: %[[F2:.*]] = bitcast i32 1065353216 to float
+; CHECK: %[[SUM:.*]] = fadd float %[[F1]], %[[F2]]
+; CHECK: ret float %[[SUM]]
+
+entry:
+ %a = alloca i64
+ %b = alloca i64
+ %a.cast = bitcast i64* %a to [2 x float]*
+ %a.gep1 = getelementptr [2 x float]* %a.cast, i32 0, i32 0
+ %a.gep2 = getelementptr [2 x float]* %a.cast, i32 0, i32 1
+ %b.cast = bitcast i64* %b to [2 x float]*
+ %b.gep1 = getelementptr [2 x float]* %b.cast, i32 0, i32 0
+ %b.gep2 = getelementptr [2 x float]* %b.cast, i32 0, i32 1
+ store float 0.0, float* %a.gep1
+ store float 1.0, float* %a.gep2
+ %v = load i64* %a
+ store i64 %v, i64* %b
+ %f1 = load float* %b.gep1
+ %f2 = load float* %b.gep2
+ %ret = fadd float %f1, %f2
+ ret float %ret
+}
+
+@complex1 = external global [2 x float]
+@complex2 = external global [2 x float]
+
+define void @test26() {
+; Test a case of splitting up loads and stores against a globals.
+;
+; CHECK-LABEL: @test26(
+; CHECK-NOT: alloca
+; CHECK: %[[L1:.*]] = load i32* bitcast
+; CHECK: %[[L2:.*]] = load i32* bitcast
+; CHECK: %[[F1:.*]] = bitcast i32 %[[L1]] to float
+; CHECK: %[[F2:.*]] = bitcast i32 %[[L2]] to float
+; CHECK: %[[SUM:.*]] = fadd float %[[F1]], %[[F2]]
+; CHECK: %[[C1:.*]] = bitcast float %[[SUM]] to i32
+; CHECK: %[[C2:.*]] = bitcast float %[[SUM]] to i32
+; CHECK: store i32 %[[C1]], i32* bitcast
+; CHECK: store i32 %[[C2]], i32* bitcast
+; CHECK: ret void
+
+entry:
+ %a = alloca i64
+ %a.cast = bitcast i64* %a to [2 x float]*
+ %a.gep1 = getelementptr [2 x float]* %a.cast, i32 0, i32 0
+ %a.gep2 = getelementptr [2 x float]* %a.cast, i32 0, i32 1
+ %v1 = load i64* bitcast ([2 x float]* @complex1 to i64*)
+ store i64 %v1, i64* %a
+ %f1 = load float* %a.gep1
+ %f2 = load float* %a.gep2
+ %sum = fadd float %f1, %f2
+ store float %sum, float* %a.gep1
+ store float %sum, float* %a.gep2
+ %v2 = load i64* %a
+ store i64 %v2, i64* bitcast ([2 x float]* @complex2 to i64*)
+ ret void
+}
+
+define float @test27() {
+; Another, more complex case of splittable i64 loads and stores. This example
+; is a particularly challenging one because the load and store both point into
+; the alloca SROA is processing, and they overlap but at an offset.
+;
+; CHECK-LABEL: @test27(
+; CHECK-NOT: alloca
+; CHECK: %[[F1:.*]] = bitcast i32 0 to float
+; CHECK: %[[F2:.*]] = bitcast i32 1065353216 to float
+; CHECK: %[[SUM:.*]] = fadd float %[[F1]], %[[F2]]
+; CHECK: ret float %[[SUM]]
+
+entry:
+ %a = alloca [12 x i8]
+ %gep1 = getelementptr [12 x i8]* %a, i32 0, i32 0
+ %gep2 = getelementptr [12 x i8]* %a, i32 0, i32 4
+ %gep3 = getelementptr [12 x i8]* %a, i32 0, i32 8
+ %iptr1 = bitcast i8* %gep1 to i64*
+ %iptr2 = bitcast i8* %gep2 to i64*
+ %fptr1 = bitcast i8* %gep1 to float*
+ %fptr2 = bitcast i8* %gep2 to float*
+ %fptr3 = bitcast i8* %gep3 to float*
+ store float 0.0, float* %fptr1
+ store float 1.0, float* %fptr2
+ %v = load i64* %iptr1
+ store i64 %v, i64* %iptr2
+ %f1 = load float* %fptr2
+ %f2 = load float* %fptr3
+ %ret = fadd float %f1, %f2
+ ret float %ret
+}
+
+define i32 @PR22093() {
+; Test that we don't try to pre-split a splittable store of a splittable but
+; not pre-splittable load over the same alloca. We "handle" this case when the
+; load is unsplittable but unrelated to this alloca by just generating extra
+; loads without touching the original, but when the original load was out of
+; this alloca we need to handle it specially to ensure the splits line up
+; properly for rewriting.
+;
+; CHECK-LABEL: @PR22093(
+; CHECK-NOT: alloca
+; CHECK: alloca i16
+; CHECK-NOT: alloca
+; CHECK: store volatile i16
+
+entry:
+ %a = alloca i32
+ %a.cast = bitcast i32* %a to i16*
+ store volatile i16 42, i16* %a.cast
+ %load = load i32* %a
+ store i32 %load, i32* %a
+ ret i32 %load
+}
+
+define void @PR22093.2() {
+; Another way that we end up being unable to split a particular set of loads
+; and stores can even have ordering importance. Here we have a load which is
+; pre-splittable by itself, and the first store is also compatible. But the
+; second store of the load makes the load unsplittable because of a mismatch of
+; splits. Because this makes the load unsplittable, we also have to go back and
+; remove the first store from the presplit candidates as its load won't be
+; presplit.
+;
+; CHECK-LABEL: @PR22093.2(
+; CHECK-NOT: alloca
+; CHECK: alloca i16
+; CHECK-NEXT: alloca i8
+; CHECK-NOT: alloca
+; CHECK: store volatile i16
+; CHECK: store volatile i8
+
+entry:
+ %a = alloca i64
+ %a.cast1 = bitcast i64* %a to i32*
+ %a.cast2 = bitcast i64* %a to i16*
+ store volatile i16 42, i16* %a.cast2
+ %load = load i32* %a.cast1
+ store i32 %load, i32* %a.cast1
+ %a.gep1 = getelementptr i32* %a.cast1, i32 1
+ %a.cast3 = bitcast i32* %a.gep1 to i8*
+ store volatile i8 13, i8* %a.cast3
+ store i32 %load, i32* %a.gep1
+ ret void
+}
diff --git a/test/Transforms/SROA/vector-promotion.ll b/test/Transforms/SROA/vector-promotion.ll
index 830a22a..c20c635 100644
--- a/test/Transforms/SROA/vector-promotion.ll
+++ b/test/Transforms/SROA/vector-promotion.ll
@@ -604,3 +604,22 @@ entry:
ret <2 x float> %result
; CHECK-NEXT: ret <2 x float> %[[V4]]
}
+
+define <4 x float> @test12() {
+; CHECK-LABEL: @test12(
+ %a = alloca <3 x i32>, align 16
+; CHECK-NOT: alloca
+
+ %cast1 = bitcast <3 x i32>* %a to <4 x i32>*
+ store <4 x i32> undef, <4 x i32>* %cast1, align 16
+; CHECK-NOT: store
+
+ %cast2 = bitcast <3 x i32>* %a to <3 x float>*
+ %cast3 = bitcast <3 x float>* %cast2 to <4 x float>*
+ %vec = load <4 x float>* %cast3
+; CHECK-NOT: load
+
+; CHECK: %[[ret:.*]] = bitcast <4 x i32> undef to <4 x float>
+; CHECK-NEXT: ret <4 x float> %[[ret]]
+ ret <4 x float> %vec
+}
diff --git a/test/Transforms/SampleProfile/branch.ll b/test/Transforms/SampleProfile/branch.ll
index e646609..6391fc5 100644
--- a/test/Transforms/SampleProfile/branch.ll
+++ b/test/Transforms/SampleProfile/branch.ll
@@ -32,8 +32,8 @@ define i32 @main(i32 %argc, i8** nocapture readonly %argv) #0 {
; CHECK: Printing analysis 'Branch Probability Analysis' for function 'main':
entry:
- tail call void @llvm.dbg.value(metadata !{i32 %argc}, i64 0, metadata !13, metadata !{}), !dbg !27
- tail call void @llvm.dbg.value(metadata !{i8** %argv}, i64 0, metadata !14, metadata !{}), !dbg !27
+ tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !13, metadata !{}), !dbg !27
+ tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !14, metadata !{}), !dbg !27
%cmp = icmp slt i32 %argc, 2, !dbg !28
br i1 %cmp, label %return, label %if.end, !dbg !28
; CHECK: edge entry -> return probability is 1 / 2 = 50%
@@ -43,7 +43,7 @@ if.end: ; preds = %entry
%arrayidx = getelementptr inbounds i8** %argv, i64 1, !dbg !30
%0 = load i8** %arrayidx, align 8, !dbg !30, !tbaa !31
%call = tail call i32 @atoi(i8* %0) #4, !dbg !30
- tail call void @llvm.dbg.value(metadata !{i32 %call}, i64 0, metadata !17, metadata !{}), !dbg !30
+ tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !17, metadata !{}), !dbg !30
%cmp1 = icmp sgt i32 %call, 100, !dbg !35
br i1 %cmp1, label %for.body, label %if.end6, !dbg !35
; CHECK: edge if.end -> for.body probability is 1 / 2 = 50%
@@ -55,14 +55,14 @@ for.body: ; preds = %if.end, %for.body
%add = fadd double %s.015, 3.049000e+00, !dbg !36
%conv = sitofp i32 %u.016 to double, !dbg !36
%add4 = fadd double %add, %conv, !dbg !36
- tail call void @llvm.dbg.value(metadata !{double %add4}, i64 0, metadata !18, metadata !{}), !dbg !36
+ tail call void @llvm.dbg.value(metadata double %add4, i64 0, metadata !18, metadata !{}), !dbg !36
%div = fdiv double 3.940000e+00, %s.015, !dbg !37
%mul = fmul double %div, 3.200000e-01, !dbg !37
%add5 = fadd double %add4, %mul, !dbg !37
%sub = fsub double %add4, %add5, !dbg !37
- tail call void @llvm.dbg.value(metadata !{double %sub}, i64 0, metadata !18, metadata !{}), !dbg !37
+ tail call void @llvm.dbg.value(metadata double %sub, i64 0, metadata !18, metadata !{}), !dbg !37
%inc = add nsw i32 %u.016, 1, !dbg !38
- tail call void @llvm.dbg.value(metadata !{i32 %inc}, i64 0, metadata !21, metadata !{}), !dbg !38
+ tail call void @llvm.dbg.value(metadata i32 %inc, i64 0, metadata !21, metadata !{}), !dbg !38
%exitcond = icmp eq i32 %inc, %call, !dbg !38
br i1 %exitcond, label %if.end6, label %for.body, !dbg !38
; CHECK: edge for.body -> if.end6 probability is 1 / 10227 = 0.00977804
@@ -98,46 +98,46 @@ attributes #4 = { nounwind readonly }
!llvm.module.flags = !{!25, !42}
!llvm.ident = !{!26}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.4 (trunk 192896) (llvm/trunk 192895)\001\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [./branch.cc] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"branch.cc", metadata !"."}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00main\00main\00\004\000\001\000\006\00256\001\004", metadata !1, metadata !5, metadata !6, null, i32 (i32, i8**)* @main, null, null, metadata !12} ; [ DW_TAG_subprogram ] [line 4] [def] [main]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./branch.cc]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !8, metadata !8, metadata !9}
-!8 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!9 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
-!10 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !11} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from char]
-!11 = metadata !{metadata !"0x24\00char\000\008\008\000\000\006", null, null} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
-!12 = metadata !{metadata !13, metadata !14, metadata !15, metadata !17, metadata !18, metadata !21, metadata !23}
-!13 = metadata !{metadata !"0x101\00argc\0016777220\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [argc] [line 4]
-!14 = metadata !{metadata !"0x101\00argv\0033554436\000", metadata !4, metadata !5, metadata !9} ; [ DW_TAG_arg_variable ] [argv] [line 4]
-!15 = metadata !{metadata !"0x100\00result\007\000", metadata !4, metadata !5, metadata !16} ; [ DW_TAG_auto_variable ] [result] [line 7]
-!16 = metadata !{metadata !"0x24\00double\000\0064\0064\000\000\004", null, null} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
-!17 = metadata !{metadata !"0x100\00limit\008\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_auto_variable ] [limit] [line 8]
-!18 = metadata !{metadata !"0x100\00s\0010\000", metadata !19, metadata !5, metadata !16} ; [ DW_TAG_auto_variable ] [s] [line 10]
-!19 = metadata !{metadata !"0xb\009\000\000", metadata !1, metadata !20} ; [ DW_TAG_lexical_block ] [./branch.cc]
-!20 = metadata !{metadata !"0xb\009\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [./branch.cc]
-!21 = metadata !{metadata !"0x100\00u\0011\000", metadata !22, metadata !5, metadata !8} ; [ DW_TAG_auto_variable ] [u] [line 11]
-!22 = metadata !{metadata !"0xb\0011\000\000", metadata !1, metadata !19} ; [ DW_TAG_lexical_block ] [./branch.cc]
-!23 = metadata !{metadata !"0x100\00x\0012\000", metadata !24, metadata !5, metadata !16} ; [ DW_TAG_auto_variable ] [x] [line 12]
-!24 = metadata !{metadata !"0xb\0011\000\000", metadata !1, metadata !22} ; [ DW_TAG_lexical_block ] [./branch.cc]
-!25 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!26 = metadata !{metadata !"clang version 3.4 (trunk 192896) (llvm/trunk 192895)"}
-!27 = metadata !{i32 4, i32 0, metadata !4, null}
-!28 = metadata !{i32 5, i32 0, metadata !29, null}
-!29 = metadata !{metadata !"0xb\005\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [./branch.cc]
-!30 = metadata !{i32 8, i32 0, metadata !4, null}
-!31 = metadata !{metadata !32, metadata !32, i64 0}
-!32 = metadata !{metadata !"any pointer", metadata !33, i64 0}
-!33 = metadata !{metadata !"omnipotent char", metadata !34, i64 0}
-!34 = metadata !{metadata !"Simple C/C++ TBAA"}
-!35 = metadata !{i32 9, i32 0, metadata !20, null}
-!36 = metadata !{i32 13, i32 0, metadata !24, null}
-!37 = metadata !{i32 14, i32 0, metadata !24, null}
-!38 = metadata !{i32 11, i32 0, metadata !22, null}
-!39 = metadata !{i32 20, i32 0, metadata !4, null}
-!40 = metadata !{i32 21, i32 0, metadata !4, null}
-!41 = metadata !{i32 22, i32 0, metadata !4, null}
-!42 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\004\00clang version 3.4 (trunk 192896) (llvm/trunk 192895)\001\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [./branch.cc] [DW_LANG_C_plus_plus]
+!1 = !{!"branch.cc", !"."}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00main\00main\00\004\000\001\000\006\00256\001\004", !1, !5, !6, null, i32 (i32, i8**)* @main, null, null, !12} ; [ DW_TAG_subprogram ] [line 4] [def] [main]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./branch.cc]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!8, !8, !9}
+!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!9 = !{!"0xf\00\000\0064\0064\000\000", null, null, !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
+!10 = !{!"0xf\00\000\0064\0064\000\000", null, null, !11} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from char]
+!11 = !{!"0x24\00char\000\008\008\000\000\006", null, null} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
+!12 = !{!13, !14, !15, !17, !18, !21, !23}
+!13 = !{!"0x101\00argc\0016777220\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [argc] [line 4]
+!14 = !{!"0x101\00argv\0033554436\000", !4, !5, !9} ; [ DW_TAG_arg_variable ] [argv] [line 4]
+!15 = !{!"0x100\00result\007\000", !4, !5, !16} ; [ DW_TAG_auto_variable ] [result] [line 7]
+!16 = !{!"0x24\00double\000\0064\0064\000\000\004", null, null} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
+!17 = !{!"0x100\00limit\008\000", !4, !5, !8} ; [ DW_TAG_auto_variable ] [limit] [line 8]
+!18 = !{!"0x100\00s\0010\000", !19, !5, !16} ; [ DW_TAG_auto_variable ] [s] [line 10]
+!19 = !{!"0xb\009\000\000", !1, !20} ; [ DW_TAG_lexical_block ] [./branch.cc]
+!20 = !{!"0xb\009\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [./branch.cc]
+!21 = !{!"0x100\00u\0011\000", !22, !5, !8} ; [ DW_TAG_auto_variable ] [u] [line 11]
+!22 = !{!"0xb\0011\000\000", !1, !19} ; [ DW_TAG_lexical_block ] [./branch.cc]
+!23 = !{!"0x100\00x\0012\000", !24, !5, !16} ; [ DW_TAG_auto_variable ] [x] [line 12]
+!24 = !{!"0xb\0011\000\000", !1, !22} ; [ DW_TAG_lexical_block ] [./branch.cc]
+!25 = !{i32 2, !"Dwarf Version", i32 4}
+!26 = !{!"clang version 3.4 (trunk 192896) (llvm/trunk 192895)"}
+!27 = !MDLocation(line: 4, scope: !4)
+!28 = !MDLocation(line: 5, scope: !29)
+!29 = !{!"0xb\005\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [./branch.cc]
+!30 = !MDLocation(line: 8, scope: !4)
+!31 = !{!32, !32, i64 0}
+!32 = !{!"any pointer", !33, i64 0}
+!33 = !{!"omnipotent char", !34, i64 0}
+!34 = !{!"Simple C/C++ TBAA"}
+!35 = !MDLocation(line: 9, scope: !20)
+!36 = !MDLocation(line: 13, scope: !24)
+!37 = !MDLocation(line: 14, scope: !24)
+!38 = !MDLocation(line: 11, scope: !22)
+!39 = !MDLocation(line: 20, scope: !4)
+!40 = !MDLocation(line: 21, scope: !4)
+!41 = !MDLocation(line: 22, scope: !4)
+!42 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SampleProfile/calls.ll b/test/Transforms/SampleProfile/calls.ll
index c39472b..d566609 100644
--- a/test/Transforms/SampleProfile/calls.ll
+++ b/test/Transforms/SampleProfile/calls.ll
@@ -92,29 +92,29 @@ declare i32 @printf(i8*, ...) #2
!llvm.module.flags = !{!8, !9}
!llvm.ident = !{!10}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5 \000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [./calls.cc] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"calls.cc", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4, metadata !7}
-!4 = metadata !{metadata !"0x2e\00sum\00sum\00\003\000\001\000\006\00256\000\003", metadata !1, metadata !5, metadata !6, null, i32 (i32, i32)* @_Z3sumii, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 3] [def] [sum]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [./calls.cc]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !"0x2e\00main\00main\00\007\000\001\000\006\00256\000\007", metadata !1, metadata !5, metadata !6, null, i32 ()* @main, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 7] [def] [main]
-!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!10 = metadata !{metadata !"clang version 3.5 "}
-!11 = metadata !{i32 4, i32 0, metadata !4, null}
-!12 = metadata !{i32 8, i32 0, metadata !7, null}
-!13 = metadata !{i32 9, i32 0, metadata !7, null}
-!14 = metadata !{i32 9, i32 0, metadata !15, null}
-!15 = metadata !{metadata !"0xb\001", metadata !1, metadata !7} ; [ DW_TAG_lexical_block ] [./calls.cc]
-!16 = metadata !{i32 10, i32 0, metadata !17, null}
-!17 = metadata !{metadata !"0xb\0010\000\000", metadata !1, metadata !7} ; [ DW_TAG_lexical_block ] [./calls.cc]
-!18 = metadata !{i32 10, i32 0, metadata !19, null}
-!19 = metadata !{metadata !"0xb\001", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ] [./calls.cc]
-!20 = metadata !{i32 10, i32 0, metadata !21, null}
-!21 = metadata !{metadata !"0xb\002", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ] [./calls.cc]
-!22 = metadata !{i32 10, i32 0, metadata !23, null}
-!23 = metadata !{metadata !"0xb\003", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ] [./calls.cc]
-!24 = metadata !{i32 11, i32 0, metadata !7, null}
-!25 = metadata !{i32 12, i32 0, metadata !7, null}
+!0 = !{!"0x11\004\00clang version 3.5 \000\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [./calls.cc] [DW_LANG_C_plus_plus]
+!1 = !{!"calls.cc", !"."}
+!2 = !{}
+!3 = !{!4, !7}
+!4 = !{!"0x2e\00sum\00sum\00\003\000\001\000\006\00256\000\003", !1, !5, !6, null, i32 (i32, i32)* @_Z3sumii, null, null, !2} ; [ DW_TAG_subprogram ] [line 3] [def] [sum]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [./calls.cc]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!"0x2e\00main\00main\00\007\000\001\000\006\00256\000\007", !1, !5, !6, null, i32 ()* @main, null, null, !2} ; [ DW_TAG_subprogram ] [line 7] [def] [main]
+!8 = !{i32 2, !"Dwarf Version", i32 4}
+!9 = !{i32 1, !"Debug Info Version", i32 2}
+!10 = !{!"clang version 3.5 "}
+!11 = !MDLocation(line: 4, scope: !4)
+!12 = !MDLocation(line: 8, scope: !7)
+!13 = !MDLocation(line: 9, scope: !7)
+!14 = !MDLocation(line: 9, scope: !15)
+!15 = !{!"0xb\001", !1, !7} ; [ DW_TAG_lexical_block ] [./calls.cc]
+!16 = !MDLocation(line: 10, scope: !17)
+!17 = !{!"0xb\0010\000\000", !1, !7} ; [ DW_TAG_lexical_block ] [./calls.cc]
+!18 = !MDLocation(line: 10, scope: !19)
+!19 = !{!"0xb\001", !1, !17} ; [ DW_TAG_lexical_block ] [./calls.cc]
+!20 = !MDLocation(line: 10, scope: !21)
+!21 = !{!"0xb\002", !1, !17} ; [ DW_TAG_lexical_block ] [./calls.cc]
+!22 = !MDLocation(line: 10, scope: !23)
+!23 = !{!"0xb\003", !1, !17} ; [ DW_TAG_lexical_block ] [./calls.cc]
+!24 = !MDLocation(line: 11, scope: !7)
+!25 = !MDLocation(line: 12, scope: !7)
diff --git a/test/Transforms/SampleProfile/discriminator.ll b/test/Transforms/SampleProfile/discriminator.ll
index 73c73d1..cafc69d 100644
--- a/test/Transforms/SampleProfile/discriminator.ll
+++ b/test/Transforms/SampleProfile/discriminator.ll
@@ -66,25 +66,25 @@ while.end: ; preds = %while.cond
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.5 \000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [discriminator.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"discriminator.c", metadata !"."}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", metadata !1, metadata !5, metadata !6, null, i32 (i32)* @foo, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [discriminator.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!8 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!9 = metadata !{metadata !"clang version 3.5 "}
-!10 = metadata !{i32 2, i32 0, metadata !4, null}
-!11 = metadata !{i32 3, i32 0, metadata !4, null}
-!12 = metadata !{i32 3, i32 0, metadata !13, null}
-!13 = metadata !{metadata !"0xb\001", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [discriminator.c]
-!14 = metadata !{i32 4, i32 0, metadata !15, null}
-!15 = metadata !{metadata !"0xb\004\000\001", metadata !1, metadata !16} ; [ DW_TAG_lexical_block ] [discriminator.c]
-!16 = metadata !{metadata !"0xb\003\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [discriminator.c]
-!17 = metadata !{i32 4, i32 0, metadata !18, null}
-!18 = metadata !{metadata !"0xb\001", metadata !1, metadata !15} ; [ DW_TAG_lexical_block ] [discriminator.c]
-!19 = metadata !{i32 5, i32 0, metadata !16, null}
-!20 = metadata !{i32 6, i32 0, metadata !16, null}
-!21 = metadata !{i32 7, i32 0, metadata !4, null}
+!0 = !{!"0x11\0012\00clang version 3.5 \000\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [discriminator.c] [DW_LANG_C99]
+!1 = !{!"discriminator.c", !"."}
+!2 = !{}
+!3 = !{!4}
+!4 = !{!"0x2e\00foo\00foo\00\001\000\001\000\006\00256\000\001", !1, !5, !6, null, i32 (i32)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [discriminator.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 1, !"Debug Info Version", i32 2}
+!9 = !{!"clang version 3.5 "}
+!10 = !MDLocation(line: 2, scope: !4)
+!11 = !MDLocation(line: 3, scope: !4)
+!12 = !MDLocation(line: 3, scope: !13)
+!13 = !{!"0xb\001", !1, !4} ; [ DW_TAG_lexical_block ] [discriminator.c]
+!14 = !MDLocation(line: 4, scope: !15)
+!15 = !{!"0xb\004\000\001", !1, !16} ; [ DW_TAG_lexical_block ] [discriminator.c]
+!16 = !{!"0xb\003\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [discriminator.c]
+!17 = !MDLocation(line: 4, scope: !18)
+!18 = !{!"0xb\001", !1, !15} ; [ DW_TAG_lexical_block ] [discriminator.c]
+!19 = !MDLocation(line: 5, scope: !16)
+!20 = !MDLocation(line: 6, scope: !16)
+!21 = !MDLocation(line: 7, scope: !4)
diff --git a/test/Transforms/SampleProfile/fnptr.ll b/test/Transforms/SampleProfile/fnptr.ll
index f78123c..096033b 100644
--- a/test/Transforms/SampleProfile/fnptr.ll
+++ b/test/Transforms/SampleProfile/fnptr.ll
@@ -127,29 +127,29 @@ declare i32 @printf(i8* nocapture readonly, ...) #1
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
-!0 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!1 = metadata !{metadata !"clang version 3.6.0 "}
-!2 = metadata !{i32 9, i32 3, metadata !3, null}
-!3 = metadata !{metadata !"0x2e\00foo\00foo\00\008\000\001\000\000\00256\001\008", metadata !4, metadata !5, metadata !6, null, double (i32)* @_Z3fooi, null, null, metadata !7} ; [ DW_TAG_subprogram ] [line 8] [def] [foo]
-!4 = metadata !{metadata !"fnptr.cc", metadata !"."}
-!5 = metadata !{metadata !"0x29", metadata !4} ; [ DW_TAG_file_type ] [./fnptr.cc]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{}
-!8 = metadata !{i32 9, i32 14, metadata !3, null}
-!9 = metadata !{i32 13, i32 3, metadata !10, null}
-!10 = metadata !{metadata !"0x2e\00bar\00bar\00\0012\000\001\000\000\00256\001\0012", metadata !4, metadata !5, metadata !6, null, double (i32)* @_Z3bari, null, null, metadata !7} ; [ DW_TAG_subprogram ] [line 12] [def] [bar]
-!11 = metadata !{i32 13, i32 14, metadata !10, null}
-!12 = metadata !{i32 19, i32 3, metadata !13, null}
-!13 = metadata !{metadata !"0x2e\00main\00main\00\0016\000\001\000\000\00256\001\0016", metadata !4, metadata !5, metadata !6, null, i32 ()* @main, null, null, metadata !7} ; [ DW_TAG_subprogram ] [line 16] [def] [main]
-!14 = metadata !{i32 20, i32 5, metadata !13, null}
-!15 = metadata !{i32 21, i32 15, metadata !13, null}
-!16 = metadata !{i32 22, i32 11, metadata !13, null}
-!17 = metadata !{metadata !"branch_weights", i32 534, i32 2064}
-!18 = metadata !{i32 23, i32 14, metadata !13, null}
-!19 = metadata !{i32 25, i32 14, metadata !13, null}
-!20 = metadata !{i32 20, i32 28, metadata !13, null}
-!21 = metadata !{metadata !"branch_weights", i32 0, i32 1075}
-!22 = metadata !{i32 19, i32 26, metadata !13, null}
-!23 = metadata !{metadata !"branch_weights", i32 0, i32 534}
-!24 = metadata !{i32 27, i32 3, metadata !13, null}
-!25 = metadata !{i32 28, i32 3, metadata !13, null}
+!0 = !{i32 2, !"Debug Info Version", i32 2}
+!1 = !{!"clang version 3.6.0 "}
+!2 = !MDLocation(line: 9, column: 3, scope: !3)
+!3 = !{!"0x2e\00foo\00foo\00\008\000\001\000\000\00256\001\008", !4, !5, !6, null, double (i32)* @_Z3fooi, null, null, !7} ; [ DW_TAG_subprogram ] [line 8] [def] [foo]
+!4 = !{!"fnptr.cc", !"."}
+!5 = !{!"0x29", !4} ; [ DW_TAG_file_type ] [./fnptr.cc]
+!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{}
+!8 = !MDLocation(line: 9, column: 14, scope: !3)
+!9 = !MDLocation(line: 13, column: 3, scope: !10)
+!10 = !{!"0x2e\00bar\00bar\00\0012\000\001\000\000\00256\001\0012", !4, !5, !6, null, double (i32)* @_Z3bari, null, null, !7} ; [ DW_TAG_subprogram ] [line 12] [def] [bar]
+!11 = !MDLocation(line: 13, column: 14, scope: !10)
+!12 = !MDLocation(line: 19, column: 3, scope: !13)
+!13 = !{!"0x2e\00main\00main\00\0016\000\001\000\000\00256\001\0016", !4, !5, !6, null, i32 ()* @main, null, null, !7} ; [ DW_TAG_subprogram ] [line 16] [def] [main]
+!14 = !MDLocation(line: 20, column: 5, scope: !13)
+!15 = !MDLocation(line: 21, column: 15, scope: !13)
+!16 = !MDLocation(line: 22, column: 11, scope: !13)
+!17 = !{!"branch_weights", i32 534, i32 2064}
+!18 = !MDLocation(line: 23, column: 14, scope: !13)
+!19 = !MDLocation(line: 25, column: 14, scope: !13)
+!20 = !MDLocation(line: 20, column: 28, scope: !13)
+!21 = !{!"branch_weights", i32 0, i32 1075}
+!22 = !MDLocation(line: 19, column: 26, scope: !13)
+!23 = !{!"branch_weights", i32 0, i32 534}
+!24 = !MDLocation(line: 27, column: 3, scope: !13)
+!25 = !MDLocation(line: 28, column: 3, scope: !13)
diff --git a/test/Transforms/SampleProfile/propagate.ll b/test/Transforms/SampleProfile/propagate.ll
index 9ee8ec5..594645f 100644
--- a/test/Transforms/SampleProfile/propagate.ll
+++ b/test/Transforms/SampleProfile/propagate.ll
@@ -198,46 +198,46 @@ attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "n
!llvm.module.flags = !{!8, !9}
!llvm.ident = !{!10}
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5 \000\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [propagate.cc] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"propagate.cc", metadata !"."}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4, metadata !7}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00\003\000\001\000\006\00256\000\003", metadata !1, metadata !5, metadata !6, null, i64 (i32, i32, i64)* @_Z3fooiil, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 3] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [propagate.cc]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{metadata !"0x2e\00main\00main\00\0024\000\001\000\006\00256\000\0024", metadata !1, metadata !5, metadata !6, null, i32 ()* @main, null, null, metadata !2} ; [ DW_TAG_subprogram ] [line 24] [def] [main]
-!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
-!10 = metadata !{metadata !"clang version 3.5 "}
-!11 = metadata !{i32 4, i32 0, metadata !12, null}
-!12 = metadata !{metadata !"0xb\004\000\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!13 = metadata !{i32 5, i32 0, metadata !14, null}
-!14 = metadata !{metadata !"0xb\004\000\000", metadata !1, metadata !12} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!15 = metadata !{i32 7, i32 0, metadata !16, null}
-!16 = metadata !{metadata !"0xb\007\000\000", metadata !1, metadata !17} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!17 = metadata !{metadata !"0xb\006\000\000", metadata !1, metadata !12} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!18 = metadata !{i32 8, i32 0, metadata !19, null}
-!19 = metadata !{metadata !"0xb\008\000\000", metadata !1, metadata !20} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!20 = metadata !{metadata !"0xb\007\000\000", metadata !1, metadata !16} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!21 = metadata !{i32 9, i32 0, metadata !19, null}
-!22 = metadata !{i32 10, i32 0, metadata !23, null}
-!23 = metadata !{metadata !"0xb\0010\000\000", metadata !1, metadata !20} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!24 = metadata !{i32 11, i32 0, metadata !25, null}
-!25 = metadata !{metadata !"0xb\0010\000\000", metadata !1, metadata !23} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!26 = metadata !{i32 12, i32 0, metadata !25, null}
-!27 = metadata !{i32 13, i32 0, metadata !25, null}
-!28 = metadata !{i32 14, i32 0, metadata !29, null}
-!29 = metadata !{metadata !"0xb\0014\000\000", metadata !1, metadata !30} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!30 = metadata !{metadata !"0xb\0013\000\000", metadata !1, metadata !23} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!31 = metadata !{i32 15, i32 0, metadata !32, null}
-!32 = metadata !{metadata !"0xb\0014\000\000", metadata !1, metadata !29} ; [ DW_TAG_lexical_block ] [propagate.cc]
-!33 = metadata !{i32 16, i32 0, metadata !32, null}
-!34 = metadata !{i32 17, i32 0, metadata !32, null}
-!35 = metadata !{i32 19, i32 0, metadata !20, null}
-!36 = metadata !{i32 21, i32 0, metadata !4, null}
-!37 = metadata !{i32 22, i32 0, metadata !4, null}
-!38 = metadata !{i32 25, i32 0, metadata !7, null}
-!39 = metadata !{i32 26, i32 0, metadata !7, null}
-!40 = metadata !{i32 27, i32 0, metadata !7, null}
-!41 = metadata !{i32 28, i32 0, metadata !7, null}
-!42 = metadata !{i32 29, i32 0, metadata !7, null}
+!0 = !{!"0x11\004\00clang version 3.5 \000\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [propagate.cc] [DW_LANG_C_plus_plus]
+!1 = !{!"propagate.cc", !"."}
+!2 = !{i32 0}
+!3 = !{!4, !7}
+!4 = !{!"0x2e\00foo\00foo\00\003\000\001\000\006\00256\000\003", !1, !5, !6, null, i64 (i32, i32, i64)* @_Z3fooiil, null, null, !2} ; [ DW_TAG_subprogram ] [line 3] [def] [foo]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [propagate.cc]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{!"0x2e\00main\00main\00\0024\000\001\000\006\00256\000\0024", !1, !5, !6, null, i32 ()* @main, null, null, !2} ; [ DW_TAG_subprogram ] [line 24] [def] [main]
+!8 = !{i32 2, !"Dwarf Version", i32 4}
+!9 = !{i32 1, !"Debug Info Version", i32 2}
+!10 = !{!"clang version 3.5 "}
+!11 = !MDLocation(line: 4, scope: !12)
+!12 = !{!"0xb\004\000\000", !1, !4} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!13 = !MDLocation(line: 5, scope: !14)
+!14 = !{!"0xb\004\000\000", !1, !12} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!15 = !MDLocation(line: 7, scope: !16)
+!16 = !{!"0xb\007\000\000", !1, !17} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!17 = !{!"0xb\006\000\000", !1, !12} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!18 = !MDLocation(line: 8, scope: !19)
+!19 = !{!"0xb\008\000\000", !1, !20} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!20 = !{!"0xb\007\000\000", !1, !16} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!21 = !MDLocation(line: 9, scope: !19)
+!22 = !MDLocation(line: 10, scope: !23)
+!23 = !{!"0xb\0010\000\000", !1, !20} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!24 = !MDLocation(line: 11, scope: !25)
+!25 = !{!"0xb\0010\000\000", !1, !23} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!26 = !MDLocation(line: 12, scope: !25)
+!27 = !MDLocation(line: 13, scope: !25)
+!28 = !MDLocation(line: 14, scope: !29)
+!29 = !{!"0xb\0014\000\000", !1, !30} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!30 = !{!"0xb\0013\000\000", !1, !23} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!31 = !MDLocation(line: 15, scope: !32)
+!32 = !{!"0xb\0014\000\000", !1, !29} ; [ DW_TAG_lexical_block ] [propagate.cc]
+!33 = !MDLocation(line: 16, scope: !32)
+!34 = !MDLocation(line: 17, scope: !32)
+!35 = !MDLocation(line: 19, scope: !20)
+!36 = !MDLocation(line: 21, scope: !4)
+!37 = !MDLocation(line: 22, scope: !4)
+!38 = !MDLocation(line: 25, scope: !7)
+!39 = !MDLocation(line: 26, scope: !7)
+!40 = !MDLocation(line: 27, scope: !7)
+!41 = !MDLocation(line: 28, scope: !7)
+!42 = !MDLocation(line: 29, scope: !7)
diff --git a/test/Transforms/ScalarRepl/debuginfo-preserved.ll b/test/Transforms/ScalarRepl/debuginfo-preserved.ll
index eb660d2..b0c459e 100644
--- a/test/Transforms/ScalarRepl/debuginfo-preserved.ll
+++ b/test/Transforms/ScalarRepl/debuginfo-preserved.ll
@@ -17,10 +17,10 @@ entry:
%b.addr = alloca i32, align 4
%c = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
- call void @llvm.dbg.declare(metadata !{i32* %a.addr}, metadata !6, metadata !{}), !dbg !7
+ call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !6, metadata !{}), !dbg !7
store i32 %b, i32* %b.addr, align 4
- call void @llvm.dbg.declare(metadata !{i32* %b.addr}, metadata !8, metadata !{}), !dbg !9
- call void @llvm.dbg.declare(metadata !{i32* %c}, metadata !10, metadata !{}), !dbg !12
+ call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !8, metadata !{}), !dbg !9
+ call void @llvm.dbg.declare(metadata i32* %c, metadata !10, metadata !{}), !dbg !12
%tmp = load i32* %a.addr, align 4, !dbg !13
store i32 %tmp, i32* %c, align 4, !dbg !13
%tmp1 = load i32* %a.addr, align 4, !dbg !14
@@ -42,24 +42,24 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!20}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.0 (trunk 131941)\000\00\000\00\000", metadata !18, metadata !19, metadata !19, metadata !17, null, null} ; [ DW_TAG_compile_unit ]
-!1 = metadata !{metadata !"0x2e\00f\00f\00\001\000\001\000\006\00256\000\001", metadata !18, metadata !2, metadata !3, null, i32 (i32, i32)* @f, null, null, null} ; [ DW_TAG_subprogram ] [line 1] [def] [f]
-!2 = metadata !{metadata !"0x29", metadata !18} ; [ DW_TAG_file_type ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !18, metadata !2, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !0} ; [ DW_TAG_base_type ]
-!6 = metadata !{metadata !"0x101\00a\0016777217\000", metadata !1, metadata !2, metadata !5} ; [ DW_TAG_arg_variable ]
-!7 = metadata !{i32 1, i32 11, metadata !1, null}
-!8 = metadata !{metadata !"0x101\00b\0033554433\000", metadata !1, metadata !2, metadata !5} ; [ DW_TAG_arg_variable ]
-!9 = metadata !{i32 1, i32 18, metadata !1, null}
-!10 = metadata !{metadata !"0x100\00c\002\000", metadata !11, metadata !2, metadata !5} ; [ DW_TAG_auto_variable ]
-!11 = metadata !{metadata !"0xb\001\0021\000", metadata !18, metadata !1} ; [ DW_TAG_lexical_block ]
-!12 = metadata !{i32 2, i32 9, metadata !11, null}
-!13 = metadata !{i32 2, i32 14, metadata !11, null}
-!14 = metadata !{i32 3, i32 5, metadata !11, null}
-!15 = metadata !{i32 4, i32 5, metadata !11, null}
-!16 = metadata !{i32 5, i32 5, metadata !11, null}
-!17 = metadata !{metadata !1}
-!18 = metadata !{metadata !"/d/j/debug-test.c", metadata !"/Volumes/Data/b"}
-!19 = metadata !{i32 0}
-!20 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\0012\00clang version 3.0 (trunk 131941)\000\00\000\00\000", !18, !19, !19, !17, null, null} ; [ DW_TAG_compile_unit ]
+!1 = !{!"0x2e\00f\00f\00\001\000\001\000\006\00256\000\001", !18, !2, !3, null, i32 (i32, i32)* @f, null, null, null} ; [ DW_TAG_subprogram ] [line 1] [def] [f]
+!2 = !{!"0x29", !18} ; [ DW_TAG_file_type ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !18, !2, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{!5}
+!5 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !0} ; [ DW_TAG_base_type ]
+!6 = !{!"0x101\00a\0016777217\000", !1, !2, !5} ; [ DW_TAG_arg_variable ]
+!7 = !MDLocation(line: 1, column: 11, scope: !1)
+!8 = !{!"0x101\00b\0033554433\000", !1, !2, !5} ; [ DW_TAG_arg_variable ]
+!9 = !MDLocation(line: 1, column: 18, scope: !1)
+!10 = !{!"0x100\00c\002\000", !11, !2, !5} ; [ DW_TAG_auto_variable ]
+!11 = !{!"0xb\001\0021\000", !18, !1} ; [ DW_TAG_lexical_block ]
+!12 = !MDLocation(line: 2, column: 9, scope: !11)
+!13 = !MDLocation(line: 2, column: 14, scope: !11)
+!14 = !MDLocation(line: 3, column: 5, scope: !11)
+!15 = !MDLocation(line: 4, column: 5, scope: !11)
+!16 = !MDLocation(line: 5, column: 5, scope: !11)
+!17 = !{!1}
+!18 = !{!"/d/j/debug-test.c", !"/Volumes/Data/b"}
+!19 = !{i32 0}
+!20 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/Scalarizer/basic.ll b/test/Transforms/Scalarizer/basic.ll
index 1cfc0dd..a94cf9f 100644
--- a/test/Transforms/Scalarizer/basic.ll
+++ b/test/Transforms/Scalarizer/basic.ll
@@ -443,9 +443,9 @@ exit:
ret <4 x float> %next_acc
}
-!0 = metadata !{ metadata !"root" }
-!1 = metadata !{ metadata !"set1", metadata !0 }
-!2 = metadata !{ metadata !"set2", metadata !0 }
-!3 = metadata !{ metadata !3 }
-!4 = metadata !{ float 4.0 }
-!5 = metadata !{ i64 0, i64 8, null }
+!0 = !{ !"root" }
+!1 = !{ !"set1", !0 }
+!2 = !{ !"set2", !0 }
+!3 = !{ !3 }
+!4 = !{ float 4.0 }
+!5 = !{ i64 0, i64 8, null }
diff --git a/test/Transforms/Scalarizer/dbginfo.ll b/test/Transforms/Scalarizer/dbginfo.ll
index ee7182b..ed65aaa 100644
--- a/test/Transforms/Scalarizer/dbginfo.ll
+++ b/test/Transforms/Scalarizer/dbginfo.ll
@@ -16,9 +16,9 @@ define void @f1(<4 x i32>* nocapture %a, <4 x i32>* nocapture readonly %b, <4 x
; CHECK: %b.i1 = getelementptr i32* %b.i0, i32 1
; CHECK: %b.i2 = getelementptr i32* %b.i0, i32 2
; CHECK: %b.i3 = getelementptr i32* %b.i0, i32 3
-; CHECK: tail call void @llvm.dbg.value(metadata !{<4 x i32>* %a}, i64 0, metadata !{{[0-9]+}}, metadata {{.*}}), !dbg !{{[0-9]+}}
-; CHECK: tail call void @llvm.dbg.value(metadata !{<4 x i32>* %b}, i64 0, metadata !{{[0-9]+}}, metadata {{.*}}), !dbg !{{[0-9]+}}
-; CHECK: tail call void @llvm.dbg.value(metadata !{<4 x i32>* %c}, i64 0, metadata !{{[0-9]+}}, metadata {{.*}}), !dbg !{{[0-9]+}}
+; CHECK: tail call void @llvm.dbg.value(metadata <4 x i32>* %a, i64 0, metadata !{{[0-9]+}}, metadata {{.*}}), !dbg !{{[0-9]+}}
+; CHECK: tail call void @llvm.dbg.value(metadata <4 x i32>* %b, i64 0, metadata !{{[0-9]+}}, metadata {{.*}}), !dbg !{{[0-9]+}}
+; CHECK: tail call void @llvm.dbg.value(metadata <4 x i32>* %c, i64 0, metadata !{{[0-9]+}}, metadata {{.*}}), !dbg !{{[0-9]+}}
; CHECK: %bval.i0 = load i32* %b.i0, align 16, !dbg ![[TAG1:[0-9]+]], !tbaa ![[TAG2:[0-9]+]]
; CHECK: %bval.i1 = load i32* %b.i1, align 4, !dbg ![[TAG1]], !tbaa ![[TAG2]]
; CHECK: %bval.i2 = load i32* %b.i2, align 8, !dbg ![[TAG1]], !tbaa ![[TAG2]]
@@ -37,9 +37,9 @@ define void @f1(<4 x i32>* nocapture %a, <4 x i32>* nocapture readonly %b, <4 x
; CHECK: store i32 %add.i3, i32* %a.i3, align 4, !dbg ![[TAG1]], !tbaa ![[TAG2]]
; CHECK: ret void
entry:
- tail call void @llvm.dbg.value(metadata !{<4 x i32>* %a}, i64 0, metadata !15, metadata !{}), !dbg !20
- tail call void @llvm.dbg.value(metadata !{<4 x i32>* %b}, i64 0, metadata !16, metadata !{}), !dbg !20
- tail call void @llvm.dbg.value(metadata !{<4 x i32>* %c}, i64 0, metadata !17, metadata !{}), !dbg !20
+ tail call void @llvm.dbg.value(metadata <4 x i32>* %a, i64 0, metadata !15, metadata !{}), !dbg !20
+ tail call void @llvm.dbg.value(metadata <4 x i32>* %b, i64 0, metadata !16, metadata !{}), !dbg !20
+ tail call void @llvm.dbg.value(metadata <4 x i32>* %c, i64 0, metadata !17, metadata !{}), !dbg !20
%bval = load <4 x i32>* %b, align 16, !dbg !21, !tbaa !22
%cval = load <4 x i32>* %c, align 16, !dbg !21, !tbaa !22
%add = add <4 x i32> %bval, %cval, !dbg !21
@@ -57,30 +57,30 @@ attributes #1 = { nounwind readnone }
!llvm.module.flags = !{!18, !26}
!llvm.ident = !{!19}
-!0 = metadata !{metadata !"0x11\0012\00clang version 3.4 (trunk 194134) (llvm/trunk 194126)\001\00\000\00\000", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/home/richards/llvm/build//tmp/add.c] [DW_LANG_C99]
-!1 = metadata !{metadata !"/tmp/add.c", metadata !"/home/richards/llvm/build"}
-!2 = metadata !{i32 0}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00f1\00f1\00\003\000\001\000\006\00256\001\004", metadata !1, metadata !5, metadata !6, null, void (<4 x i32>*, <4 x i32>*, <4 x i32>*)* @f1, null, null, metadata !14} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 4] [f]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/home/richards/llvm/build//tmp/add.c]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{null, metadata !8, metadata !8, metadata !8}
-!8 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from V4SI]
-!9 = metadata !{metadata !"0x16\00V4SI\001\000\000\000\000", metadata !1, null, metadata !10} ; [ DW_TAG_typedef ] [V4SI] [line 1, size 0, align 0, offset 0] [from ]
-!10 = metadata !{metadata !"0x1\00\000\00128\00128\000\002048", null, null, metadata !11, metadata !12, i32 0, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 128, align 128, offset 0] [vector] [from int]
-!11 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!12 = metadata !{metadata !13}
-!13 = metadata !{metadata !"0x21\000\004"} ; [ DW_TAG_subrange_type ] [0, 3]
-!14 = metadata !{metadata !15, metadata !16, metadata !17}
-!15 = metadata !{metadata !"0x101\00a\0016777219\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [a] [line 3]
-!16 = metadata !{metadata !"0x101\00b\0033554435\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [b] [line 3]
-!17 = metadata !{metadata !"0x101\00c\0050331651\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [c] [line 3]
-!18 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!19 = metadata !{metadata !"clang version 3.4 (trunk 194134) (llvm/trunk 194126)"}
-!20 = metadata !{i32 3, i32 0, metadata !4, null}
-!21 = metadata !{i32 5, i32 0, metadata !4, null}
-!22 = metadata !{metadata !23, metadata !23, i64 0}
-!23 = metadata !{metadata !"omnipotent char", metadata !24, i64 0}
-!24 = metadata !{metadata !"Simple C/C++ TBAA"}
-!25 = metadata !{i32 6, i32 0, metadata !4, null}
-!26 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\0012\00clang version 3.4 (trunk 194134) (llvm/trunk 194126)\001\00\000\00\000", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/home/richards/llvm/build//tmp/add.c] [DW_LANG_C99]
+!1 = !{!"/tmp/add.c", !"/home/richards/llvm/build"}
+!2 = !{i32 0}
+!3 = !{!4}
+!4 = !{!"0x2e\00f1\00f1\00\003\000\001\000\006\00256\001\004", !1, !5, !6, null, void (<4 x i32>*, <4 x i32>*, <4 x i32>*)* @f1, null, null, !14} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 4] [f]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/home/richards/llvm/build//tmp/add.c]
+!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = !{null, !8, !8, !8}
+!8 = !{!"0xf\00\000\0064\0064\000\000", null, null, !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from V4SI]
+!9 = !{!"0x16\00V4SI\001\000\000\000\000", !1, null, !10} ; [ DW_TAG_typedef ] [V4SI] [line 1, size 0, align 0, offset 0] [from ]
+!10 = !{!"0x1\00\000\00128\00128\000\002048", null, null, !11, !12, i32 0, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 128, align 128, offset 0] [vector] [from int]
+!11 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!12 = !{!13}
+!13 = !{!"0x21\000\004"} ; [ DW_TAG_subrange_type ] [0, 3]
+!14 = !{!15, !16, !17}
+!15 = !{!"0x101\00a\0016777219\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [a] [line 3]
+!16 = !{!"0x101\00b\0033554435\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [b] [line 3]
+!17 = !{!"0x101\00c\0050331651\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [c] [line 3]
+!18 = !{i32 2, !"Dwarf Version", i32 4}
+!19 = !{!"clang version 3.4 (trunk 194134) (llvm/trunk 194126)"}
+!20 = !MDLocation(line: 3, scope: !4)
+!21 = !MDLocation(line: 5, scope: !4)
+!22 = !{!23, !23, i64 0}
+!23 = !{!"omnipotent char", !24, i64 0}
+!24 = !{!"Simple C/C++ TBAA"}
+!25 = !MDLocation(line: 6, scope: !4)
+!26 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll b/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
index a90e072..76f41e8 100644
--- a/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
+++ b/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
@@ -12,5 +12,9 @@ Cont: ; preds = %0
ret i32 0
Other: ; preds = %0
+ landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
ret i32 1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll b/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll
index cf29b71..8e15637 100644
--- a/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll
+++ b/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll
@@ -1,27 +1,27 @@
-; The phi should not be eliminated in this case, because the fp op could trap.
+; The phi should not be eliminated in this case, because the divide op could trap.
; RUN: opt < %s -simplifycfg -S | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i686-apple-darwin8"
-@G = weak global double 0.000000e+00, align 8 ; <double*> [#uses=2]
+@G = weak global i32 0, align 8 ; <i32*> [#uses=2]
-define void @test(i32 %X, i32 %Y, double %Z) {
+define void @test(i32 %X, i32 %Y, i32 %Z) {
entry:
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- %tmp = load double* @G, align 8 ; <double> [#uses=2]
+ %tmp = load i32* @G, align 8 ; <i32> [#uses=2]
%tmp3 = icmp eq i32 %X, %Y ; <i1> [#uses=1]
%tmp34 = zext i1 %tmp3 to i8 ; <i8> [#uses=1]
%toBool = icmp ne i8 %tmp34, 0 ; <i1> [#uses=1]
br i1 %toBool, label %cond_true, label %cond_next
cond_true: ; preds = %entry
- %tmp7 = fadd double %tmp, %Z ; <double> [#uses=1]
+ %tmp7 = udiv i32 %tmp, %Z ; <i32> [#uses=1]
br label %cond_next
cond_next: ; preds = %cond_true, %entry
-; CHECK: = phi double
- %F.0 = phi double [ %tmp, %entry ], [ %tmp7, %cond_true ] ; <double> [#uses=1]
- store double %F.0, double* @G, align 8
+; CHECK: = phi i32
+ %F.0 = phi i32 [ %tmp, %entry ], [ %tmp7, %cond_true ] ; <i32> [#uses=1]
+ store i32 %F.0, i32* @G, align 8
ret void
}
diff --git a/test/Transforms/SimplifyCFG/AArch64/lit.local.cfg b/test/Transforms/SimplifyCFG/AArch64/lit.local.cfg
new file mode 100644
index 0000000..6642d28
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/AArch64/lit.local.cfg
@@ -0,0 +1,5 @@
+config.suffixes = ['.ll']
+
+targets = set(config.root.targets_to_build.split())
+if not 'AArch64' in targets:
+ config.unsupported = True
diff --git a/test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll b/test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll
new file mode 100644
index 0000000..076cb58
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll
@@ -0,0 +1,72 @@
+; RUN: opt < %s -mtriple=aarch64-linux-gnu -simplifycfg -enable-unsafe-fp-math -S >%t
+; RUN: FileCheck %s < %t
+; ModuleID = 't.cc'
+
+; Function Attrs: nounwind
+define double @_Z3fooRdS_S_S_(double* dereferenceable(8) %x, double* dereferenceable(8) %y, double* dereferenceable(8) %a) #0 {
+entry:
+ %0 = load double* %y, align 8
+ %cmp = fcmp oeq double %0, 0.000000e+00
+ %1 = load double* %x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+; fadd (const, (fmul x, y))
+if.then: ; preds = %entry
+; CHECK-LABEL: if.then:
+; CHECK: %3 = fmul fast double %1, %2
+; CHECK-NEXT: %mul = fadd fast double 1.000000e+00, %3
+ %2 = load double* %a, align 8
+ %3 = fmul fast double %1, %2
+ %mul = fadd fast double 1.000000e+00, %3
+ store double %mul, double* %y, align 8
+ br label %if.end
+
+; fsub ((fmul x, y), z)
+if.else: ; preds = %entry
+; CHECK-LABEL: if.else:
+; CHECK: %mul1 = fmul fast double %1, %2
+; CHECK-NEXT: %sub1 = fsub fast double %mul1, %0
+ %4 = load double* %a, align 8
+ %mul1 = fmul fast double %1, %4
+ %sub1 = fsub fast double %mul1, %0
+ store double %sub1, double* %y, align 8
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %5 = load double* %y, align 8
+ %cmp2 = fcmp oeq double %5, 2.000000e+00
+ %6 = load double* %x, align 8
+ br i1 %cmp2, label %if.then2, label %if.else2
+
+; fsub (x, (fmul y, z))
+if.then2: ; preds = %entry
+; CHECK-LABEL: if.then2:
+; CHECK: %7 = fmul fast double %5, 3.000000e+00
+; CHECK-NEXT: %mul2 = fsub fast double %6, %7
+ %7 = load double* %a, align 8
+ %8 = fmul fast double %6, 3.0000000e+00
+ %mul2 = fsub fast double %7, %8
+ store double %mul2, double* %y, align 8
+ br label %if.end2
+
+; fsub (fneg((fmul x, y)), const)
+if.else2: ; preds = %entry
+; CHECK-LABEL: if.else2:
+; CHECK: %mul3 = fmul fast double %5, 3.000000e+00
+; CHECK-NEXT: %neg = fsub fast double 0.000000e+00, %mul3
+; CHECK-NEXT: %sub2 = fsub fast double %neg, 3.000000e+00
+ %mul3 = fmul fast double %6, 3.0000000e+00
+ %neg = fsub fast double 0.0000000e+00, %mul3
+ %sub2 = fsub fast double %neg, 3.0000000e+00
+ store double %sub2, double* %y, align 8
+ br label %if.end2
+
+if.end2: ; preds = %if.else, %if.then
+ %9 = load double* %x, align 8
+ %10 = load double* %y, align 8
+ %add = fadd fast double %9, %10
+ %11 = load double* %a, align 8
+ %add2 = fadd fast double %add, %11
+ ret double %add2
+}
+
diff --git a/test/Transforms/SimplifyCFG/PhiBlockMerge.ll b/test/Transforms/SimplifyCFG/PhiBlockMerge.ll
index 36b52f5..5550829 100644
--- a/test/Transforms/SimplifyCFG/PhiBlockMerge.ll
+++ b/test/Transforms/SimplifyCFG/PhiBlockMerge.ll
@@ -4,9 +4,7 @@
;
define i32 @test(i1 %a, i1 %b) {
-; CHECK: br i1 %a
br i1 %a, label %M, label %O
-; CHECK: O:
O: ; preds = %0
; CHECK: select i1 %b, i32 0, i32 1
; CHECK-NOT: phi
@@ -18,9 +16,9 @@ N: ; preds = %Q, %O
%Wp = phi i32 [ 0, %O ], [ 1, %Q ] ; <i32> [#uses=1]
br label %M
M: ; preds = %N, %0
-; CHECK: %W = phi i32
%W = phi i32 [ %Wp, %N ], [ 2, %0 ] ; <i32> [#uses=1]
%R = add i32 %W, 1 ; <i32> [#uses=1]
ret i32 %R
+; CHECK: ret
}
diff --git a/test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll b/test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll
new file mode 100644
index 0000000..fa74549
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll
@@ -0,0 +1,45 @@
+; RUN: opt -S -simplifycfg < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+define i64 @test1(i64 %A) {
+; CHECK-LABEL: @test1(
+; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; CHECK-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTLZ]]
+; CHECK-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+define i64 @test1b(i64 %A) {
+; CHECK-LABEL: @test1b(
+; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; CHECK-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTLZ]]
+; CHECK-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+
diff --git a/test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg b/test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg
new file mode 100644
index 0000000..0913324
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'PowerPC' in config.root.targets:
+ config.unsupported = True
diff --git a/test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll b/test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll
new file mode 100644
index 0000000..5b27994
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll
@@ -0,0 +1,249 @@
+; RUN: opt -S -simplifycfg -mtriple=r600-unknown-unknown -mcpu=SI < %s | FileCheck -check-prefix=SI -check-prefix=ALL %s
+; RUN: opt -S -simplifycfg -mtriple=r600-unknown-unknown -mcpu=tonga < %s | FileCheck -check-prefix=SI -check-prefix=ALL %s
+
+
+define i64 @test1(i64 %A) {
+; ALL-LABEL: @test1(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; SI-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTLZ]]
+; SI-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2(i32 %A) {
+; ALL-LABEL: @test2(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; SI-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTLZ]]
+; SI-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3(i16 signext %A) {
+; ALL-LABEL: @test3(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; SI-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 16, i16 [[CTLZ]]
+; SI-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1b(i64 %A) {
+; ALL-LABEL: @test1b(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; SI-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTTZ]]
+; SI-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2b(i32 %A) {
+; ALL-LABEL: @test2b(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; SI-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTTZ]]
+; SI-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3b(i16 signext %A) {
+; ALL-LABEL: @test3b(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; SI-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 16, i16 [[CTTZ]]
+; SI-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1c(i64 %A) {
+; ALL-LABEL: @test1c(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 63, i64 [[CTLZ]]
+; ALL-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 63, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test2c(i32 %A) {
+; ALL-LABEL: @test2c(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 31, i32 [[CTLZ]]
+; ALL-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 31, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3c(i16 signext %A) {
+; ALL-LABEL: @test3c(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 15, i16 [[CTLZ]]
+; ALL-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 15, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1d(i64 %A) {
+; ALL-LABEL: @test1d(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 63, i64 [[CTTZ]]
+; ALL-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 63, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2d(i32 %A) {
+; ALL-LABEL: @test2d(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 31, i32 [[CTTZ]]
+; ALL-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 31, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3d(i16 signext %A) {
+; ALL-LABEL: @test3d(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 15, i16 [[CTTZ]]
+; ALL-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 15, %entry ]
+ ret i16 %cond
+}
+
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
diff --git a/test/Transforms/SimplifyCFG/R600/lit.local.cfg b/test/Transforms/SimplifyCFG/R600/lit.local.cfg
new file mode 100644
index 0000000..ad9ce25
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/R600/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'R600' in config.root.targets:
+ config.unsupported = True
diff --git a/test/Transforms/SimplifyCFG/SpeculativeExec.ll b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
index 83fa419..31de3c8 100644
--- a/test/Transforms/SimplifyCFG/SpeculativeExec.ll
+++ b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
@@ -28,22 +28,6 @@ bb3: ; preds = %bb2, %entry
ret i32 %tmp5
}
-declare i8 @llvm.cttz.i8(i8, i1)
-
-define i8 @test2(i8 %a) {
-; CHECK-LABEL: @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
-}
-
define i8* @test4(i1* %dummy, i8* %a, i8* %b) {
; Test that we don't speculate an arbitrarily large number of unfolded constant
; expressions.
diff --git a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index 21428c6..22b144b 100644
--- a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -46,32 +46,6 @@ T:
ret i32 2
}
-; PR9450
-define i32 @test4(i32 %v, i32 %w) {
-; CHECK: entry:
-; CHECK-NEXT: switch i32 %v, label %T [
-; CHECK-NEXT: i32 3, label %V
-; CHECK-NEXT: i32 2, label %U
-; CHECK-NEXT: ]
-
-entry:
- br label %SWITCH
-V:
- ret i32 7
-SWITCH:
- switch i32 %v, label %default [
- i32 1, label %T
- i32 2, label %U
- i32 3, label %V
- ]
-default:
- unreachable
-U:
- ret i32 %w
-T:
- ret i32 2
-}
-
;; We can either convert the following control-flow to a select or remove the
;; unreachable control flow because of the undef store of null. Make sure we do
diff --git a/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll b/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll
new file mode 100644
index 0000000..69f6c69
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll
@@ -0,0 +1,330 @@
+; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
+; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
+; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
+
+
+define i64 @test1(i64 %A) {
+; ALL-LABEL: @test1(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; LZCNT-NEXT: select i1 [[COND]], i64 64, i64 [[CTLZ]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test2(i32 %A) {
+; ALL-LABEL: @test2(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+; LZCNT-NEXT: select i1 [[COND]], i32 32, i32 [[CTLZ]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3(i16 signext %A) {
+; ALL-LABEL: @test3(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+; LZCNT-NEXT: select i1 [[COND]], i16 16, i16 [[CTLZ]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1b(i64 %A) {
+; ALL-LABEL: @test1b(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; BMI-NEXT: select i1 [[COND]], i64 64, i64 [[CTTZ]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2b(i32 %A) {
+; ALL-LABEL: @test2b(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+; BMI-NEXT: select i1 [[COND]], i32 32, i32 [[CTTZ]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3b(i16 signext %A) {
+; ALL-LABEL: @test3b(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+; BMI-NEXT: select i1 [[COND]], i16 16, i16 [[CTTZ]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+; The following tests verify that calls to cttz/ctlz are speculated even if
+; basic block %cond.true has an extra zero extend/truncate which is "free"
+; for the target.
+
+define i64 @test1e(i32 %x) {
+; ALL-LABEL: @test1e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+; ALL: [[ZEXT:%[A-Za-z0-9]+]] = zext i32 [[CTTZ]] to i64
+; BMI-NEXT: select i1 [[COND]], i64 32, i64 [[ZEXT]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %phitmp2 = zext i32 %0 to i64
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %phitmp2, %cond.true ], [ 32, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test2e(i64 %x) {
+; ALL-LABEL: @test2e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTTZ]] to i32
+; BMI-NEXT: select i1 [[COND]], i32 64, i32 [[TRUNC]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i32
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i32 %cond
+}
+
+define i64 @test3e(i32 %x) {
+; ALL-LABEL: @test3e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+; ALL: [[ZEXT:%[A-Za-z0-9]+]] = zext i32 [[CTLZ]] to i64
+; LZCNT-NEXT: select i1 [[COND]], i64 32, i64 [[ZEXT]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %phitmp2 = zext i32 %0 to i64
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %phitmp2, %cond.true ], [ 32, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test4e(i64 %x) {
+; ALL-LABEL: @test4e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTLZ]] to i32
+; LZCNT-NEXT: select i1 [[COND]], i32 64, i32 [[TRUNC]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i32
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i32 %cond
+}
+
+define i16 @test5e(i64 %x) {
+; ALL-LABEL: @test5e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTLZ]] to i16
+; LZCNT-NEXT: select i1 [[COND]], i16 64, i16 [[TRUNC]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i16 %cond
+}
+
+define i16 @test6e(i32 %x) {
+; ALL-LABEL: @test6e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i32 [[CTLZ]] to i16
+; LZCNT-NEXT: select i1 [[COND]], i16 32, i16 [[TRUNC]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %cast = trunc i32 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 32, %entry ]
+ ret i16 %cond
+}
+
+define i16 @test7e(i64 %x) {
+; ALL-LABEL: @test7e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTTZ]] to i16
+; BMI-NEXT: select i1 [[COND]], i16 64, i16 [[TRUNC]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i16 %cond
+}
+
+define i16 @test8e(i32 %x) {
+; ALL-LABEL: @test8e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i32 [[CTTZ]] to i16
+; BMI-NEXT: select i1 [[COND]], i16 32, i16 [[TRUNC]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %cast = trunc i32 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 32, %entry ]
+ ret i16 %cond
+}
+
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
diff --git a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
index fc22e7e..ea3b575 100644
--- a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
+++ b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
@@ -21,8 +21,8 @@ target triple = "x86_64-unknown-linux-gnu"
; The table for @cprop
; CHECK: @switch.table5 = private unnamed_addr constant [7 x i32] [i32 5, i32 42, i32 126, i32 -452, i32 128, i32 6, i32 7]
-; The table for @unreachable
-; CHECK: @switch.table6 = private unnamed_addr constant [5 x i32] [i32 0, i32 0, i32 0, i32 1, i32 -1]
+; The table for @unreachable_case
+; CHECK: @switch.table6 = private unnamed_addr constant [9 x i32] [i32 0, i32 0, i32 0, i32 2, i32 -1, i32 1, i32 1, i32 1, i32 1]
; A simple int-to-int selection switch.
; It is dense enough to be replaced by table lookup.
@@ -752,7 +752,7 @@ return:
; CHECK: %switch.gep = getelementptr inbounds [7 x i32]* @switch.table5, i32 0, i32 %switch.tableidx
}
-define i32 @unreachable(i32 %x) {
+define i32 @unreachable_case(i32 %x) {
entry:
switch i32 %x, label %sw.default [
i32 0, label %sw.bb
@@ -770,19 +770,47 @@ sw.bb: br label %return
sw.bb1: unreachable
sw.bb2: br label %return
sw.bb3: br label %return
-sw.default: unreachable
+sw.default: br label %return
return:
- %retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ]
+ %retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ], [ 2, %sw.default ]
ret i32 %retval.0
-; CHECK-LABEL: @unreachable(
+; CHECK-LABEL: @unreachable_case(
; CHECK: switch.lookup:
-; CHECK: getelementptr inbounds [5 x i32]* @switch.table6, i32 0, i32 %switch.tableidx
+; CHECK: getelementptr inbounds [9 x i32]* @switch.table6, i32 0, i32 %switch.tableidx
+}
+
+define i32 @unreachable_default(i32 %x) {
+entry:
+ switch i32 %x, label %default [
+ i32 0, label %bb0
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ ]
+
+bb0: br label %return
+bb1: br label %return
+bb2: br label %return
+bb3: br label %return
+default: unreachable
+
+return:
+ %retval = phi i32 [ 42, %bb0 ], [ 52, %bb1 ], [ 1, %bb2 ], [ 2, %bb3 ]
+ ret i32 %retval
+
+; CHECK-LABEL: @unreachable_default(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
+; CHECK-NOT: icmp
+; CHECK-NOT: br 1i
+; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i32]* @switch.table7, i32 0, i32 %switch.tableidx
+; CHECK-NEXT: %switch.load = load i32* %switch.gep
+; CHECK-NEXT: ret i32 %switch.load
}
; Don't create a table with illegal type
-; rdar://12779436
define i96 @illegaltype(i32 %c) {
entry:
switch i32 %c, label %sw.default [
@@ -1078,3 +1106,170 @@ return:
; CHECK-NEXT: ret i8 %switch.idx.cast
}
+; Reuse the inverted table range compare.
+define i32 @reuse_cmp1(i32 %x) {
+entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+sw.bb1: br label %sw.epilog
+sw.bb2: br label %sw.epilog
+sw.bb3: br label %sw.epilog
+sw.default: br label %sw.epilog
+sw.epilog:
+ %r.0 = phi i32 [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
+ %cmp = icmp eq i32 %r.0, 0 ; This compare can be "replaced".
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @reuse_cmp1(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
+; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
+; CHECK-NEXT: %inverted.cmp = xor i1 [[C]], true
+; CHECK: [[R:%.+]] = select i1 %inverted.cmp, i32 100, i32 {{.*}}
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+; Reuse the table range compare.
+define i32 @reuse_cmp2(i32 %x) {
+entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+sw.bb1: br label %sw.epilog
+sw.bb2: br label %sw.epilog
+sw.bb3: br label %sw.epilog
+sw.default: br label %sw.epilog
+sw.epilog:
+ %r.0 = phi i32 [ 4, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %sw.bb ]
+ %cmp = icmp ne i32 %r.0, 4 ; This compare can be "replaced".
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @reuse_cmp2(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
+; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
+; CHECK: [[R:%.+]] = select i1 [[C]], i32 {{.*}}, i32 100
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+; Cannot reuse the table range compare, because the default value is the same
+; as one of the case values.
+define i32 @no_reuse_cmp(i32 %x) {
+entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+sw.bb1: br label %sw.epilog
+sw.bb2: br label %sw.epilog
+sw.bb3: br label %sw.epilog
+sw.default: br label %sw.epilog
+sw.epilog:
+ %r.0 = phi i32 [ 12, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
+ %cmp = icmp ne i32 %r.0, 0
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @no_reuse_cmp(
+; CHECK: [[S:%.+]] = select
+; CHECK-NEXT: %cmp = icmp ne i32 [[S]], 0
+; CHECK-NEXT: [[R:%.+]] = select i1 %cmp, i32 [[S]], i32 100
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+; Cannot reuse the table range compare, because the phi at the switch merge
+; point is not dominated by the switch.
+define i32 @no_reuse_cmp2(i32 %x, i32 %y) {
+entry:
+ %ec = icmp ne i32 %y, 0
+ br i1 %ec, label %switch.entry, label %sw.epilog
+switch.entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+sw.bb1: br label %sw.epilog
+sw.bb2: br label %sw.epilog
+sw.bb3: br label %sw.epilog
+sw.default: br label %sw.epilog
+sw.epilog:
+ %r.0 = phi i32 [100, %entry], [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
+ %cmp = icmp eq i32 %r.0, 0 ; This compare can be "replaced".
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @no_reuse_cmp2(
+; CHECK: %r.0 = phi
+; CHECK-NEXT: %cmp = icmp eq i32 %r.0, 0
+; CHECK-NEXT: [[R:%.+]] = select i1 %cmp
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+define void @pr20210(i8 %x, i1 %y) {
+; %z has uses outside of its BB or the phi it feeds into,
+; so doing a table lookup and jumping directly to while.cond would
+; cause %z to cease dominating all its uses.
+
+entry:
+ br i1 %y, label %sw, label %intermediate
+
+sw:
+ switch i8 %x, label %end [
+ i8 7, label %intermediate
+ i8 3, label %intermediate
+ i8 2, label %intermediate
+ i8 1, label %intermediate
+ i8 0, label %intermediate
+ ]
+
+intermediate:
+ %z = zext i8 %x to i32
+ br label %while.cond
+
+while.cond:
+ %i = phi i32 [ %z, %intermediate ], [ %j, %while.body ]
+ %b = icmp ne i32 %i, 7
+ br i1 %b, label %while.body, label %while.end
+
+while.body:
+ %j = add i32 %i, 1
+ br label %while.cond
+
+while.end:
+ call void @exit(i32 %z)
+ unreachable
+
+end:
+ ret void
+; CHECK-LABEL: @pr20210
+; CHECK: switch i8 %x
+}
diff --git a/test/Transforms/SimplifyCFG/basictest.ll b/test/Transforms/SimplifyCFG/basictest.ll
index d6958a9..5d9dad4 100644
--- a/test/Transforms/SimplifyCFG/basictest.ll
+++ b/test/Transforms/SimplifyCFG/basictest.ll
@@ -1,6 +1,7 @@
; Test CFG simplify removal of branch instructions.
;
; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; RUN: opt < %s -passes=simplify-cfg -S | FileCheck %s
define void @test1() {
br label %1
@@ -68,6 +69,6 @@ bb3:
}
declare i8 @test6g(i8*)
-!0 = metadata !{metadata !1, metadata !1, i64 0}
-!1 = metadata !{metadata !"foo"}
-!2 = metadata !{i8 0, i8 2}
+!0 = !{!1, !1, i64 0}
+!1 = !{!"foo"}
+!2 = !{i8 0, i8 2}
diff --git a/test/Transforms/SimplifyCFG/branch-fold-dbg.ll b/test/Transforms/SimplifyCFG/branch-fold-dbg.ll
index 9235f62..f715a0c 100644
--- a/test/Transforms/SimplifyCFG/branch-fold-dbg.ll
+++ b/test/Transforms/SimplifyCFG/branch-fold-dbg.ll
@@ -25,7 +25,7 @@ BB2: ; preds = %BB1
BB3: ; preds = %BB2
%6 = getelementptr inbounds [5 x %0]* @0, i32 0, i32 %0, !dbg !6
- call void @llvm.dbg.value(metadata !{%0* %6}, i64 0, metadata !7, metadata !{}), !dbg !12
+ call void @llvm.dbg.value(metadata %0* %6, i64 0, metadata !7, metadata !{}), !dbg !12
%7 = icmp eq %0* %6, null, !dbg !13
br i1 %7, label %BB5, label %BB4, !dbg !13
@@ -41,19 +41,19 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\00231\000\001\000\006\00256\000\000", metadata !15, metadata !1, metadata !3, null, void (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 231] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !15} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang (trunk 129006)\001\00\000\00\000", metadata !15, metadata !4, metadata !4, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !15, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{i32 131, i32 2, metadata !0, null}
-!6 = metadata !{i32 134, i32 2, metadata !0, null}
-!7 = metadata !{metadata !"0x100\00bar\00232\000", metadata !8, metadata !1, metadata !9} ; [ DW_TAG_auto_variable ]
-!8 = metadata !{metadata !"0xb\00231\001\003", metadata !15, metadata !0} ; [ DW_TAG_lexical_block ]
-!9 = metadata !{metadata !"0xf\00\000\0032\0032\000\000", null, metadata !2, metadata !10} ; [ DW_TAG_pointer_type ]
-!10 = metadata !{metadata !"0x26\00\000\000\000\000\000", null, metadata !2, metadata !11} ; [ DW_TAG_const_type ]
-!11 = metadata !{metadata !"0x24\00unsigned int\000\0032\0032\000\000\007", null, metadata !2} ; [ DW_TAG_base_type ]
-!12 = metadata !{i32 232, i32 40, metadata !8, null}
-!13 = metadata !{i32 234, i32 2, metadata !8, null}
-!14 = metadata !{i32 274, i32 1, metadata !8, null}
-!15 = metadata !{metadata !"a.c", metadata !"/private/tmp"}
+!0 = !{!"0x2e\00foo\00foo\00\00231\000\001\000\006\00256\000\000", !15, !1, !3, null, void (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 231] [def] [scope 0] [foo]
+!1 = !{!"0x29", !15} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang (trunk 129006)\001\00\000\00\000", !15, !4, !4, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !15, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !MDLocation(line: 131, column: 2, scope: !0)
+!6 = !MDLocation(line: 134, column: 2, scope: !0)
+!7 = !{!"0x100\00bar\00232\000", !8, !1, !9} ; [ DW_TAG_auto_variable ]
+!8 = !{!"0xb\00231\001\003", !15, !0} ; [ DW_TAG_lexical_block ]
+!9 = !{!"0xf\00\000\0032\0032\000\000", null, !2, !10} ; [ DW_TAG_pointer_type ]
+!10 = !{!"0x26\00\000\000\000\000\000", null, !2, !11} ; [ DW_TAG_const_type ]
+!11 = !{!"0x24\00unsigned int\000\0032\0032\000\000\007", null, !2} ; [ DW_TAG_base_type ]
+!12 = !MDLocation(line: 232, column: 40, scope: !8)
+!13 = !MDLocation(line: 234, column: 2, scope: !8)
+!14 = !MDLocation(line: 274, column: 1, scope: !8)
+!15 = !{!"a.c", !"/private/tmp"}
diff --git a/test/Transforms/SimplifyCFG/clamp.ll b/test/Transforms/SimplifyCFG/clamp.ll
new file mode 100644
index 0000000..d21894a
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/clamp.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+define float @clamp(float %a, float %b, float %c) {
+; CHECK-LABEL: @clamp
+; CHECK: %cmp = fcmp ogt float %a, %c
+; CHECK: %cmp1 = fcmp olt float %a, %b
+; CHECK: %cond = select i1 %cmp1, float %b, float %a
+; CHECK: %cond5 = select i1 %cmp, float %c, float %cond
+; CHECK: ret float %cond5
+entry:
+ %cmp = fcmp ogt float %a, %c
+ br i1 %cmp, label %cond.end4, label %cond.false
+
+cond.false: ; preds = %entry
+ %cmp1 = fcmp olt float %a, %b
+ %cond = select i1 %cmp1, float %b, float %a
+ br label %cond.end4
+
+cond.end4: ; preds = %entry, %cond.false
+ %cond5 = phi float [ %cond, %cond.false ], [ %c, %entry ]
+ ret float %cond5
+}
diff --git a/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll b/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll
index cc382be..869ce09 100644
--- a/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll
+++ b/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll
@@ -1,8 +1,8 @@
; RUN: opt -simplifycfg -S < %s | FileCheck %s
define i32 @foo(i32 %i) nounwind ssp {
- call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !6, metadata !{}), !dbg !7
- call void @llvm.dbg.value(metadata !8, i64 0, metadata !9, metadata !{}), !dbg !11
+ call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !6, metadata !{}), !dbg !7
+ call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !9, metadata !{}), !dbg !11
%1 = icmp ne i32 %i, 0, !dbg !12
;CHECK: call i32 (...)* @bar()
;CHECK-NEXT: llvm.dbg.value
@@ -10,12 +10,12 @@ define i32 @foo(i32 %i) nounwind ssp {
; <label>:2 ; preds = %0
%3 = call i32 (...)* @bar(), !dbg !13
- call void @llvm.dbg.value(metadata !{i32 %3}, i64 0, metadata !9, metadata !{}), !dbg !13
+ call void @llvm.dbg.value(metadata i32 %3, i64 0, metadata !9, metadata !{}), !dbg !13
br label %6, !dbg !15
; <label>:4 ; preds = %0
%5 = call i32 (...)* @bar(), !dbg !16
- call void @llvm.dbg.value(metadata !{i32 %5}, i64 0, metadata !9, metadata !{}), !dbg !16
+ call void @llvm.dbg.value(metadata i32 %5, i64 0, metadata !9, metadata !{}), !dbg !16
br label %6, !dbg !18
; <label>:6 ; preds = %4, %2
@@ -32,25 +32,25 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.module.flags = !{!21}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\002\000\001\000\006\00256\000\000", metadata !20, metadata !1, metadata !3, null, i32 (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 2] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !20} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang\001\00\000\00\000", metadata !20, metadata !8, metadata !8, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !20, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !2} ; [ DW_TAG_base_type ]
-!6 = metadata !{metadata !"0x101\00i\0016777218\000", metadata !0, metadata !1, metadata !5} ; [ DW_TAG_arg_variable ]
-!7 = metadata !{i32 2, i32 13, metadata !0, null}
-!8 = metadata !{i32 0}
-!9 = metadata !{metadata !"0x100\00k\003\000", metadata !10, metadata !1, metadata !5} ; [ DW_TAG_auto_variable ]
-!10 = metadata !{metadata !"0xb\002\0016\000", metadata !20, metadata !0} ; [ DW_TAG_lexical_block ]
-!11 = metadata !{i32 3, i32 12, metadata !10, null}
-!12 = metadata !{i32 4, i32 3, metadata !10, null}
-!13 = metadata !{i32 5, i32 5, metadata !14, null}
-!14 = metadata !{metadata !"0xb\004\0010\001", metadata !20, metadata !10} ; [ DW_TAG_lexical_block ]
-!15 = metadata !{i32 6, i32 3, metadata !14, null}
-!16 = metadata !{i32 7, i32 5, metadata !17, null}
-!17 = metadata !{metadata !"0xb\006\0010\002", metadata !20, metadata !10} ; [ DW_TAG_lexical_block ]
-!18 = metadata !{i32 8, i32 3, metadata !17, null}
-!19 = metadata !{i32 9, i32 3, metadata !10, null}
-!20 = metadata !{metadata !"b.c", metadata !"/private/tmp"}
-!21 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00\002\000\001\000\006\00256\000\000", !20, !1, !3, null, i32 (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 2] [def] [scope 0] [foo]
+!1 = !{!"0x29", !20} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang\001\00\000\00\000", !20, !8, !8, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !20, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{!5}
+!5 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !2} ; [ DW_TAG_base_type ]
+!6 = !{!"0x101\00i\0016777218\000", !0, !1, !5} ; [ DW_TAG_arg_variable ]
+!7 = !MDLocation(line: 2, column: 13, scope: !0)
+!8 = !{i32 0}
+!9 = !{!"0x100\00k\003\000", !10, !1, !5} ; [ DW_TAG_auto_variable ]
+!10 = !{!"0xb\002\0016\000", !20, !0} ; [ DW_TAG_lexical_block ]
+!11 = !MDLocation(line: 3, column: 12, scope: !10)
+!12 = !MDLocation(line: 4, column: 3, scope: !10)
+!13 = !MDLocation(line: 5, column: 5, scope: !14)
+!14 = !{!"0xb\004\0010\001", !20, !10} ; [ DW_TAG_lexical_block ]
+!15 = !MDLocation(line: 6, column: 3, scope: !14)
+!16 = !MDLocation(line: 7, column: 5, scope: !17)
+!17 = !{!"0xb\006\0010\002", !20, !10} ; [ DW_TAG_lexical_block ]
+!18 = !MDLocation(line: 8, column: 3, scope: !17)
+!19 = !MDLocation(line: 9, column: 3, scope: !10)
+!20 = !{!"b.c", !"/private/tmp"}
+!21 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SimplifyCFG/hoist-with-range.ll b/test/Transforms/SimplifyCFG/hoist-with-range.ll
index 362aa9a..7ca3ff2 100644
--- a/test/Transforms/SimplifyCFG/hoist-with-range.ll
+++ b/test/Transforms/SimplifyCFG/hoist-with-range.ll
@@ -3,7 +3,7 @@
define void @foo(i1 %c, i8* %p) {
; CHECK: if:
; CHECK-NEXT: load i8* %p, !range !0
-; CHECK: !0 = metadata !{i8 0, i8 1, i8 3, i8 5}
+; CHECK: !0 = !{i8 0, i8 1, i8 3, i8 5}
if:
br i1 %c, label %then, label %else
then:
@@ -16,5 +16,5 @@ out:
ret void
}
-!0 = metadata !{ i8 0, i8 1 }
-!1 = metadata !{ i8 3, i8 5 }
+!0 = !{ i8 0, i8 1 }
+!1 = !{ i8 3, i8 5 }
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll b/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll
index 8cc07e3..b2b3841 100644
--- a/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll
@@ -34,4 +34,4 @@ if.end:
ret void
}
-!0 = metadata !{metadata !"branch_weights", i32 1, i32 0}
+!0 = !{!"branch_weights", i32 1, i32 0}
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll b/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll
index 941f5ad..32a30c3 100644
--- a/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll
@@ -129,12 +129,12 @@ sw.epilog:
ret void
}
-!0 = metadata !{metadata !"branch_weights", i32 64, i32 4}
-!1 = metadata !{metadata !"branch_weights", i32 4, i32 64}
-; CHECK: !0 = metadata !{metadata !"branch_weights", i32 256, i32 4352, i32 16}
-!2 = metadata !{metadata !"branch_weights", i32 4, i32 4, i32 8}
-!3 = metadata !{metadata !"branch_weights", i32 8, i32 8, i32 4}
-; CHECK: !1 = metadata !{metadata !"branch_weights", i32 32, i32 48, i32 96, i32 16}
-!4 = metadata !{metadata !"branch_weights", i32 7, i32 6, i32 4, i32 3}
-!5 = metadata !{metadata !"branch_weights", i32 17, i32 13, i32 9}
-; CHECK: !3 = metadata !{metadata !"branch_weights", i32 7, i32 3, i32 4, i32 6}
+!0 = !{!"branch_weights", i32 64, i32 4}
+!1 = !{!"branch_weights", i32 4, i32 64}
+; CHECK: !0 = !{!"branch_weights", i32 256, i32 4352, i32 16}
+!2 = !{!"branch_weights", i32 4, i32 4, i32 8}
+!3 = !{!"branch_weights", i32 8, i32 8, i32 4}
+; CHECK: !1 = !{!"branch_weights", i32 32, i32 48, i32 96, i32 16}
+!4 = !{!"branch_weights", i32 7, i32 6, i32 4, i32 3}
+!5 = !{!"branch_weights", i32 17, i32 13, i32 9}
+; CHECK: !3 = !{!"branch_weights", i32 7, i32 3, i32 4, i32 6}
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/test/Transforms/SimplifyCFG/preserve-branchweights.ll
index bdd25ba..7802a05 100644
--- a/test/Transforms/SimplifyCFG/preserve-branchweights.ll
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights.ll
@@ -364,29 +364,29 @@ for.exit:
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}
-!3 = metadata !{metadata !"branch_weights", i32 4, i32 3, i32 2, i32 1}
-!4 = metadata !{metadata !"branch_weights", i32 4, i32 3, i32 2, i32 1}
-!5 = metadata !{metadata !"branch_weights", i32 7, i32 6, i32 5}
-!6 = metadata !{metadata !"branch_weights", i32 1, i32 3}
-!7 = metadata !{metadata !"branch_weights", i32 33, i32 9, i32 8, i32 7}
-!8 = metadata !{metadata !"branch_weights", i32 33, i32 9, i32 8}
-!9 = metadata !{metadata !"branch_weights", i32 7, i32 6}
-!10 = metadata !{metadata !"branch_weights", i32 672646, i32 21604207}
-!11 = metadata !{metadata !"branch_weights", i32 6960, i32 21597248}
-
-; CHECK: !0 = metadata !{metadata !"branch_weights", i32 5, i32 11}
-; CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 5}
-; CHECK: !2 = metadata !{metadata !"branch_weights", i32 7, i32 1, i32 2}
-; CHECK: !3 = metadata !{metadata !"branch_weights", i32 49, i32 12, i32 24, i32 35}
-; CHECK: !4 = metadata !{metadata !"branch_weights", i32 11, i32 5}
-; CHECK: !5 = metadata !{metadata !"branch_weights", i32 17, i32 15}
-; CHECK: !6 = metadata !{metadata !"branch_weights", i32 9, i32 7}
-; CHECK: !7 = metadata !{metadata !"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
-; CHECK: !8 = metadata !{metadata !"branch_weights", i32 24, i32 33}
-; CHECK: !9 = metadata !{metadata !"branch_weights", i32 8, i32 33}
+!0 = !{!"branch_weights", i32 3, i32 5}
+!1 = !{!"branch_weights", i32 1, i32 1}
+!2 = !{!"branch_weights", i32 1, i32 2}
+!3 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
+!4 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
+!5 = !{!"branch_weights", i32 7, i32 6, i32 5}
+!6 = !{!"branch_weights", i32 1, i32 3}
+!7 = !{!"branch_weights", i32 33, i32 9, i32 8, i32 7}
+!8 = !{!"branch_weights", i32 33, i32 9, i32 8}
+!9 = !{!"branch_weights", i32 7, i32 6}
+!10 = !{!"branch_weights", i32 672646, i32 21604207}
+!11 = !{!"branch_weights", i32 6960, i32 21597248}
+
+; CHECK: !0 = !{!"branch_weights", i32 5, i32 11}
+; CHECK: !1 = !{!"branch_weights", i32 1, i32 5}
+; CHECK: !2 = !{!"branch_weights", i32 7, i32 1, i32 2}
+; CHECK: !3 = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
+; CHECK: !4 = !{!"branch_weights", i32 11, i32 5}
+; CHECK: !5 = !{!"branch_weights", i32 17, i32 15}
+; CHECK: !6 = !{!"branch_weights", i32 9, i32 7}
+; CHECK: !7 = !{!"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
+; CHECK: !8 = !{!"branch_weights", i32 24, i32 33}
+; CHECK: !9 = !{!"branch_weights", i32 8, i32 33}
;; The false weight prints out as a negative integer here, but inside llvm, we
;; treat the weight as an unsigned integer.
-; CHECK: !10 = metadata !{metadata !"branch_weights", i32 112017436, i32 -735157296}
+; CHECK: !10 = !{!"branch_weights", i32 112017436, i32 -735157296}
diff --git a/test/Transforms/SimplifyCFG/seh-nounwind.ll b/test/Transforms/SimplifyCFG/seh-nounwind.ll
new file mode 100644
index 0000000..3845e31
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/seh-nounwind.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -simplifycfg < %s | FileCheck %s
+
+; Don't remove invokes of nounwind functions if the personality handles async
+; exceptions. The @div function in this test can fault, even though it can't
+; throw a synchronous exception.
+
+define i32 @div(i32 %n, i32 %d) nounwind {
+entry:
+ %div = sdiv i32 %n, %d
+ ret i32 %div
+}
+
+define i32 @main() nounwind {
+entry:
+ %call = invoke i32 @div(i32 10, i32 0)
+ to label %__try.cont unwind label %lpad
+
+lpad:
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+ catch i8* null
+ br label %__try.cont
+
+__try.cont:
+ %retval.0 = phi i32 [ %call, %entry ], [ 0, %lpad ]
+ ret i32 %retval.0
+}
+
+; CHECK-LABEL: define i32 @main()
+; CHECK: invoke i32 @div(i32 10, i32 0)
+
+declare i32 @__C_specific_handler(...)
diff --git a/test/Transforms/SimplifyCFG/select-gep.ll b/test/Transforms/SimplifyCFG/select-gep.ll
index 96c214c..43e46ca 100644
--- a/test/Transforms/SimplifyCFG/select-gep.ll
+++ b/test/Transforms/SimplifyCFG/select-gep.ll
@@ -1,27 +1,8 @@
; RUN: opt -S -simplifycfg < %s | FileCheck %s
-define i8* @test1(i8* %x, i64 %y) nounwind {
-entry:
- %tmp1 = load i8* %x, align 1
- %cmp = icmp eq i8 %tmp1, 47
- br i1 %cmp, label %if.then, label %if.end
-
-if.then:
- %incdec.ptr = getelementptr inbounds i8* %x, i64 %y
- br label %if.end
-
-if.end:
- %x.addr = phi i8* [ %incdec.ptr, %if.then ], [ %x, %entry ]
- ret i8* %x.addr
-
-; CHECK-LABEL: @test1(
-; CHECK-NOT: select
-; CHECK: ret i8* %x.addr
-}
-
%ST = type { i8, i8 }
-define i8* @test2(%ST* %x, i8* %y) nounwind {
+define i8* @test1(%ST* %x, i8* %y) nounwind {
entry:
%cmp = icmp eq %ST* %x, null
br i1 %cmp, label %if.then, label %if.end
@@ -34,7 +15,7 @@ if.end:
%x.addr = phi i8* [ %incdec.ptr, %if.then ], [ %y, %entry ]
ret i8* %x.addr
-; CHECK-LABEL: @test2(
+; CHECK-LABEL: @test1(
; CHECK: %incdec.ptr.y = select i1 %cmp, i8* %incdec.ptr, i8* %y
; CHECK: ret i8* %incdec.ptr.y
}
diff --git a/test/Transforms/SimplifyCFG/sink-common-code.ll b/test/Transforms/SimplifyCFG/sink-common-code.ll
index 28d7279..cdb6ed2 100644
--- a/test/Transforms/SimplifyCFG/sink-common-code.ll
+++ b/test/Transforms/SimplifyCFG/sink-common-code.ll
@@ -4,7 +4,7 @@ define zeroext i1 @test1(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
entry:
br i1 %flag, label %if.then, label %if.else
-; CHECK: test1
+; CHECK-LABEL: test1
; CHECK: add
; CHECK: select
; CHECK: icmp
@@ -30,7 +30,7 @@ define zeroext i1 @test2(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
entry:
br i1 %flag, label %if.then, label %if.else
-; CHECK: test2
+; CHECK-LABEL: test2
; CHECK: add
; CHECK: select
; CHECK: icmp
@@ -51,3 +51,33 @@ if.end:
%tobool4 = icmp ne i8 %obeys.0, 0
ret i1 %tobool4
}
+
+declare i32 @foo(i32, i32) nounwind readnone
+
+define i32 @test3(i1 zeroext %flag, i32 %x, i32 %y) {
+entry:
+ br i1 %flag, label %if.then, label %if.else
+
+if.then:
+ %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
+ %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
+ br label %if.end
+
+if.else:
+ %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
+ %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
+ br label %if.end
+
+if.end:
+ %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
+ %yy = phi i32 [ %y0, %if.then ], [ %y1, %if.else ]
+ %ret = add i32 %xx, %yy
+ ret i32 %ret
+}
+
+; CHECK-LABEL: test3
+; CHECK: select
+; CHECK: call
+; CHECK: call
+; CHECK: add
+; CHECK-NOT: br
diff --git a/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll b/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
new file mode 100644
index 0000000..a109b31
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
@@ -0,0 +1,77 @@
+; RUN: opt %s -simplifycfg -S | FileCheck %s
+
+declare i32 @f(i32)
+
+define i32 @basic(i32 %x) {
+; CHECK-LABEL: @basic
+; CHECK: x.off = add i32 %x, -5
+; CHECK: %switch = icmp ult i32 %x.off, 3
+; CHECK: br i1 %switch, label %a, label %default
+
+entry:
+ switch i32 %x, label %default [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ ]
+default:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+a:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+}
+
+
+define i32 @unreachable(i32 %x) {
+; CHECK-LABEL: @unreachable
+; CHECK: x.off = add i32 %x, -5
+; CHECK: %switch = icmp ult i32 %x.off, 3
+; CHECK: br i1 %switch, label %a, label %b
+
+entry:
+ switch i32 %x, label %unreachable [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ i32 10, label %b
+ i32 20, label %b
+ i32 30, label %b
+ i32 40, label %b
+ ]
+unreachable:
+ unreachable
+a:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+b:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+}
+
+
+define i32 @unreachable2(i32 %x) {
+; CHECK-LABEL: @unreachable2
+; CHECK: x.off = add i32 %x, -5
+; CHECK: %switch = icmp ult i32 %x.off, 3
+; CHECK: br i1 %switch, label %a, label %b
+
+entry:
+ ; Note: folding the most popular case destination into the default
+ ; would prevent switch-to-icmp here.
+ switch i32 %x, label %unreachable [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ i32 10, label %b
+ i32 20, label %b
+ ]
+unreachable:
+ unreachable
+a:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+b:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+}
diff --git a/test/Transforms/SimplifyCFG/switch-to-br.ll b/test/Transforms/SimplifyCFG/switch-to-br.ll
new file mode 100644
index 0000000..01484cd
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/switch-to-br.ll
@@ -0,0 +1,64 @@
+; RUN: opt %s -simplifycfg -S | FileCheck %s
+
+declare i32 @f(i32)
+
+define i32 @basic(i32 %x) {
+; CHECK-LABEL: @basic
+; CHECK-LABEL: entry:
+; CHECK-NEXT: call i32 @f(i32 0)
+; CHECK-NEXT: ret i32 %0
+
+entry:
+ switch i32 %x, label %default [
+ i32 5, label %default
+ i32 6, label %default
+ i32 7, label %default
+ ]
+default:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+}
+
+
+define i32 @constant() {
+; CHECK-LABEL: @constant
+; CHECK-LABEL: entry:
+; CHECK-NEXT: call i32 @f(i32 1)
+; CHECK-NEXT: ret i32 %0
+
+entry:
+ switch i32 42, label %default [
+ i32 41, label %default
+ i32 42, label %a
+ i32 43, label %b
+ ]
+default:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+a:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+b:
+ %2 = call i32 @f(i32 2)
+ ret i32 %2
+}
+
+
+define i32 @unreachable(i32 %x) {
+; CHECK-LABEL: @unreachable
+; CHECK-LABEL: entry:
+; CHECK-NEXT: call i32 @f(i32 0)
+; CHECK-NEXT: ret i32 %0
+
+entry:
+ switch i32 %x, label %unreachable [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ ]
+unreachable:
+ unreachable
+a:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+}
diff --git a/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 69f97e5..f4d171a 100644
--- a/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -35,38 +35,3 @@ return:
%retval.0 = phi i32 [ 4, %sw.epilog ], [ 2, %sw.bb1 ], [ 10, %sw.bb ]
ret i32 %retval.0
}
-
-; int foo1_without_default(int a) {
-; switch(a) {
-; case 10:
-; return 10;
-; case 20:
-; return 2;
-; }
-; __builtin_unreachable();
-; }
-
-define i32 @foo1_without_default(i32 %a) {
-; CHECK-LABEL: @foo1_without_default
-; CHECK: %switch.selectcmp = icmp eq i32 %a, 10
-; CHECK-NEXT: %switch.select = select i1 %switch.selectcmp, i32 10, i32 2
-; CHECK-NOT: %switch.selectcmp1
-entry:
- switch i32 %a, label %sw.epilog [
- i32 10, label %sw.bb
- i32 20, label %sw.bb1
- ]
-
-sw.bb:
- br label %return
-
-sw.bb1:
- br label %return
-
-sw.epilog:
- unreachable
-
-return:
- %retval.0 = phi i32 [ 2, %sw.bb1 ], [ 10, %sw.bb ]
- ret i32 %retval.0
-}
diff --git a/test/Transforms/SimplifyCFG/trap-debugloc.ll b/test/Transforms/SimplifyCFG/trap-debugloc.ll
index adf4215..24a286f 100644
--- a/test/Transforms/SimplifyCFG/trap-debugloc.ll
+++ b/test/Transforms/SimplifyCFG/trap-debugloc.ll
@@ -11,14 +11,14 @@ define void @foo() nounwind ssp {
!llvm.module.flags = !{!10}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\003\000\001\000\006\000\000\000", metadata !8, metadata !1, metadata !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !8} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00Apple clang version 3.0 (tags/Apple/clang-206.1) (based on LLVM 3.0svn)\001\00\000\00\000", metadata !8, metadata !4, metadata !4, metadata !9, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !8, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{i32 4, i32 2, metadata !6, null}
-!6 = metadata !{metadata !"0xb\003\0012\000", metadata !8, metadata !0} ; [ DW_TAG_lexical_block ]
-!7 = metadata !{i32 5, i32 1, metadata !6, null}
-!8 = metadata !{metadata !"foo.c", metadata !"/private/tmp"}
-!9 = metadata !{metadata !0}
-!10 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00\003\000\001\000\006\000\000\000", !8, !1, !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 0] [foo]
+!1 = !{!"0x29", !8} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00Apple clang version 3.0 (tags/Apple/clang-206.1) (based on LLVM 3.0svn)\001\00\000\00\000", !8, !4, !4, !9, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !8, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !MDLocation(line: 4, column: 2, scope: !6)
+!6 = !{!"0xb\003\0012\000", !8, !0} ; [ DW_TAG_lexical_block ]
+!7 = !MDLocation(line: 5, column: 1, scope: !6)
+!8 = !{!"foo.c", !"/private/tmp"}
+!9 = !{!0}
+!10 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SimplifyCFG/trivial-throw.ll b/test/Transforms/SimplifyCFG/trivial-throw.ll
deleted file mode 100644
index ca2b569..0000000
--- a/test/Transforms/SimplifyCFG/trivial-throw.ll
+++ /dev/null
@@ -1,77 +0,0 @@
-; RUN: opt -simplifycfg -S < %s | FileCheck %s
-; <rdar://problem/13360379>
-
-@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
-@_ZTS13TestException = linkonce_odr constant [16 x i8] c"13TestException\00"
-@_ZTI13TestException = linkonce_odr unnamed_addr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([16 x i8]* @_ZTS13TestException, i32 0, i32 0) }
-
-define void @throw(i32 %n) #0 {
-entry:
- %exception = call i8* @__cxa_allocate_exception(i64 1) #4
- call void @__cxa_throw(i8* %exception, i8* bitcast ({ i8*, i8* }* @_ZTI13TestException to i8*), i8* null) #2
- unreachable
-}
-
-define void @func() #0 {
-entry:
-; CHECK: func()
-; CHECK: invoke void @throw
-; CHECK-NOT: call void @throw
- invoke void @throw(i32 42) #0
- to label %exit unwind label %lpad
-
-lpad:
- %tmp0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- cleanup
- resume { i8*, i32 } %tmp0
-
-exit:
- invoke void @abort() #2
- to label %invoke.cont unwind label %lpad1
-
-invoke.cont:
- unreachable
-
-lpad1:
- %tmp1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- catch i8* bitcast ({ i8*, i8* }* @_ZTI13TestException to i8*)
- %tmp2 = extractvalue { i8*, i32 } %tmp1, 1
- %tmp3 = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI13TestException to i8*)) #4
- %matches = icmp eq i32 %tmp2, %tmp3
- br i1 %matches, label %catch, label %eh.resume
-
-catch:
- ret void
-
-eh.resume:
- resume { i8*, i32 } %tmp1
-}
-
-define linkonce_odr hidden void @__clang_call_terminate(i8*) #1 {
- %2 = call i8* @__cxa_begin_catch(i8* %0) #4
- call void @_ZSt9terminatev() #5
- unreachable
-}
-
-declare void @abort() #2
-
-declare i32 @llvm.eh.typeid.for(i8*) #3
-
-declare void @__cxa_end_catch()
-
-declare i8* @__cxa_allocate_exception(i64)
-
-declare i32 @__gxx_personality_v0(...)
-
-declare void @__cxa_throw(i8*, i8*, i8*)
-
-declare i8* @__cxa_begin_catch(i8*)
-
-declare void @_ZSt9terminatev()
-
-attributes #0 = { ssp uwtable }
-attributes #1 = { noinline noreturn nounwind }
-attributes #2 = { noreturn }
-attributes #3 = { nounwind readnone }
-attributes #4 = { nounwind }
-attributes #5 = { noreturn nounwind }
diff --git a/test/Transforms/SimplifyCFG/volatile-phioper.ll b/test/Transforms/SimplifyCFG/volatile-phioper.ll
index 1ef3a7c..6367451 100644
--- a/test/Transforms/SimplifyCFG/volatile-phioper.ll
+++ b/test/Transforms/SimplifyCFG/volatile-phioper.ll
@@ -45,4 +45,4 @@ attributes #0 = { nounwind ssp uwtable "fp-contract-model"="standard" "no-frame-
attributes #1 = { "fp-contract-model"="standard" "no-frame-pointer-elim" "no-frame-pointer-elim-non-leaf" "relocation-model"="pic" "ssp-buffers-size"="8" }
attributes #2 = { nounwind }
-!0 = metadata !{i32 1039}
+!0 = !{i32 1039}
diff --git a/test/Transforms/StraightLineStrengthReduce/slsr.ll b/test/Transforms/StraightLineStrengthReduce/slsr.ll
new file mode 100644
index 0000000..951cbb0
--- /dev/null
+++ b/test/Transforms/StraightLineStrengthReduce/slsr.ll
@@ -0,0 +1,119 @@
+; RUN: opt < %s -slsr -gvn -dce -S | FileCheck %s
+
+declare i32 @foo(i32 %a)
+
+define i32 @slsr1(i32 %b, i32 %s) {
+; CHECK-LABEL: @slsr1(
+ ; v0 = foo(b * s);
+ %mul0 = mul i32 %b, %s
+; CHECK: mul i32
+; CHECK-NOT: mul i32
+ %v0 = call i32 @foo(i32 %mul0)
+
+ ; v1 = foo((b + 1) * s);
+ %b1 = add i32 %b, 1
+ %mul1 = mul i32 %b1, %s
+ %v1 = call i32 @foo(i32 %mul1)
+
+ ; v2 = foo((b + 2) * s);
+ %b2 = add i32 %b, 2
+ %mul2 = mul i32 %b2, %s
+ %v2 = call i32 @foo(i32 %mul2)
+
+ ; return v0 + v1 + v2;
+ %1 = add i32 %v0, %v1
+ %2 = add i32 %1, %v2
+ ret i32 %2
+}
+
+; v0 = foo(a * b)
+; v1 = foo((a + 1) * b)
+; v2 = foo(a * (b + 1))
+; v3 = foo((a + 1) * (b + 1))
+define i32 @slsr2(i32 %a, i32 %b) {
+; CHECK-LABEL: @slsr2(
+ %a1 = add i32 %a, 1
+ %b1 = add i32 %b, 1
+ %mul0 = mul i32 %a, %b
+; CHECK: mul i32
+; CHECK-NOT: mul i32
+ %mul1 = mul i32 %a1, %b
+ %mul2 = mul i32 %a, %b1
+ %mul3 = mul i32 %a1, %b1
+
+ %v0 = call i32 @foo(i32 %mul0)
+ %v1 = call i32 @foo(i32 %mul1)
+ %v2 = call i32 @foo(i32 %mul2)
+ %v3 = call i32 @foo(i32 %mul3)
+
+ %1 = add i32 %v0, %v1
+ %2 = add i32 %1, %v2
+ %3 = add i32 %2, %v3
+ ret i32 %3
+}
+
+; The bump is a multiple of the stride.
+;
+; v0 = foo(b * s);
+; v1 = foo((b + 2) * s);
+; v2 = foo((b + 4) * s);
+; return v0 + v1 + v2;
+;
+; ==>
+;
+; mul0 = b * s;
+; v0 = foo(mul0);
+; bump = s * 2;
+; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump.
+; v1 = foo(mul1);
+; mul2 = mul1 + bump;
+; v2 = foo(mul2);
+; return v0 + v1 + v2;
+define i32 @slsr3(i32 %b, i32 %s) {
+; CHECK-LABEL: @slsr3(
+ %mul0 = mul i32 %b, %s
+; CHECK: mul i32
+ %v0 = call i32 @foo(i32 %mul0)
+
+ %b1 = add i32 %b, 2
+ %mul1 = mul i32 %b1, %s
+; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i32 %s, 2
+; CHECK: %mul1 = add i32 %mul0, [[BUMP]]
+ %v1 = call i32 @foo(i32 %mul1)
+
+ %b2 = add i32 %b, 4
+ %mul2 = mul i32 %b2, %s
+; CHECK: %mul2 = add i32 %mul1, [[BUMP]]
+ %v2 = call i32 @foo(i32 %mul2)
+
+ %1 = add i32 %v0, %v1
+ %2 = add i32 %1, %v2
+ ret i32 %2
+}
+
+; Do not rewrite a candidate if its potential basis does not dominate it.
+; v0 = 0;
+; if (cond)
+; v0 = foo(a * b);
+; v1 = foo((a + 1) * b);
+; return v0 + v1;
+define i32 @not_dominate(i1 %cond, i32 %a, i32 %b) {
+; CHECK-LABEL: @not_dominate(
+entry:
+ %a1 = add i32 %a, 1
+ br i1 %cond, label %then, label %merge
+
+then:
+ %mul0 = mul i32 %a, %b
+; CHECK: %mul0 = mul i32 %a, %b
+ %v0 = call i32 @foo(i32 %mul0)
+ br label %merge
+
+merge:
+ %v0.phi = phi i32 [ 0, %entry ], [ %mul0, %then ]
+ %mul1 = mul i32 %a1, %b
+; CHECK: %mul1 = mul i32 %a1, %b
+ %v1 = call i32 @foo(i32 %mul1)
+ %sum = add i32 %v0.phi, %v1
+ ret i32 %sum
+}
diff --git a/test/Transforms/StripSymbols/2010-06-30-StripDebug.ll b/test/Transforms/StripSymbols/2010-06-30-StripDebug.ll
index 6100a6a..f2c705a 100644
--- a/test/Transforms/StripSymbols/2010-06-30-StripDebug.ll
+++ b/test/Transforms/StripSymbols/2010-06-30-StripDebug.ll
@@ -6,7 +6,7 @@
define void @foo() nounwind readnone optsize ssp {
entry:
- tail call void @llvm.dbg.value(metadata !9, i64 0, metadata !5, metadata !{}), !dbg !10
+ tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !5, metadata !{}), !dbg !10
ret void, !dbg !11
}
@@ -18,17 +18,17 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.lv.foo = !{!5}
!llvm.dbg.gv = !{!8}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00foo\002\000\001\000\006\000\001\000", metadata !12, metadata !1, metadata !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ]
-!1 = metadata !{metadata !"0x29", metadata !12} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", metadata !12, metadata !4, metadata !4, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !12, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{metadata !"0x100\00y\003\000", metadata !6, metadata !1, metadata !7} ; [ DW_TAG_auto_variable ]
-!6 = metadata !{metadata !"0xb\002\000\000", metadata !12, metadata !0} ; [ DW_TAG_lexical_block ]
-!7 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", metadata !12, metadata !1} ; [ DW_TAG_base_type ]
-!8 = metadata !{metadata !"0x34\00x\00x\00\001\000\001", metadata !1, metadata !1, metadata !7, i32* @x} ; [ DW_TAG_variable ]
-!9 = metadata !{i32 0}
-!10 = metadata !{i32 3, i32 0, metadata !6, null}
-!11 = metadata !{i32 4, i32 0, metadata !6, null}
-!12 = metadata !{metadata !"b.c", metadata !"/tmp"}
-!13 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00foo\002\000\001\000\006\000\001\000", !12, !1, !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ]
+!1 = !{!"0x29", !12} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\000", !12, !4, !4, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !12, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !{!"0x100\00y\003\000", !6, !1, !7} ; [ DW_TAG_auto_variable ]
+!6 = !{!"0xb\002\000\000", !12, !0} ; [ DW_TAG_lexical_block ]
+!7 = !{!"0x24\00int\000\0032\0032\000\000\005", !12, !1} ; [ DW_TAG_base_type ]
+!8 = !{!"0x34\00x\00x\00\001\000\001", !1, !1, !7, i32* @x} ; [ DW_TAG_variable ]
+!9 = !{i32 0}
+!10 = !MDLocation(line: 3, scope: !6)
+!11 = !MDLocation(line: 4, scope: !6)
+!12 = !{!"b.c", !"/tmp"}
+!13 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/StripSymbols/2010-08-25-crash.ll b/test/Transforms/StripSymbols/2010-08-25-crash.ll
index c211dc1..1534647 100644
--- a/test/Transforms/StripSymbols/2010-08-25-crash.ll
+++ b/test/Transforms/StripSymbols/2010-08-25-crash.ll
@@ -7,18 +7,18 @@ entry:
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!14}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00foo\003\000\001\000\006\000\000\000", metadata !10, metadata !1, metadata !3, null, i32 ()* @foo, null, null, null} ; [ DW_TAG_subprogram ]
-!1 = metadata !{metadata !"0x29", metadata !10} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang version 2.8 (trunk 112062)\001\00\000\00\001", metadata !10, metadata !11, metadata !11, metadata !12, metadata !13, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !10, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", metadata !10, metadata !1} ; [ DW_TAG_base_type ]
-!6 = metadata !{metadata !"0x34\00i\00i\00i\002\001\001", metadata !1, metadata !1, metadata !7, i32 0, null} ; [ DW_TAG_variable ]
-!7 = metadata !{metadata !"0x26\00\000\000\000\000\000", metadata !10, metadata !1, metadata !5} ; [ DW_TAG_const_type ]
-!8 = metadata !{i32 3, i32 13, metadata !9, null}
-!9 = metadata !{metadata !"0xb\003\0011\000", metadata !10, metadata !0} ; [ DW_TAG_lexical_block ]
-!10 = metadata !{metadata !"/tmp/a.c", metadata !"/Volumes/Lalgate/clean/D.CW"}
-!11 = metadata !{i32 0}
-!12 = metadata !{metadata !0}
-!13 = metadata !{metadata !6}
-!14 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00foo\003\000\001\000\006\000\000\000", !10, !1, !3, null, i32 ()* @foo, null, null, null} ; [ DW_TAG_subprogram ]
+!1 = !{!"0x29", !10} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang version 2.8 (trunk 112062)\001\00\000\00\001", !10, !11, !11, !12, !13, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !10, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{!5}
+!5 = !{!"0x24\00int\000\0032\0032\000\000\005", !10, !1} ; [ DW_TAG_base_type ]
+!6 = !{!"0x34\00i\00i\00i\002\001\001", !1, !1, !7, i32 0, null} ; [ DW_TAG_variable ]
+!7 = !{!"0x26\00\000\000\000\000\000", !10, !1, !5} ; [ DW_TAG_const_type ]
+!8 = !MDLocation(line: 3, column: 13, scope: !9)
+!9 = !{!"0xb\003\0011\000", !10, !0} ; [ DW_TAG_lexical_block ]
+!10 = !{!"/tmp/a.c", !"/Volumes/Lalgate/clean/D.CW"}
+!11 = !{i32 0}
+!12 = !{!0}
+!13 = !{!6}
+!14 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/StripSymbols/strip-dead-debug-info.ll b/test/Transforms/StripSymbols/strip-dead-debug-info.ll
index 04a3f32..aca7cd6 100644
--- a/test/Transforms/StripSymbols/strip-dead-debug-info.ll
+++ b/test/Transforms/StripSymbols/strip-dead-debug-info.ll
@@ -18,7 +18,7 @@ entry:
; Function Attrs: nounwind readonly ssp
define i32 @foo(i32 %i) #2 {
entry:
- tail call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !15, metadata !{}), !dbg !20
+ tail call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !15, metadata !{}), !dbg !20
%.0 = load i32* @xyz, align 4
ret i32 %.0, !dbg !21
}
@@ -30,29 +30,29 @@ attributes #2 = { nounwind readonly ssp }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!25}
-!0 = metadata !{metadata !"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\001", metadata !1, metadata !2, metadata !2, metadata !23, metadata !24, null} ; [ DW_TAG_compile_unit ] [/tmp//g.c] [DW_LANG_C89]
-!1 = metadata !{metadata !"g.c", metadata !"/tmp/"}
-!2 = metadata !{null}
-!3 = metadata !{metadata !"0x2e\00bar\00bar\00\005\001\001\000\006\000\001\000", metadata !1, null, metadata !4, null, null, null, null, null} ; [ DW_TAG_subprogram ] [line 5] [local] [def] [scope 0] [bar]
-!4 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !1, metadata !5, null, metadata !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/tmp//g.c]
-!6 = metadata !{metadata !"0x2e\00fn\00fn\00fn\006\000\001\000\006\000\001\000", metadata !1, null, metadata !7, null, i32 ()* @fn, null, null, null} ; [ DW_TAG_subprogram ] [line 6] [def] [scope 0] [fn]
-!7 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !1, metadata !5, null, metadata !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!8 = metadata !{metadata !9}
-!9 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", metadata !1, metadata !5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!10 = metadata !{metadata !"0x2e\00foo\00foo\00foo\007\000\001\000\006\000\001\000", metadata !1, null, metadata !11, null, i32 (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 0] [foo]
-!11 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !1, metadata !5, null, metadata !12, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!12 = metadata !{metadata !9, metadata !9}
-!13 = metadata !{metadata !"0x100\00bb\005\000", metadata !14, metadata !5, metadata !9} ; [ DW_TAG_auto_variable ]
-!14 = metadata !{metadata !"0xb\005\000\000", metadata !1, metadata !3} ; [ DW_TAG_lexical_block ] [/tmp//g.c]
-!15 = metadata !{metadata !"0x101\00i\007\000", metadata !10, metadata !5, metadata !9} ; [ DW_TAG_arg_variable ]
-!16 = metadata !{metadata !"0x34\00abcd\00abcd\00\002\001\001", metadata !5, metadata !5, metadata !9, null, null} ; [ DW_TAG_variable ]
-!17 = metadata !{metadata !"0x34\00xyz\00xyz\00\003\000\001", metadata !5, metadata !5, metadata !9, i32* @xyz, null} ; [ DW_TAG_variable ]
-!18 = metadata !{i32 6, i32 0, metadata !19, null}
-!19 = metadata !{metadata !"0xb\006\000\000", metadata !1, metadata !6} ; [ DW_TAG_lexical_block ] [/tmp//g.c]
-!20 = metadata !{i32 7, i32 0, metadata !10, null}
-!21 = metadata !{i32 10, i32 0, metadata !22, null}
-!22 = metadata !{metadata !"0xb\007\000\000", metadata !1, metadata !10} ; [ DW_TAG_lexical_block ] [/tmp//g.c]
-!23 = metadata !{metadata !3, metadata !6, metadata !10}
-!24 = metadata !{metadata !16, metadata !17}
-!25 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x11\001\004.2.1 (Based on Apple Inc. build 5658) (LLVM build)\001\00\000\00\001", !1, !2, !2, !23, !24, null} ; [ DW_TAG_compile_unit ] [/tmp//g.c] [DW_LANG_C89]
+!1 = !{!"g.c", !"/tmp/"}
+!2 = !{null}
+!3 = !{!"0x2e\00bar\00bar\00\005\001\001\000\006\000\001\000", !1, null, !4, null, null, null, null, null} ; [ DW_TAG_subprogram ] [line 5] [local] [def] [scope 0] [bar]
+!4 = !{!"0x15\00\000\000\000\000\000\000", !1, !5, null, !2, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/tmp//g.c]
+!6 = !{!"0x2e\00fn\00fn\00fn\006\000\001\000\006\000\001\000", !1, null, !7, null, i32 ()* @fn, null, null, null} ; [ DW_TAG_subprogram ] [line 6] [def] [scope 0] [fn]
+!7 = !{!"0x15\00\000\000\000\000\000\000", !1, !5, null, !8, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = !{!9}
+!9 = !{!"0x24\00int\000\0032\0032\000\000\005", !1, !5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!10 = !{!"0x2e\00foo\00foo\00foo\007\000\001\000\006\000\001\000", !1, null, !11, null, i32 (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 0] [foo]
+!11 = !{!"0x15\00\000\000\000\000\000\000", !1, !5, null, !12, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!12 = !{!9, !9}
+!13 = !{!"0x100\00bb\005\000", !14, !5, !9} ; [ DW_TAG_auto_variable ]
+!14 = !{!"0xb\005\000\000", !1, !3} ; [ DW_TAG_lexical_block ] [/tmp//g.c]
+!15 = !{!"0x101\00i\007\000", !10, !5, !9} ; [ DW_TAG_arg_variable ]
+!16 = !{!"0x34\00abcd\00abcd\00\002\001\001", !5, !5, !9, null, null} ; [ DW_TAG_variable ]
+!17 = !{!"0x34\00xyz\00xyz\00\003\000\001", !5, !5, !9, i32* @xyz, null} ; [ DW_TAG_variable ]
+!18 = !MDLocation(line: 6, scope: !19)
+!19 = !{!"0xb\006\000\000", !1, !6} ; [ DW_TAG_lexical_block ] [/tmp//g.c]
+!20 = !MDLocation(line: 7, scope: !10)
+!21 = !MDLocation(line: 10, scope: !22)
+!22 = !{!"0xb\007\000\000", !1, !10} ; [ DW_TAG_lexical_block ] [/tmp//g.c]
+!23 = !{!3, !6, !10}
+!24 = !{!16, !17}
+!25 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/StructurizeCFG/nested-loop-order.ll b/test/Transforms/StructurizeCFG/nested-loop-order.ll
new file mode 100644
index 0000000..fee1ff0
--- /dev/null
+++ b/test/Transforms/StructurizeCFG/nested-loop-order.ll
@@ -0,0 +1,79 @@
+; RUN: opt -S -structurizecfg %s -o - | FileCheck %s
+
+define void @main(float addrspace(1)* %out) {
+
+; CHECK: main_body:
+; CHECK: br label %LOOP.outer
+main_body:
+ br label %LOOP.outer
+
+; CHECK: LOOP.outer:
+; CHECK: br label %LOOP
+LOOP.outer: ; preds = %ENDIF28, %main_body
+ %temp8.0.ph = phi float [ 0.000000e+00, %main_body ], [ %tmp35, %ENDIF28 ]
+ %temp4.0.ph = phi i32 [ 0, %main_body ], [ %tmp20, %ENDIF28 ]
+ br label %LOOP
+
+; CHECK: LOOP:
+; br i1 %{{[0-9]+}}, label %ENDIF, label %Flow
+LOOP: ; preds = %IF29, %LOOP.outer
+ %temp4.0 = phi i32 [ %temp4.0.ph, %LOOP.outer ], [ %tmp20, %IF29 ]
+ %tmp20 = add i32 %temp4.0, 1
+ %tmp22 = icmp sgt i32 %tmp20, 3
+ br i1 %tmp22, label %ENDLOOP, label %ENDIF
+
+; CHECK: Flow3
+; CHECK: br i1 %{{[0-9]+}}, label %ENDLOOP, label %LOOP.outer
+
+; CHECK: ENDLOOP:
+; CHECK: ret void
+ENDLOOP: ; preds = %ENDIF28, %IF29, %LOOP
+ %temp8.1 = phi float [ %temp8.0.ph, %LOOP ], [ %temp8.0.ph, %IF29 ], [ %tmp35, %ENDIF28 ]
+ %tmp23 = icmp eq i32 %tmp20, 3
+ %.45 = select i1 %tmp23, float 0.000000e+00, float 1.000000e+00
+ store float %.45, float addrspace(1)* %out
+ ret void
+
+; CHECK: ENDIF:
+; CHECK: br i1 %tmp31, label %IF29, label %Flow1
+ENDIF: ; preds = %LOOP
+ %tmp31 = icmp sgt i32 %tmp20, 1
+ br i1 %tmp31, label %IF29, label %ENDIF28
+
+; CHECK: Flow:
+; CHECK br i1 %{{[0-9]+}}, label %Flow, label %LOOP
+
+; CHECK: IF29:
+; CHECK: br label %Flow1
+IF29: ; preds = %ENDIF
+ %tmp32 = icmp sgt i32 %tmp20, 2
+ br i1 %tmp32, label %ENDLOOP, label %LOOP
+
+; CHECK: Flow1:
+; CHECK: br label %Flow
+
+; CHECK: Flow2:
+; CHECK: br i1 %{{[0-9]+}}, label %ENDIF28, label %Flow3
+
+; CHECK: ENDIF28:
+; CHECK: br label %Flow3
+ENDIF28: ; preds = %ENDIF
+ %tmp35 = fadd float %temp8.0.ph, 1.0
+ %tmp36 = icmp sgt i32 %tmp20, 2
+ br i1 %tmp36, label %ENDLOOP, label %LOOP.outer
+}
+
+; Function Attrs: nounwind readnone
+declare <4 x float> @llvm.SI.vs.load.input(<16 x i8>, i32, i32) #1
+
+; Function Attrs: readnone
+declare float @llvm.AMDIL.clamp.(float, float, float) #2
+
+declare void @llvm.SI.export(i32, i32, i32, i32, i32, float, float, float, float)
+
+attributes #0 = { "ShaderType"="1" "enable-no-nans-fp-math"="true" "unsafe-fp-math"="true" }
+attributes #1 = { nounwind readnone }
+attributes #2 = { readnone }
+
+!0 = !{!1, !1, i64 0, i32 1}
+!1 = !{!"const", null}
diff --git a/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll b/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll
new file mode 100644
index 0000000..668a1e9
--- /dev/null
+++ b/test/Transforms/StructurizeCFG/one-loop-multiple-backedges.ll
@@ -0,0 +1,42 @@
+; RUN: opt -S -structurizecfg %s -o - | FileCheck %s
+
+; CHECK-NOT: br i1 true
+
+define void @blam(i32 addrspace(1)* nocapture %arg, float %arg1, float %arg2) {
+; CHECK: bb:
+bb:
+ br label %bb3
+
+; CHECK: bb3:
+bb3: ; preds = %bb7, %bb
+ %tmp = phi i64 [ 0, %bb ], [ %tmp8, %bb7 ]
+ %tmp4 = fcmp ult float %arg1, 3.500000e+00
+; CHECK: %0 = xor i1 %tmp4, true
+; CHECK: br i1 %0, label %bb5, label %Flow
+ br i1 %tmp4, label %bb7, label %bb5
+
+; CHECK: bb5:
+bb5: ; preds = %bb3
+ %tmp6 = fcmp olt float 0.000000e+00, %arg2
+; CHECK: br label %Flow
+ br i1 %tmp6, label %bb10, label %bb7
+
+; CHECK: Flow:
+; CHECK: br i1 %3, label %bb7, label %Flow1
+
+; CHECK: bb7
+bb7: ; preds = %bb5, %bb3
+ %tmp8 = add nuw nsw i64 %tmp, 1
+ %tmp9 = icmp slt i64 %tmp8, 5
+; CHECK: br label %Flow1
+ br i1 %tmp9, label %bb3, label %bb10
+
+; CHECK: Flow1:
+; CHECK: br i1 %7, label %bb10, label %bb3
+
+; CHECK: bb10
+bb10: ; preds = %bb7, %bb5
+ %tmp11 = phi i32 [ 15, %bb5 ], [ 255, %bb7 ]
+ store i32 %tmp11, i32 addrspace(1)* %arg, align 4
+ ret void
+}
diff --git a/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll b/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll
new file mode 100644
index 0000000..740b3d1
--- /dev/null
+++ b/test/Transforms/StructurizeCFG/post-order-traversal-bug.ll
@@ -0,0 +1,100 @@
+; RUN: opt -S -structurizecfg %s -o - | FileCheck %s
+
+; The structurize cfg pass used to do a post-order traversal to generate a list
+; of ; basic blocks and then operate on the list in reverse. This led to bugs,
+; because sometimes successors would be visited before their predecessors.
+; The fix for this was to do a reverse post-order traversal which is what the
+; algorithm requires.
+
+; Function Attrs: nounwind
+define void @test(float* nocapture %out, i32 %K1, float* nocapture readonly %nr) {
+
+; CHECK: entry:
+; CHECK: br label %for.body
+entry:
+ br label %for.body
+
+; CHECK: for.body:
+; CHECK: br i1 %{{[0-9]+}}, label %lor.lhs.false, label %Flow
+for.body: ; preds = %for.body.backedge, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.be, %for.body.backedge ], [ 1, %entry ]
+ %best_val.027 = phi float [ %best_val.027.be, %for.body.backedge ], [ 5.000000e+01, %entry ]
+ %prev_start.026 = phi i32 [ %tmp26, %for.body.backedge ], [ 0, %entry ]
+ %best_count.025 = phi i32 [ %best_count.025.be, %for.body.backedge ], [ 0, %entry ]
+ %tmp0 = trunc i64 %indvars.iv to i32
+ %cmp1 = icmp eq i32 %tmp0, %K1
+ br i1 %cmp1, label %if.then, label %lor.lhs.false
+
+; CHECK: lor.lhs.false:
+; CHECK: br label %Flow
+lor.lhs.false: ; preds = %for.body
+ %arrayidx = getelementptr inbounds float* %nr, i64 %indvars.iv
+ %tmp1 = load float* %arrayidx, align 4
+ %tmp2 = add nsw i64 %indvars.iv, -1
+ %arrayidx2 = getelementptr inbounds float* %nr, i64 %tmp2
+ %tmp3 = load float* %arrayidx2, align 4
+ %cmp3 = fcmp une float %tmp1, %tmp3
+ br i1 %cmp3, label %if.then, label %for.body.1
+
+; CHECK: Flow:
+; CHECK: br i1 %{{[0-9]+}}, label %if.then, label %Flow1
+
+; CHECK: if.then:
+; CHECK: br label %Flow1
+if.then: ; preds = %lor.lhs.false, %for.body
+ %sub4 = sub nsw i32 %tmp0, %prev_start.026
+ %tmp4 = add nsw i64 %indvars.iv, -1
+ %arrayidx8 = getelementptr inbounds float* %nr, i64 %tmp4
+ %tmp5 = load float* %arrayidx8, align 4
+ br i1 %cmp1, label %for.end, label %for.body.1
+
+; CHECK: for.end:
+; CHECK: ret void
+for.end: ; preds = %for.body.1, %if.then
+ %best_val.0.lcssa = phi float [ %best_val.233, %for.body.1 ], [ %tmp5, %if.then ]
+ store float %best_val.0.lcssa, float* %out, align 4
+ ret void
+
+; CHECK: Flow1
+; CHECK: br i1 %{{[0-9]}}, label %for.body.1, label %Flow2
+
+; CHECK: for.body.1:
+; CHECK: br i1 %{{[0-9]+}}, label %for.body.6, label %Flow3
+for.body.1: ; preds = %if.then, %lor.lhs.false
+ %best_val.233 = phi float [ %tmp5, %if.then ], [ %best_val.027, %lor.lhs.false ]
+ %best_count.231 = phi i32 [ %sub4, %if.then ], [ %best_count.025, %lor.lhs.false ]
+ %indvars.iv.next.454 = add nsw i64 %indvars.iv, 5
+ %tmp22 = trunc i64 %indvars.iv.next.454 to i32
+ %cmp1.5 = icmp eq i32 %tmp22, %K1
+ br i1 %cmp1.5, label %for.end, label %for.body.6
+
+; CHECK: Flow2:
+; CHECK: br i1 %{{[0-9]+}}, label %for.end, label %for.body
+
+; CHECK: for.body.6:
+; CHECK: br i1 %cmp5.6, label %if.then6.6, label %for.body.backedge
+for.body.6: ; preds = %for.body.1
+ %indvars.iv.next.559 = add nsw i64 %indvars.iv, 6
+ %tmp26 = trunc i64 %indvars.iv.next.559 to i32
+ %sub4.6 = sub nsw i32 %tmp26, %tmp22
+ %cmp5.6 = icmp slt i32 %best_count.231, %sub4.6
+ br i1 %cmp5.6, label %if.then6.6, label %for.body.backedge
+
+; CHECK: if.then6.6
+; CHECK: br label %for.body.backedge
+if.then6.6: ; preds = %for.body.6
+ %arrayidx8.6 = getelementptr inbounds float* %nr, i64 %indvars.iv.next.454
+ %tmp29 = load float* %arrayidx8.6, align 4
+ br label %for.body.backedge
+
+; CHECK: Flow3:
+; CHECK: br label %Flow2
+
+; CHECK: for.body.backedge:
+; CHECK: br label %Flow3
+for.body.backedge: ; preds = %if.then6.6, %for.body.6
+ %best_val.027.be = phi float [ %tmp29, %if.then6.6 ], [ %best_val.233, %for.body.6 ]
+ %best_count.025.be = phi i32 [ %sub4.6, %if.then6.6 ], [ %best_count.231, %for.body.6 ]
+ %indvars.iv.be = add nsw i64 %indvars.iv, 7
+ br label %for.body
+}
diff --git a/test/Transforms/Util/combine-alias-scope-metadata.ll b/test/Transforms/Util/combine-alias-scope-metadata.ll
new file mode 100644
index 0000000..fd0a3d5
--- /dev/null
+++ b/test/Transforms/Util/combine-alias-scope-metadata.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -S -basicaa -memcpyopt | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @test(i8* noalias dereferenceable(1) %in, i8* noalias dereferenceable(1) %out) {
+ %tmp = alloca i8
+ %tmp2 = alloca i8
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %out, i8* %in, i64 1, i32 8, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %in, i64 1, i32 8, i1 false), !alias.scope !4
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %tmp, i64 1, i32 8, i1 false), !alias.scope !5
+
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %out, i8* %tmp2, i64 1, i32 8, i1 false), !noalias !6
+
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1)
+
+!0 = !{!0}
+!1 = distinct !{!1, !0, !"in"}
+!2 = distinct !{!2, !0, !"tmp"}
+!3 = distinct !{!3, !0, !"tmp2"}
+!4 = distinct !{!1, !2}
+!5 = distinct !{!2, !3}
+!6 = distinct !{!1, !2}
diff --git a/test/Transforms/Util/lowerswitch.ll b/test/Transforms/Util/lowerswitch.ll
index 06bd4cc..17c1202 100644
--- a/test/Transforms/Util/lowerswitch.ll
+++ b/test/Transforms/Util/lowerswitch.ll
@@ -1,8 +1,8 @@
; RUN: opt -lowerswitch -S < %s | FileCheck %s
; Test that we don't crash and have a different basic block for each incoming edge.
-define void @test_lower_switch() {
-; CHECK-LABEL: @test_lower_switch
+define void @test0() {
+; CHECK-LABEL: @test0
; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NewDefault ], [ 0, %NodeBlock5 ], [ 0, %LeafBlock1 ]
BB1:
switch i32 undef, label %BB2 [
@@ -20,3 +20,35 @@ BB2:
BB3:
br label %BB2
}
+
+; Test switch cases that are merged into a single case during lowerswitch
+; (take 84 and 85 below) - check that the number of incoming phi values match
+; the number of branches.
+define void @test1() {
+; CHECK-LABEL: @test1
+entry:
+ br label %bb1
+
+bb1:
+ switch i32 undef, label %bb1 [
+ i32 84, label %bb3
+ i32 85, label %bb3
+ i32 86, label %bb2
+ i32 78, label %exit
+ i32 99, label %bb3
+ ]
+
+bb2:
+ br label %bb3
+
+bb3:
+; CHECK-LABEL: bb3
+; CHECK: %tmp = phi i32 [ 1, %NodeBlock ], [ 0, %bb2 ], [ 1, %LeafBlock3 ]
+ %tmp = phi i32 [ 1, %bb1 ], [ 0, %bb2 ], [ 1, %bb1 ], [ 1, %bb1 ]
+; CHECK-NEXT: %tmp2 = phi i32 [ 2, %NodeBlock ], [ 5, %bb2 ], [ 2, %LeafBlock3 ]
+ %tmp2 = phi i32 [ 2, %bb1 ], [ 2, %bb1 ], [ 5, %bb2 ], [ 2, %bb1 ]
+ br label %exit
+
+exit:
+ ret void
+}